QT-基础使用2-可拖拽的pushButton,实现悬浮球的效果

一、 内容简述

本文章主要介绍实现QPushButton在指定范围内可拖动,即像手机端的悬浮球那样,在手机可视单位内进行拖动,避免遮挡视线。

二、效果展示

本图片仅提供纯文字和纯图片的拖动按钮显示,当然这个类是继承于QPushButton的,也支持图文一起,图文的位置摆放可参考我的上一篇文章:QT基础使用1-QPushButton设置不同方向的图文
在这里插入图片描述

三、主要代码解析

实现代码拖拽的主要思想是,监听鼠标的事件,判断鼠标按钮,并获取鼠标的位移,判断位移是否在可移动范围内,然后将按钮移动过去。本文的按钮是继承于QPushButton的,重写监听事件,判断是否移动按钮。主要的监听代码如下

bool YDragButton::eventFilter(QObject *watched, QEvent *event)
{
    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    switch(event->type())
    {
    case QEvent::MouseButtonPress:
    {
    	//按钮按下,设置此时的状态是按下的,在鼠标移动的时候才会触发按钮移动事件
        if (mouseEvent->button() == Qt::LeftButton) {
            lastPoint = mouseEvent->pos();
            isPressed = true;
        }
        break;
    }
    case QEvent::MouseMove:
    {
        //鼠标移动过程中,如果此时按钮是按下的状态,则可以判断移动按钮
        if (isPressed) {
            int dx = mouseEvent->pos().x() - lastPoint.x();
            int dy = mouseEvent->pos().y() - lastPoint.y();
            int x1 = this->x()+dx;
            int y1 = this->y()+dy;
            int right_distance = this->parentWidget()->width() -2*x_right_distancce-this->width();
            int bottom_distance =this->parentWidget()->height() -2*y_bottom_distance -this->height();
            if(x1>x_left_distance &&x1< right_distance &&y1>y_top_distance &&y1<bottom_distance)
                this->move(this->x() + dx, this->y() + dy);
            isMoved = true;
        }
        break;
    }
    case QEvent::MouseButtonRelease:
    {
       //按钮松开
        if(isMoved !=true){
            emit clicked();
            emit toggled(!isChecked);
            isChecked = !isChecked;
        }else{
            isMoved = false;
        }
        isPressed = false;
        break;
    }
    case QEvent::MouseButtonDblClick:
        //双击按钮
        emit doubleClicked();
        break;
    default:
        break;
    }
    return QWidget::eventFilter(watched,event);
}

四、完整的拖拽代码

YDragButton.h

#include <QWidget>
#include "qpainter.h"
#include "qevent.h"
#include "qtimer.h"
#include "qdebug.h"
#include <QPushButton>

class YDragButton : public QPushButton
{
    Q_OBJECT

public:
    explicit YDragButton(QWidget *parent = 0);
    ~YDragButton();
    void setMargin(int left,int top,int right,int bottom);

signals:
    void clicked();
    void doubleClicked();
    void toggled(bool isToggled);

protected:
    bool eventFilter(QObject *watched, QEvent *event);

private:
    QString text;                   //显示文字
    bool isPressed;                 //鼠标是否按下
    QPoint lastPoint;               //鼠标按下最后坐标
    QString type;                   //图片末尾类型
    QString imgPath;                //背景图片路径
    QString imgName;                //背景图片名称
    int  iconWidth =0 ;             //图片宽度
    int iconHeight =0;              //图片高度
    bool isMoved;                   //是否正在移动中
    int x_left_distance;            //可移动的距离左侧的距离
    int y_top_distance;             //可移动的距离上面的距离
    int x_right_distancce;          //可移动的距离右侧的距离
    int y_bottom_distance;          //可移动的距离上底部的距离
    bool isChecked =false;          //按钮的选中状态
};

YDragButton.cpp

/**
 * 可拖动的按钮,作者qiong522 2023-06-26
 * 1、设置图片型的
 * 2、单独文字的可拖拽
 * 3、可设置移动的区域的,即设置四周的距离
 */
YDragButton::YDragButton(QWidget *parent) : QPushButton(parent)
{

    isPressed = false;
    isMoved = false;
    lastPoint = QPoint();
    x_left_distance = 0;
    x_right_distancce =0;
    y_top_distance =0;
    y_bottom_distance=0;
    this->installEventFilter(this);
}

YDragButton::~YDragButton()
{

}


void YDragButton::setMargin(int left, int top, int right, int bottom)
{
    x_left_distance = left;
    y_top_distance = top;
    x_right_distancce = right;
    y_bottom_distance = bottom;
}

/** 识别鼠标绑定事件
 * @brief YDragButton::eventFilter
 * @param watched
 * @param event
 * @return
 */
bool YDragButton::eventFilter(QObject *watched, QEvent *event)
{
    QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
    switch(event->type())
    {
    case QEvent::MouseButtonPress:
    {
        if (mouseEvent->button() == Qt::LeftButton) {
            lastPoint = mouseEvent->pos();
            isPressed = true;
        }
        break;
    }
    case QEvent::MouseMove:
    {
        if (isPressed) {
            int dx = mouseEvent->pos().x() - lastPoint.x();
            int dy = mouseEvent->pos().y() - lastPoint.y();
            int x1 = this->x()+dx;
            int y1 = this->y()+dy;
            int right_distance = this->parentWidget()->width() -2*x_right_distancce-this->width();
            int bottom_distance =this->parentWidget()->height() -2*y_bottom_distance -this->height();
            if(x1>x_left_distance &&x1< right_distance &&y1>y_top_distance &&y1<bottom_distance)
                this->move(this->x() + dx, this->y() + dy);
            isMoved = true;
        }
        break;
    }
    case QEvent::MouseButtonRelease:
    {
        if(isMoved !=true){
            emit clicked();
            emit toggled(!isChecked);
            isChecked = !isChecked;
        }else{
            isMoved = false;
        }
        isPressed = false;
        break;
    }
    case QEvent::MouseButtonDblClick:
        emit doubleClicked();
        break;
    default:
        break;
    }
    return QWidget::eventFilter(watched,event);
}

按钮的调用

    YDragButton *btn2 = new YDragButton(this);
    btn2->setText("雪景");
    btn2->setStyleSheet("background:transparent;font-size:50px,;color:red;");
    btn2->setGeometry(50,50,100,100);
    btn2->setMargin(0,0,0,0);
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值