QT从入门到入土(七)——鼠标事件

引言
个人认为,事件机制是Qt最难以理解且最为精妙的一部分。事件主要分为两种:

  1. 在与用户交互时发生。比如按下鼠标(mousePressEvent),敲击键盘(keyPressEvent)等。
  2. 系统自动发生,比如计时器事件(timerEvent)等。

在发生事件时(比如说上面说的按下鼠标),就会产生一个QEvent对象(这里是QMouseEvent,为QEvent的子类),这个QEvent对象会传给当前组件的event函数。如果当前组件没有安装事件过滤器(这个后面会提到),则会被event函数发放到相应的xxxEvent函数中(这里是mousePressEvent函数)。

需要区分的是:事件与信号并不相同。

比如:鼠标单击按钮,鼠标事件(QMouseEvent),而按钮本身发射clicked()信号。一般而言我们只需要关注单击信号,不用考虑鼠标事件。但是当我们要对该按钮做额外操作,不想通过信号处理,此时事件就是一个很好的选择。关闭事件(QCloseEvent)是一个常用的事件。

**

一,事件

**
Qt 中所有事件类都继承于 QEvent。在事件对象创建完毕后,Qt 将这个事件对象传递给 QObject 的 event()函数。event()函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函数(eventhandler)。
在这里插入图片描述

信号是通过connect()来绑定槽函数处理响应,那么事件是怎么处理的呢?
处理事件有5种常用的方法:

  1. 重新实现部件的paintEvent()、mousePressEvent()等事件处理函数。这是最常用的一种方法,不过只能用来处理特定部件的特定事件(即需要新建类去实现)
  2. 重新实现notify()函数。这个函数的功能强大,提供了完全的控制,可以再事件过滤器得到事件之间就获得他们。但是,它一次只能处理一个事件。
  3. 向QApplication对象上安装事件过滤器。因为一个程序只有一个QApplication对象,实现的功能和notify()函数相同,优点是可以同时处理多个事件。
  4. 重新实现event()函数。QObject类的event()函数可以在事件达到默认事件处理函数之前获得该事件。
  5. 在对象上安装事件过滤器。使用事件过滤器可以再一个界面类中同时处理不同子部件的事件(在本类中实现)

实际编程中最常用的是方法(1),其次是方法(5)。方法2要继承QApplication类,方法3需要全局的事件过滤器,减缓事件的传递。

鼠标事件:

常用的鼠标事件:(本篇处理事件用的是方法一:重写鼠标事件)

void mousePressEvent(QMouseEvent *event); //单击
void mouseReleaseEvent(QMouseEvent *event); //释放
void mouseDoubleClickEvent(QMouseEvent *event); //双击
void mouseMoveEvent(QMouseEvent *event); //移动
void wheelEvent(QWheelEvent *event); //滑轮
鼠标事件使用的时候,加头文件: #include

重写事件框架:

1️⃣鼠标按下事件

void Widget::mousePressEvent(QMouseEvent *event)
{
   
    // 如果是鼠标左键按下   
    if(event->button() == Qt::LeftButton){
   
        ···
    }
    // 如果是鼠标右键按下
    else if(event->button() == Qt::RightButton){
   
       ···
    }
}

2️⃣鼠标移动事件

void Widget::mouseMoveEvent(QMouseEvent *event)
{
   
    // 这里必须使用buttons()
    if(event->buttons() & Qt::LeftButton){
     //进行的按位与
       ···
    }
}

默认情况下,触发事件需要点击一下,才能触发。可设置为自动触发:setMouseTracking(true);

3️⃣鼠标释放事件

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
   
   ···
}

4️⃣鼠标双击事件

void Widget::mouseDoubleClickEvent(QMouseEvent *event)
{
   
    // 如果是鼠标左键按下
    if(event->button() == Qt::LeftButton){
   
      
        ···
    }
}

5️⃣滚轮事件

void Widget::wheelEvent(QWheelEvent *event)
{
   
    // 当滚轮远离使用者时
    if(event->delta() > 0){
   
        ···
    }else{
   //当滚轮向使用者方向旋转时
        ···
    }
}

实例演示(在label控件中,移动鼠标获取实时位置,并显示在界面上)

创建mylabel类,基类设置为QLabel
在这里插入图片描述

这里用了类似自定义控件的方法,对Mylabel类进行封装。设置基类QLabel 是为了在ui界面中提升label控件(即将label控件和Mylabel关联,提升时候必须二者基类相同)

在mylabel.h中声明鼠标事件

#pragma once
#include <qlabel.h>

class mylabel : public QLabel
{
   
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

We唯有自己强大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值