Qt事件处理机制3-事件函数的分发

Qt开发中,经常重写event函数和具体的事件处理函数,例如mousePressEvent、paintEvent等,那么这些具体的事件处理函数是怎样被调用的呢?答案是由继承自QObject的类中的event函数来处理事件分发。这里以间接继承自QWidget的派生类MyButton举例说明。

MyButton.h

cpp 复制代码
#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QPushButton>

class MyButton : public QPushButton
{
    Q_OBJECT
public:
    MyButton(QWidget *parent = nullptr);
    ~MyButton();

protected:
    bool event(QEvent *e) override;
    void mousePressEvent(QMouseEvent *event) override;
};

#endif // MYBUTTON_H

MyButton.cpp

cpp 复制代码
#include "MyButton.h"
#include <QDebug>
#include <QEvent>
#include <QMouseEvent>
MyButton::MyButton(QWidget *parent) : QPushButton(parent)
{

}

MyButton::~MyButton()
{

}

bool MyButton::event(QEvent *e)
{
    if (e->type() == QEvent::MouseButtonPress)
    {
        qDebug() << __FUNCTION__ << e->isAccepted();
    }

    return QPushButton::event(e);
}

void MyButton::mousePressEvent(QMouseEvent *event)
{
    qDebug() << __FUNCTION__ << event->isAccepted();
}

MainWindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

protected:
    bool event(QEvent *e) override;
    void mousePressEvent(QMouseEvent *event) override;

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

MainWindow.cpp

cpp 复制代码
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QDebug>
#include <QEvent>
#include <QMouseEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::event(QEvent *e)
{
    if (e->type() == QEvent::MouseButtonPress)
    {
        qDebug() << __FUNCTION__ << e->isAccepted();
    }

    return QMainWindow::event(e);
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    qDebug() << __FUNCTION__ << event->isAccepted();
}

运行结果正常

cpp 复制代码
MyButton::event true
MyButton::mousePressEvent true

// 若如下修改MyButton::mousePressEvent函数
void MyButton::mousePressEvent(QMouseEvent *event)
{
    qDebug() << __FUNCTION__ << event->isAccepted();
    event->ignore();
}
那么运行结果为(该代码同时验证了上一篇文章所说的事件函数的传播):
MyButton::event true
MyButton::mousePressEvent true
MainWindow::event true
MainWindow::mousePressEvent true

可以看到,QPushButton::event(e)函数里最终调用了具体事件处理函数mousePressEvent,该函数是在QWidget类的event函数中进行分发的(MyButton->QPushButton->QAbstractButton->QWidget层层调用event函数)。

补充:QWidget中,event函数主要负责事件分发

cpp 复制代码
bool QWidget::event(QEvent *event)
{
	Q_D(QWidget);

    // ignore mouse and key events when disabled
    if (!isEnabled()) {
        switch(event->type()) {
        case QEvent::TabletPress:
        case QEvent::TabletRelease:
        case QEvent::TabletMove:
        case QEvent::MouseButtonPress:
        case QEvent::MouseButtonRelease:
        case QEvent::MouseButtonDblClick:
        case QEvent::MouseMove:
        case QEvent::TouchBegin:
        case QEvent::TouchUpdate:
        case QEvent::TouchEnd:
        case QEvent::TouchCancel:
        case QEvent::ContextMenu:
        case QEvent::KeyPress:
        case QEvent::KeyRelease:
#if QT_CONFIG(wheelevent)
        case QEvent::Wheel:
#endif
            return false;
        default:
            break;
        }
    }
    
	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;
    ...
        default:
        return QObject::event(event);
    }
    return true;
}
相关推荐
吹什么轩1 小时前
c++复习:模拟实现list来更好的理解和应用list
开发语言·c++
AmyLin_20011 小时前
PDF 色彩保真工程实践【5】核心实现(下):拼装 Image XObject、页面资源与内容流
c++·pdf·sdk·颜色空间·印刷·icc·cmyk
乱七八糟的屋子2 小时前
MTL4 (Matrix Template Library) 超详细实战教程|C++高性能稠密/稀疏矩阵计算
c++·矩阵·稀疏矩阵·mtl4·matrixtemplate·c++线性代数·高性能数值计算
依然鸣3 小时前
PTA团体程序设计天梯赛L2真题讲解L2-045-048
数据结构·c++·经验分享·学习·算法·pat考试·pat
有点。3 小时前
C++深度优先搜索(二)
开发语言·c++·深度优先
小小龙学IT4 小时前
Taskflow:用一张“任务图“玩转现代 C++ 并行编程开源项
c++·开源·github
wuminyu5 小时前
JUC包的AQS与JVM的ObjectMonitor机制对比分析
java·linux·c语言·jvm·c++
就不掉头发5 小时前
C++函数模板
java·开发语言·c++
Quz5 小时前
QML ProgressBar 自定义样式:自绘组件、Material风格
qt
Quz5 小时前
QML 环形进度条:Canvas 绘制与多环进度
qt