Qt事件传递顺序是怎样的?

发布于:2024-06-26 ⋅ 阅读:(15) ⋅ 点赞:(0)

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

  1. ChildWidget 的事件过滤器首先捕捉到事件并打印 Mouse button press event filtered in ChildWidget
  2. 然后,ChildWidgetmousePressEvent 捕捉到事件并打印 Mouse press event in ChildWidget
  3. 最后,如果事件未被完全处理,传递到父窗口 ParentWidget 的事件过滤器,并打印 Mouse button press event filtered in ParentWidget from ChildWidget
  4. 然后,ParentWidgetmousePressEvent 捕捉到事件并打印 Mouse press event in ParentWidget

3.2 点击 ParentWidget

  1. ParentWidget 的事件过滤器首先捕捉到事件并打印 Mouse button press event filtered in ParentWidget
  2. 然后,ParentWidgetmousePressEvent 捕捉到事件并打印 Mouse press event in ParentWidget

网站公告

今日签到

点亮在社区的每一天
去签到