首页 > 其他分享 >Qt-绘制运动方向控制按钮

Qt-绘制运动方向控制按钮

时间:2024-07-15 19:28:23浏览次数:16  
标签:case map lineTo Qt buttons 按钮 trans 绘制 painter

源代码:qianqiu10000/myDirectionButton

效果图:↓

1.在AutoCAD中绘制自己想要的按钮轮廓

2.调整CAD中的坐标系,与Qt窗口坐标系一致,如图所示Y方向朝下

3.继承QWidget,按照CAD中的坐标点绘制,并添加一些颜色变化

#ifndef MYDIRECTIONBUTTON_H
#define MYDIRECTIONBUTTON_H

#include<QWidget>

class myDirectionButton : public QWidget
{
    Q_OBJECT

public:
    enum PRESSED {
        ZN,
        XN,
        ZP,
        XP,
        YP,
        YN,
        RN,
        RP,
        HOME,
        NONE
    };

    myDirectionButton(QWidget *parent = nullptr);

    void setPressed(int button);

signals:
    void signalPressed(int button);

protected:
    void mousePressEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void paintEvent(QPaintEvent *event)override;
    void resizeEvent(QResizeEvent *event) override;

private:
    int m_pressedBtn;
    int m_hoverBtn;
    QColor m_clrOut0;
    QColor m_clrOut1;
    QColor m_clrIn0;
    QColor m_clrIn1;
    double m_scale;

    QPainterPath m_homeBtn;             //回原按钮,比较特殊,单独拿出来
    QVector<QPainterPath>m_buttons;     //按钮区域
    QVector<QPainterPath>m_arrows;      //装饰箭头


    void createButtons();               //创建按钮路径

};

#endif // MYDIRECTIONBUTTON_H

#include "myDirectionButton.h"

#include<QDebug>
#include<QPainter>
#include<QMouseEvent>


myDirectionButton::myDirectionButton(QWidget *parent)
    : QWidget(parent)
{
    m_scale = 1.0;
    m_pressedBtn = NONE;
    m_hoverBtn = NONE;
    m_clrOut0 = QColor(200, 200, 200, 100);
    m_clrOut1 = QColor(200, 255, 200, 200);
    m_clrIn0 = QColor(255, 255, 255);
    m_clrIn1 = QColor(100, 255, 100);
    m_buttons.resize(8);
    m_arrows.resize(8);

    setMouseTracking(true);

    setMinimumSize(100, 100);
}

void myDirectionButton::createButtons()
{
    //Z-装饰箭头向上
    QPainterPath arrowZN;
    arrowZN.moveTo(0, -85);
    arrowZN.lineTo(20, -75);
    arrowZN.lineTo(10, -75);
    arrowZN.lineTo(10, -55);
    arrowZN.lineTo(-10, -55);
    arrowZN.lineTo(-10, -75);
    arrowZN.lineTo(-20, -75);
    arrowZN.closeSubpath();

    //Y+装饰箭头,逆时针
    QPainterPath arrowYP;
    arrowYP.moveTo(-77.5, -90);
    arrowYP.lineTo(-65, -85);
    arrowYP.lineTo(-70, -85);
    arrowYP.lineTo(-70, -78.2624);
    arrowYP.arcTo(QRectF(-105, -105, 210, 210), 131.81, 12.24);
    arrowYP.lineTo(-85, -85);
    arrowYP.lineTo(-90, -85);
    arrowYP.closeSubpath();

    //A+装饰箭头,逆时针
    QPainterPath arrowAP;
    arrowAP.moveTo(54.0833, -90);
    arrowAP.arcTo(QRectF(-105, -105, 210, 210), 59, -12.63);
    arrowAP.lineTo(75.9939, -79.5294);
    arrowAP.arcTo(QRectF(-110, -110, 220, 220), 46.36, -11.27);
    arrowAP.lineTo(90, -79.3725);
    arrowAP.lineTo(83.0666, -86.6022);
    arrowAP.lineTo(86.4645, -90);
    arrowAP.closeSubpath();

    //Z-按钮路径
    QPainterPath btnZN;
    btnZN.moveTo(33.5434, -37.0789);
    btnZN.arcTo(QRectF(-50, -50, 100, 100), 47.87, 84.27);
    btnZN.lineTo(-65.4074, -68.9429);
    btnZN.arcTo(QRectF(-95, -95, 190, 190), 133.49, -86.98);
    btnZN.closeSubpath();

    //Y+按钮路径
    QPainterPath btnYP;
    btnYP.moveTo(-95, -95);
    btnYP.lineTo(-31.225, -95);
    btnYP.arcTo(QRectF(-100, -100, 200, 200), 108.19, 53.61);
    btnYP.closeSubpath();

    //回原按钮
    QPainterPath home;
    home.addEllipse(-45, -45, 90, 90);

    QTransform trans;
    //路径转换
    trans.translate(rect().center().x(), rect().center().y());
    trans.scale(m_scale, m_scale);
    m_arrows[ZN] = trans.map(arrowZN);
    m_buttons[ZN] = trans.map(btnZN);
    m_buttons[YP] = trans.map(btnYP);
    m_arrows[YP] = trans.map(arrowYP);
    m_arrows[RP] = trans.map(arrowAP);
    m_homeBtn = trans.map(home);

    trans.rotate(-90);
    m_arrows[XN] = trans.map(arrowZN);
    m_buttons[XN] = trans.map(btnZN);
    m_buttons[YN] = trans.map(btnYP);

    trans.rotate(-90);
    m_arrows[ZP] = trans.map(arrowZN);
    m_buttons[ZP] = trans.map(btnZN);
    m_buttons[RN] = trans.map(btnYP);

    trans.rotate(-90);
    m_arrows[XP] = trans.map(arrowZN);
    m_buttons[XP] = trans.map(btnZN);
    m_buttons[RP] = trans.map(btnYP);
    trans.reset();


    //添加YA两个方向装饰箭头
    trans.translate(rect().center().x(), rect().center().y());
    trans.scale(m_scale, -m_scale);
    m_arrows[YN] = trans.map(arrowYP);
    m_arrows[RN] = trans.map(arrowAP);
    trans.reset();
}

