QT实现类似LOL信号系统(XXX正在路上)

本文介绍了一款使用Qt框架自定义的拖动盘控件,该控件灵感来源于代码助手,可双击添加常用代码到剪贴板。控件采用无边框窗口,支持透明背景,包含四个扇形区域和中心取消按钮,鼠标悬停时可改变颜色,点击拖动可显示拖动箭头。源代码展示了详细的绘制和事件处理过程。
摘要由CSDN通过智能技术生成

先看一下实现的效果(动态图) 

尚未进行后续优化,比如显示文本这些。

做这个控件的初衷,是因为之前做了一个代码助手, 可以把常用代码或者库添加到代码助手里边,然后使用的时候双击,加入到剪贴板,便于操作, 代码助手大概像下边这样

然后突发奇想, 感觉加上一个这种快捷键可以呼出的拖动盘, 会很酷, 所以就有了这次的拖动盘demo, 后期会将拖动盘集成到代码助手里边, 实现类似LOL的效果

有点扯远了, 下边直接上代码

头文件

class MovePanel : public QDialog
{
    Q_OBJECT

public:
    MovePanel(QWidget *parent = nullptr);
    ~MovePanel();

signals:
    void doSelected(const QString& codeName);                       //选中了某一块

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

protected:
    int currentPos(const QPoint& pos);                         //获取当前鼠标在第几象限
    void resetColor();                                         //重置所有颜色
    void initPath();                                           //初始化坐标位置path;

protected:
    void drawBackground(QPainter& p);                          //绘制背景
    void drawPie(QPainter& p);                                 //绘制4个扇形区
    void drawCancel(QPainter& p);                              //绘制中央的取消按钮
    void drawArrow(QPainter& p);                               //绘制鼠标箭头
    void drawPath(QPainter& p);
private:
    Ui::MovePanel *ui;

    QVector<QColor>          colors;                           //4个分块的颜色值
    QVector<QPainterPath>    paths;                            //4个分块的rect, 用这4个分块,确认当前鼠标再哪个分组里边
    QPoint                   point;                            //当前鼠标拖动到了哪里
    bool                     isPress{false};                   //是否在中间按下了鼠标

    int                      centerX{0};                       //图形中心X
    int                      centerY{0};                       //图形中心Y
    QRect                    centerRect;                       //图形中心的取消按钮
    int                      alpha{255};                       //透明系数
};

.cpp文件

#include "movepanel.h"
#include "ui_movepanel.h"
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPainter>
#include <QDebug>


MovePanel::MovePanel(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::MovePanel)
{
    ui->setupUi(this);
    setAutoFillBackground(true);
    setWindowFlags( Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint );   //设置无边框窗口,并位于最前
    setAttribute( Qt::WA_TranslucentBackground );                           //背景透明
    move(700, 100);
    setMouseTracking(true);

    //4个分块初始情况下都是这个颜色
    colors.append(QColor(135, 236, 211, alpha));                          //第二象限
    colors.append(QColor(135, 236, 211, alpha));                          //第一象限
    colors.append(QColor(135, 236, 211, alpha));                          //第三象限
    colors.append(QColor(135, 236, 211, alpha));                          //第四象限

    //4个代表区域的方块
    centerX = width()/2;
    centerY = height()/2;
    centerRect = QRect(centerX-40, centerY-40, 80, 80);         //中心区域

    initPath();
}

MovePanel::~MovePanel()
{
    delete ui;
}

void MovePanel::paintEvent(QPaintEvent *)
{
    QPainter p(this);
    int side = qMin(width(), height());
    p.translate(width()/2, height()/2);
    p.scale(side/200.0, side/200.0);
    p.setRenderHint(QPainter::Antialiasing);



    drawBackground(p);

    drawPie(p);

    drawArrow(p);

    drawCancel(p);
//    drawPath(p);


}

