1、事件传递顺序规则
在Qt中,事件传递的顺序事件首先传递到目标对象的事件过滤器,然后传递到事件处理函数,最后传递到父对象的事件过滤器和事件处理函数。
为了更好地理解这一过程,下面将通过一个示例来展示事件在父窗口和子窗口之间的传递顺序。
2、示例:父子窗口的事件传递
2.1 项目结构
myproject/
├── main.cpp
├── parentwidget.h
├── parentwidget.cpp
├── childwidget.h
└── childwidget.cpp
2.2 main.cpp
#include <QApplication>
#include "parentwidget.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
ParentWidget parentWidget;
parentWidget.setGeometry(100, 100, 400, 400);
parentWidget.setStyleSheet("background-color: lightblue;");
parentWidget.show();
return app.exec();
}
2.3 parentwidget.h
#ifndef PARENTWIDGET_H
#define PARENTWIDGET_H
#include <QWidget>
#include "childwidget.h"
class ParentWidget : public QWidget {
Q_OBJECT
public:
ParentWidget();
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
private:
ChildWidget *childWidget;
};
#endif // PARENTWIDGET_H
2.4 parentwidget.cpp
#include "parentwidget.h"
#include <QDebug>
#include <QEvent>
ParentWidget::ParentWidget() {
childWidget = new ChildWidget(this);
childWidget->setGeometry(50, 50, 200, 200);
childWidget->setStyleSheet("background-color: yellow;");
// Only install event filter on itself, not on the child widget
this->installEventFilter(this);
}
bool ParentWidget::eventFilter(QObject *obj, QEvent *event) {
if (event->type() == QEvent::MouseButtonPress) {
if (obj == this) {
qDebug() << "Mouse button press event filtered in ParentWidget";
}
}
return QWidget::eventFilter(obj, event);
}
void ParentWidget::mousePressEvent(QMouseEvent *event) {
qDebug() << "Mouse press event in ParentWidget";
QWidget::mousePressEvent(event);
}
2.5 childwidget.h
#ifndef CHILDWIDGET_H
#define CHILDWIDGET_H
#include <QWidget>
class ChildWidget : public QWidget {
Q_OBJECT
public:
ChildWidget(QWidget *parent = nullptr);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
};
#endif // CHILDWIDGET_H
2.6 childwidget.cpp
#include "childwidget.h"
#include <QDebug>
#include <QEvent>
ChildWidget::ChildWidget(QWidget *parent) : QWidget(parent) {
// Install event filter on itself
this->installEventFilter(this);
}
bool ChildWidget::eventFilter(QObject *obj, QEvent *event) {
if (event->type() == QEvent::MouseButtonPress) {
if (obj == this) {
qDebug() << "Mouse button press event filtered in ChildWidget";
}
}
return QWidget::eventFilter(obj, event);
}
void ChildWidget::mousePressEvent(QMouseEvent *event) {
qDebug() << "Mouse press event in ChildWidget";
QWidget::mousePressEvent(event);
}
3、示例解释和运行结果
3.1 点击 ChildWidget
时
ChildWidget
的事件过滤器首先捕捉到事件并打印Mouse button press event filtered in ChildWidget
。- 然后,
ChildWidget
的mousePressEvent
捕捉到事件并打印Mouse press event in ChildWidget
。 - 最后,如果事件未被完全处理,传递到父窗口
ParentWidget
的事件过滤器,并打印Mouse button press event filtered in ParentWidget from ChildWidget
。 - 然后,
ParentWidget
的mousePressEvent
捕捉到事件并打印Mouse press event in ParentWidget
。
3.2 点击 ParentWidget
时
ParentWidget
的事件过滤器首先捕捉到事件并打印Mouse button press event filtered in ParentWidget
。- 然后,
ParentWidget
的mousePressEvent
捕捉到事件并打印Mouse press event in ParentWidget
。