在Qt中,event()函数是所有事件进入一个对象的总入口。它本身不直接处理事件,而是像一个 “总调度员”,负责把特定类型的事件(如鼠标点击、键盘按键)分发给对应的事件处理器(如 mousePressEvent,keyPressEvent)
- 事件分发:
这是它的首要职责。根据 QEvent::type() 判断事件类型,然后调用对应的具体事件处理函数。 - 提前拦截或替换处理:
在事件被分发给具体处理器之前,你可以重写这个函数来执行一些前置操作,甚至完全接管某个事件的处理。
可以通过查看Qt源码验证,在qwidget.cpp的event()事件分发函数中,通过区分不同的事件类型来调用特定的事件处理函数
也就是说,可以在事件到达默认的事件处理函数之前,在event()中截获
bool QWidget::event(QEvent *event)
{
switch (event->type()) {
case QEvent::MouseMove:
mouseMoveEvent((QMouseEvent*)event);
break;
case QEvent::MouseButtonPress:
mousePressEvent((QMouseEvent*)event);
break;
case QEvent::MouseButtonRelease:
mouseReleaseEvent((QMouseEvent*)event);
break;
case QEvent::MouseButtonDblClick:
mouseDoubleClickEvent((QMouseEvent*)event);
break;
case QEvent::Drop:
dropEvent((QDropEvent*) event);
break;
case QEvent::DragEnter:
dragEnterEvent((QDragEnterEvent*) event);
break;
case QEvent::DragMove:
dragMoveEvent((QDragMoveEvent*) event);
break;
case QEvent::DragLeave:
dragLeaveEvent((QDragLeaveEvent*) event);
break;
default:
return QObject::event(event);
}
return true;
}
1. 重写 event() 函数
首先,在 labelpropagate.h 中,声明event()事件分发函数,如下:
class LabelPropagate : public QLabel {
protected:
bool event(QEvent *e);
};
然后,在labelpropagate.cpp 中,实现event()函数,如下:
// 最后调用了父类的 event() 函数,父类的 event() 函数的作用就是接着把事件分发到特定的事件处理函数。
// 如果直接返回 true 或 false 而不调用父类的 event() 函数,则无法将事件传递给特定的事件处理函数!
bool LabelPropagate::event(QEvent *e)
{
if (e->type() == QEvent::MouseButtonPress) {
qDebug() << "LabelPropagate::event()";
}
return QLabel::event(e); // 调用父类的 event() 函数
}
此时,运行效果:
此时的事件传递流程:
(1)事件首先到达LabelPropagate中的event()函数
(2)上一步的event()函数,调用了父类的event()函数,因此事件被分发到PropagateLabel中的mouseMoveEvent()函数
(3)PropagateLabel中的mouseMoveEvent()函数,忽略了该事件,因此事件又被传递到PropagateWidget中的 mouseMoveevent()函数
2. event() 的返回值
事件分发函数event()返回一个bool值,通常直接调用父类的event()事件分发函数,这样可以接着把事件分发到特定的事件处理函数
那么:如果不调用父类的event()函数,而是直接返回true或者false,会有什么效果呢?
// 这里对于 QEvent::MouseButtonPress 事件,
// 1. 直接返回 true
// 表示事件被识别,传递到此为止,不会接着传递。
// 此时运行,控制台打印如下:
// LabelPropagate::event()
//
// 2. 直接返回 false
// 表示事件没有被识别,会接着传递。
// 由于没有调用调用父类的 event() 函数,因此不会将事件分发到 LabelPropagate 的 mousePressEvent(),
// 而是直接传递给父控件的 mousePressEvent()
// 此时运行,控制台打印如下:
// LabelPropagate::event()
// PropagateWidget::mousePressEvent()
bool LabelPropagate::event(QEvent *e)
{
if (e->type() == QEvent::MouseButtonPress) {
qDebug() << "LabelPropagate::event()";
// return true;
return false;
}
return QLabel::event(e);
}






