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

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值