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;
}