void MovePanel::mouseMoveEvent(QMouseEvent *e)
{
    if(isPress){
        resetColor();                                               //把所有颜色重置
        point = e->pos();
        int currentIndex = currentPos(e->pos());
        if(currentIndex > -1){
            colors[currentIndex] = QColor(84,228,193,alpha);             //当前鼠标悬浮位置进行变色
        }

        update();
    }
}

void MovePanel::mousePressEvent(QMouseEvent *e)
{
    if(centerRect.contains(e->pos())){
        isPress = true;
    }
}

void MovePanel::mouseReleaseEvent(QMouseEvent *e)
{
    //如果选择了某一个下标,就结束
    if(currentPos(e->pos()) > -1){
        emit doSelected("");

//        close();
    }

    isPress = false;
    resetColor();
    update();
}

int MovePanel::currentPos(const QPoint &pos)
{
    for(int i=0; i<paths.count(); i++){
        if(paths.at(i).contains(pos)){
            qDebug() << "cur:" << i;
            return i;
        }
    }
    return -1;
}

void MovePanel::resetColor()
{
    for(int i=0; i<colors.count(); i++){
        colors[i]=QColor(135, 236, 211, alpha);
    }
}

void MovePanel::initPath()
{
    //构造4个扇形区
    for(int i=0; i<4; i++){
        QPainterPath path;
        //要注意,这里使用的是绝对坐标, 而不是相对side/200的坐标
        path.arcTo(QRectF(-200, -200, 400, 400), -45+(i*90), 90);
        path.translate(centerX, centerY);
        paths.append(path);
    }
}

void MovePanel::drawBackground(QPainter &p)
{
    p.save();
    p.setBrush(QColor(0, 0, 0, 0));         //绘制一个透明的背景
    p.setPen(Qt::NoPen);
    p.drawEllipse(-100, -100, 200, 200);
    p.restore();

}

void MovePanel::drawPie(QPainter &p)
{
    p.save();
    p.setPen(QColor(0, 220, 176, alpha));

    p.rotate(-45);

    //绘制第二象限
    p.setBrush(colors.at(1));
    p.drawPie(QRectF(-90, -90, 180, 180.0), 0*16, 90*16);

    //绘制第一象限
    p.rotate(-90);
    p.setBrush(colors.at(2));
    p.drawPie(QRectF(-90, -90, 180, 180.0), 0*16, 90*16);

    //绘制第三象限
    p.rotate(-90);
    p.setBrush(colors.at(3));
    p.drawPie(QRectF(-90, -90, 180, 180.0), 0*16, 90*16);

    //绘制第四象限
    p.rotate(-90);
    p.setBrush(colors.at(0));
    p.drawPie(QRectF(-90, -90, 180, 180.0), 0*16, 90*16);

    p.restore();
}

void MovePanel::drawCancel(QPainter &p)
{
    QRect rec;
    if(!isPress){
        rec = QRect(-5, -5, 10, 10);
    }else{
        rec = QRect(-2, -2, 4, 4);
    }

    p.save();
    p.setPen(QColor(28,175,244, alpha));
    p.setBrush(QColor(84,228,193,alpha));

    p.drawEllipse(rec);
    p.restore();

}

void MovePanel::drawArrow(QPainter &p)
{
    if(isPress){
        p.save();

        p.setPen(QColor(28,175,244, alpha));
        p.drawLine( 0, 0, point.x()/2-100, point.y()/2-100 );
        p.setPen(Qt::NoPen);
        p.setBrush(QColor(28,175,244, alpha));
        p.drawEllipse( point.x()/2-105, point.y()/2-105, 10, 10 );

        p.restore();
    }
}

void MovePanel::drawPath(QPainter &p)
{
    p.save();
    p.setPen(Qt::red);
    p.setBrush(Qt::yellow);
    for(int i=0; i<4; i++){
        p.drawPath(paths[i]);
    }


    p.restore();
}

学无止境,QT冲冲冲

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值