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;
}
相关推荐
李元豪3 小时前
【智鹿空间】c++实现了一个简单的链表数据结构 MyList,其中包含基本的 Get 和 Modify 操作,
数据结构·c++·链表
UestcXiye3 小时前
《TCP/IP网络编程》学习笔记 | Chapter 9:套接字的多种可选项
c++·计算机网络·ip·tcp
一丝晨光4 小时前
编译器、IDE对C/C++新标准的支持
c语言·开发语言·c++·ide·msvc·visual studio·gcc
丶Darling.5 小时前
Day40 | 动态规划 :完全背包应用 组合总和IV(类比爬楼梯)
c++·算法·动态规划·记忆化搜索·回溯
内蒙深海大鲨鱼5 小时前
qt之ui开发
数据库·qt·ui
奶味少女酱~5 小时前
常用的c++特性-->day02
开发语言·c++·算法
我是哈哈hh5 小时前
专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结
c++·算法·动态规划
我有一颗薄荷糖6 小时前
Qt--命令行终端程序开发
开发语言·数据库·qt
_小柏_6 小时前
C/C++基础知识复习(15)
c语言·c++
_oP_i7 小时前
cmake could not find a package configuration file provided by “Microsoft.GSL“
c++