• Qt事件处理机制(二)重写事件处理函数:重写鼠标移动事件,实现用鼠标拖动按钮在widget中自由移动!


    前言

    首先给出上一篇博客Qt事件处理机制(一)安装事件过滤器的地址:https://blog.csdn.net/qq_40876689/article/details/126473927?spm=1001.2014.3001.5502
    上篇博客总结了Qt事件处理机制常用的有2种方法,并记录了第一种方法安装事件过滤器的具体使用步骤及详细的代码。本篇博客记录一下第二种方法,重写事件处理函数的使用步骤以及相应代码。

    重写事件处理函数的步骤

    1.创建一个新的类,并继承自某一个Qt的类,该类中有你想要重写的事件处理函数。
    2.直接在新创建的类中重写相应的处理函数。
    此处就不详细说明了, 在下一步代码实例中进行举例说明。

    具体示例和代码详解

    1.效果图
    重写鼠标事件实现鼠标拖动按钮移动

    本示例想要自己处理按钮的鼠标按下事件、鼠标松开事件、鼠标移动事件,就需要创建一个类继承自QPushButton,然后重写QPushButton的三个事件处理函数,分别是:

    • mousePressEvent(QMouseEvent*e)
    • mouseRleaseEvent(QMouseEvent*e)
    • mouseMoveEvent(QMouseEvent*e)

    QBtnDog.h文件

    #pragma once
    #include 
    #include "ui_QBtnDog.h"
    
    class CQBtnDog : public QPushButton
    {
    	Q_OBJECT
    
    public:
    	CQBtnDog(QWidget*parent = nullptr);
    	~CQBtnDog();
    protected:
    	void mousePressEvent(QMouseEvent*);
    	void mouseReleaseEvent(QMouseEvent*);
    	void mouseMoveEvent(QMouseEvent*);
    private:
    	Ui::CQBtnDogClass ui;
    	bool m_pPressed;
    	QPoint m_pPointPress;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    QBtnDog.cpp文件

    #include "QBtnDog.h"
    #include 
    
    CQBtnDog::CQBtnDog(QWidget*parent)
    	: QPushButton(parent)
    	, m_pPressed(false)
    {
    	ui.setupUi(this);
    }
    CQBtnDog::~CQBtnDog()
    {}
    
    void CQBtnDog::mousePressEvent(QMouseEvent* event)
    {
    	m_pPressed = true;
    	m_pPointPress = QCursor::pos();       //记录鼠标按下时的坐标
    }
    
    void CQBtnDog::mouseReleaseEvent(QMouseEvent* event)
    {
    	m_pPressed = false;
    }
    
    void CQBtnDog::mouseMoveEvent(QMouseEvent* event)
    {
    	if (m_pPressed)
    	{
    		QPoint newPoint = QCursor::pos();	//记录鼠标移动最新的鼠标坐标
    		float xDis = newPoint.x() - m_pPointPress.x();				//计算移动后和按下时的坐标差x
    		float yDis = newPoint.y() - m_pPointPress.y();				//计算移动后和按下时的坐标差y
    		this->move(this->pos().x() + xDis, this->pos().y()+yDis);	//让自定义按钮的位置加上坐标差,并移动至加上移动距离之后的位置
    		m_pPointPress = QCursor::pos();		//更新按下时的坐标为当前坐标位置
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    新创建的类,继承了QPushButton,重写了QPushButton的鼠标按下、松开、移动事件处理函数,所以当鼠标在该按钮有相应的操作时,会执行重写的处理函数。
    在鼠标按下事件处理函数中,m_pPressed = true;用于标记鼠标是否按下状态,并记录下当前鼠标的位置。
    鼠标松开事件处理函数中,m_pPressed = false;表示鼠标已松开。
    鼠标移动事件处理函数中,先获取移动后的鼠标坐标,用移动后的鼠标坐标减去刚刚按下时的鼠标坐标,得到一个移动距离,然后移动当前窗口位置,也就是示例图中的newBtn按钮,将它的位置加上移动距离,就是移动后的位置;最后在更新一下记录最新鼠标坐标的变量;至此,鼠标放在自定义按钮上,按下之后,进行移动,自定义的按钮也会进行移动。

    常见的Qt事件类型及相应的事件处理函数

    1. 键盘事件: 按键按下和松开
    2. 鼠标事件: 鼠标移动,鼠标按键的按下和松开
    3. 拖放事件: 用鼠标进行拖放
    4. 滚轮事件: 鼠标滚轮滚动
    5. 绘屏事件: 重绘屏幕的某些部分
    6. 定时事件: 定时器到时
    7. 焦点事件: 键盘焦点移动
    8. 进入和离开事件: 鼠标移入widget之内,或是移出
    9. 移动事件: widget的位置改变
    10. 大小改变事件: widget的大小改变
    11. 显示和隐藏事件: widget显示和隐藏
    12. 窗口事件: 窗口是否为当前窗口
    事件类型名称对应的事件处理函数
    键盘按下keyPressEvent(QKeyEvnet* event)
    键盘松开keyReleaseEvent(QKeyEvnet* event)
    鼠标按下mousePressEvent(QMouseEvent* event)
    鼠标松开mouseReleaseEvent(QMouseEvent* event)
    鼠标移动mouseMoveEvent(QMouseEvent* event)
    鼠标双击事件mouseDoubleClickEvent(QMouseEvent* event)
    鼠标滚轮事件wheelEvent(QWheelEvent* event)
    重绘事件paintEvent(QPaintEvent* event)
    大小改变事件resizeEvent(QResizeEvent* event)
    移动事件moveEvent(QMoveEvent* event)
    进入事件enterEvent(QEvent* event)
    离开事件leaveEvent(QEvent* event)
    显示事件showEvent(QShowEvent* event)
    隐藏事件hideEvent(QHideEvent* event)

    总结

    本片博客主要记录重写事件处理函数的方法,例子中也展示了如何通过重写按钮鼠标移动事件,拖动按钮在widget中自由移动。
    兄弟加油!一起变强!

  • 相关阅读:
    让数据流动起来,RocketMQ Connect 技术架构解析
    opencv 的轮廓检测方法(7)
    【蓝桥每日一题]-前缀和与差分(保姆级教程 篇1)
    【PyTorch】深度学习实践之 梯度下降Gradient Descent
    Spring Boot、Spring Cloud 自定义配置文件(如何整合配置中心)
    解锁黑科技!群晖管家+cpolar内网穿透,让你的本地黑群晖实现公网远程访问!
    CODING DevSecOps 助力金融企业跑出数字加速度
    AI网络爬虫:下载m3u8视频文件
    Lotusscript中的Base64处理
    SSD1306 oled显示屏的驱动SPI接口
  • 原文地址:https://blog.csdn.net/qq_40876689/article/details/126491346