前几篇QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接),QT从入门到实战x篇_23_定时器实现方法1:事件timerEvent(QTimerEvent* ev),静态变量的作用域,初始化及赋值)介绍了鼠标与定时器事件,本篇将会介绍这些事件内部的机制。
总结:
- 用途:用于事件的分发
- 也可以做拦截操作,不建议
bool event(QEvent* e)
- 返回值如果是true代表用户处理这个事件,不向下分发了
e->type()==鼠标按下
1. event事件分发器
以前面的事件为例,当程序中触发鼠标及计时器事件并不是直接触发,而是需要通过一个
bool event(QEvent* e)
的事件分发器来触发对应的事件。其基本模型如下:
bool event(QEvent* e)
的参数为QEvent类,其返回值为bool类型,如果返回的是true
,代表用户要处理这个事件,不向下分发事件。
2. 通过event事件分发器拦截事件
根据这一特性可以做事件的拦截操作,例如在鼠标进入时不分发给对应的
mouseMoveEvent
中,而是在
bool event(QEvent* e)
就处理好了操作。一般不会做如此操作,为了演示效果,下边在事件分发器中做拦截。
在前面的例子中,鼠标移动就会输出坐标值,一旦进入TextLabel
中按下和释放鼠标也会有对应的输出。
此处通过事件分发器拦截鼠标按下事件。
(1)通过查看QEvent
类的介绍,查看到其中包含了Qt
中所有的event
知道对应的鼠标按下事件的枚举值
(2)对应代码:
mylabel.h
//通过重写event分发器拦截鼠标按下按钮
bool event(QEvent *e);
mylabel.cpp
//通过e来判断鼠标是否按下
bool myLabel::event(QEvent *e)
{
//如果是鼠标按下,在分发中做拦截操作
if(e->type()==QEvent::MouseButtonPress)
{
//将子类强转为父类
QMouseEvent* ev=static_cast<QMouseEvent *>(e);
QString str=QString::fromLocal8Bit("Event::鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
//true代表用户自己处理这个事件,不向下分发
return true;
}
//其他事件交给父类处理 默认处理
return QLabel::event(e);
}
运行结果:
上面进行拦截是很少使用的,因为QT中事件是很多的,主要是目的为了表明事件是由分发器进行分发的。
3. 学习视频地址:QT从入门到实战x篇_25_event事件分发器
整体代码如下:
mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent = nullptr);
//鼠标进入事件
void enterEvent(QEvent *event);
//鼠标离开事件
void leaveEvent(QEvent *);
//鼠标按下
virtual void mousePressEvent(QMouseEvent *ev);
//鼠标释放
virtual void mouseReleaseEvent(QMouseEvent *ev);
//鼠标移动
virtual void mouseMoveEvent(QMouseEvent *ev);
//通过重写event分发器拦截鼠标按下按钮
bool event(QEvent *e);
signals:
};
#endif // MYLABEL_H
mylabel.cpp
#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
//设置鼠标追踪状态,默认是false
setMouseTracking(true);
}
//鼠标进入事件
void myLabel::enterEvent(QEvent *event)
{
// qDebug()<<"鼠标进入";
}
//鼠标离开事件
void myLabel::leaveEvent(QEvent *)
{
// qDebug()<<"鼠标离开";
}
//鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{
//当鼠标左键按下,提示信息
// if(ev->button()==Qt::LeftButton)
// {
QString str=QString("鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
// }
}
//鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{
// if(ev->button()==Qt::LeftButton)
// {
QString str=QString("鼠标释放了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
// }
}
//鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
//&为位与运算符,只有在所有状态下均为左键按下时为真
// if(ev->buttons() & Qt::LeftButton)
// {
QString str=QString("鼠标移动了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
// }
}
//通过e来判断鼠标是否按下
bool myLabel::event(QEvent *e)
{
//如果是鼠标按下,在分发中做拦截操作
if(e->type()==QEvent::MouseButtonPress)
{
//将子类强转为父类
QMouseEvent* ev=static_cast<QMouseEvent *>(e);
QString str=QString::fromLocal8Bit("Event::鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug()<<str;
//true代表用户自己处理这个事件,不向下分发
return true;
}
//其他事件交给父类处理 默认处理
return QLabel::event(e);
}