void myDirectionButton::paintEvent(QPaintEvent *event)
{
    QWidget::paintEvent(event);

    QPainter painter(this);

    painter.setPen(Qt::NoPen);
    //绘制按钮区
    painter.setBrush(m_clrOut0);
    for(int i = 0; i < m_buttons.count(); i++) {
        painter.drawPath(m_buttons.at(i));
    }

    //绘制回原按钮
    painter.drawPath(m_homeBtn);

    //绘制装饰箭头
    painter.setBrush(m_clrIn0);
    for(int i = 0; i < m_arrows.count(); i++) {
        painter.drawPath(m_arrows.at(i));
    }

    //根据状态绘制不同颜色
    switch (m_pressedBtn)
    {
        case ZN:
        case ZP:
        case XN:
        case XP:
        case YP:
        case YN:
        case RP:
        case RN:
            painter.setBrush(m_clrOut1);
            painter.drawPath(m_buttons[m_pressedBtn]);
            painter.setBrush(m_clrIn1);
            painter.drawPath(m_arrows[m_pressedBtn]);
            break;
        case HOME:
            painter.setBrush(m_clrIn1);
            painter.drawPath(m_homeBtn);
            break;
        default:
            {
                switch (m_hoverBtn) {
                    case ZN:
                    case ZP:
                    case XN:
                    case XP:
                    case YP:
                    case YN:
                    case RP:
                    case RN:
                        painter.setBrush(m_clrOut1.lighter());
                        painter.drawPath(m_buttons[m_hoverBtn]);
                        painter.setBrush(m_clrIn1.lighter());
                        painter.drawPath(m_arrows[m_hoverBtn]);
                        break;
                    case HOME:
                        painter.setBrush(m_clrIn1.lighter());
                        painter.drawPath(m_homeBtn);
                        break;
                    default:
                        break;
                }
            }
            break;
    }

    //绘制文字
    painter.translate(size().width() / 2, size().height() / 2);
    painter.scale(m_scale, m_scale);
    QFont font = painter.font();
    font.setPixelSize(28);
    painter.setFont(font);
    painter.setPen(QPen(Qt::black, 2, Qt::SolidLine));
    painter.drawText(QRectF(-45, -45, 90, 90), Qt::AlignCenter, "HOME");

    font.setPixelSize(15);
    painter.setFont(font);
    painter.drawText(QRectF(-10, -75, 20, 20), Qt::AlignCenter, "Z-");
    painter.drawText(QRectF(-75, -10, 20, 20), Qt::AlignCenter, "X-");
    painter.drawText(QRectF(-10, 55, 20, 20), Qt::AlignCenter, "Z+");
    painter.drawText(QRectF(55, -10, 20, 20), Qt::AlignCenter, "X+");
    painter.drawText(QRectF(-85, -85, 15, 10), Qt::AlignCenter, "Y+");
    painter.drawText(QRectF(-85, 75, 15, 10), Qt::AlignCenter, "Y-");
    painter.drawText(QRectF(66, 80, 15, 10), Qt::AlignCenter, "R-");
    painter.drawText(QRectF(66, -90, 15, 10), Qt::AlignCenter, "R+");
}

void myDirectionButton::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);

    //默认绘图区域200X200,窗口变化时缩放
    int edge = qMin(size().width(), size().height());
    m_scale = edge / 200.0;

    createButtons();
}

void myDirectionButton::mouseReleaseEvent(QMouseEvent *)
{
    if(m_pressedBtn != HOME) {
        setPressed(NONE);
    }
}

void myDirectionButton::mouseMoveEvent(QMouseEvent *event)
{
    QWidget::mouseMoveEvent(event);

    if(m_pressedBtn != NONE) {
        return;
    }

    QPoint p = event->pos();

    int state = NONE;

    if(m_homeBtn.contains(p))    {
        state = HOME;
    }
    else
    {
        for(int index = 0; index < m_buttons.count(); index++)        {
            if(m_buttons[index].contains(p))            {
                state = index;
            }
        }
    }

    if(m_hoverBtn != state)    {
        m_hoverBtn = state;
        update();
    }
}

void myDirectionButton::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        QPoint p = event->pos();

        //Home键比较特殊,鼠标弹释放时不会自动恢复颜色,因为他要标记Home过程
        //外部设备Home结束后才能取消Home状态
        if(m_homeBtn.contains(p))
        {
            setPressed(HOME);
            return;
        }

        for(int index = 0; index < m_buttons.count(); index++)
        {
            if(m_buttons[index].contains(p))
            {
                setPressed(index);
                return ;
            }
        }
    }
}

void myDirectionButton::setPressed(int button)
{
    if(button != m_pressedBtn)
    {
        m_pressedBtn = button;
        emit signalPressed(button);
        update();
    }


}


标签:case,map,lineTo,Qt,buttons,按钮,trans,绘制,painter
From: https://blog.csdn.net/weixin_69505365/article/details/140429293

相关文章

  • 记录解决QT父子窗口互传值、一些数据类型转换问题
    @目录一、父子窗口互相传值①父向子窗口传递值②子向父窗口传递值二、数据类型转换①int转QString②int转16进制③QString转unsignedchar④unchar转QString⑤char转int⑥QByteArray转16进制一、父子窗口互相传值①父向子窗口传递值父.hprivateslots:voidon_btnMore_c......
  • SAP ABAP ME21N工具栏按钮失效增强
    如何使ME21N工具栏的按钮按指定条件失效发布日期:2024/07/12案例:事务码ME21N,当输入明细的工厂为3121时,使按钮【屏幕概览关闭】失效1.鼠标放在【屏幕概览关闭】上按F1,查看技术信息。确定程序名和状态栏信息。在状态栏中确认按钮ID(METROF)2.确定增强点if_command_mm~exec......
  • Qt UI线程中使用QThread::sleep有什么影响
    在Qt中,QThread::sleep 是一个静态函数,用于让当前线程休眠指定的时间,以实现线程暂停的目的。当在UI线程中调用 QThread::sleep 函数时,会导致UI线程在指定的时间内被阻塞,即界面无法响应用户的操作,直到休眠时间结束。因此,在UI线程中使用 QThread::sleep 可能会导致界面冻结,影响......
  • 【可视化大屏系列】Echarts之饼图绘制
    本文为个人近期学习总结,若有错误之处,欢迎指出!Echarts之饼图绘制前言1.需求2.实现效果3.大概思路4.代码实现子组件写法父组件写法5.附加(1)圆环饼图的绘制(2)南丁格尔玫瑰饼图A.半径展示数据的大小B.面积展示数据的大小前言在前文页面布局、DataV的使用、Echarts......
  • C++使用gnuplot-cpp库绘制图像
    最近想要对一些时变的变量进行可视化,搜索来搜索去选择了使用gnuplot这个工具。sudoapt-getinstallgnuplotsudoapt-getinstallgnuplot-x11#使其支持linux终端这样就安装完gnuplot了。接着可以在命令行中键入gnuplot命令打开gnuplot的交互式环境。由于这里着目于使用c++......
  • 13 - matlab m_map地学绘图工具基础函数 - 介绍创建管理颜色映射的函数m_colmap和轮廓
    13-matlabm_map地学绘图工具基础函数-介绍创建管理颜色映射的函数m_colmap和轮廓图绘制颜色条的函数m_contfbar0.引言1.关于m_colmap2.关于m_contfbar3.结语0.引言  本篇介绍下m_map中用于创建和管理颜色映射函数(m_colmap)和为轮廓图绘制颜色条的函......
  • Qt Creator导入不同Qt版本
    1.下载好想要使用的Qt版本2.3.添加Qt版本、编译器和调试器4.名称自己设置,选择好上面添加的编译器,调试器和Qt版本即可......
  • YOLOv8中根据标签绘制真实框
    这个在写论文的过程中获取展示图片的时侯可能会需要用的。最近也是自己在弄目标检测方面的东西,然后这也是自己碰到的问题,想着能分享一下,希望对有需要的人有所帮助。也欢迎大家来讨论问题、交流心得。importcv2importos#定义输入文件夹和输出文件夹路径input_img_folder......
  • Qt-动态库
    前言1.本文中所有的代码案例使用Qt创建,CMake构建、Windows端使用MinGW编译、Linux端使用GNU编译。2.完整的代码示例在绑定的资源中,审核通过后,大家可以免费下载。一库简介1.库是将一些写好的函数和变量代码整合在一起,编译生成库文件,以提供给程序使用。作用是为了复用代......
  • Qt-线程和线程池
    前言Qt实现在线程中执行任务有4种方法,分别是:1. 创建一个派生于QThread类的子类,重写run函数,在run函数中执行任务2.创建一个派生于QObject的子类,调用QObject::moveToThread()方法将子类对象移动到子线程对象中。3.使用线程池QThreadPool4.使用QtConcurrent执行并......