Qt 处理事件的第三种方式:”在 QObject 中注册事件过滤器”,如果对象使用 installEventFilter()函数注册了事件过滤器,目标对象中的所有事件将首先发给这个监视对象的 eventFilter()函数。
mybutton.h 文件如下:
#ifndef MYBUTTON_H #define MYBUTTON_H #include <QPushButton> #include <QMouseEvent> class MyButton : public QPushButton { protected: bool event(QEvent *e); }; #endif
mybutton.cpp 文件如下:
#include "mybutton.h" bool MyButton::event(QEvent *e) { if (e->type() == QEvent::MouseButtonPress) { QMouseEvent *event = static_cast<QMouseEvent*> (e); this->setText(QString("Press: %1, %2").arg(QString::number(event->x()), QString::number(event->y()))); return true; } else if (e->type() == QEvent::MouseButtonRelease) { QMouseEvent *event = static_cast<QMouseEvent*> (e); this->setText(QString("Release: %1, %2").arg(QString::number(event->x()), QString::number(event->y()))); return true; } else if (e->type() == QEvent::MouseMove) { QMouseEvent *event = static_cast<QMouseEvent*> (e); this->setText(QString("Move: %1, %2").arg(QString::number(event->x()), QString::number(event->y()))); return true; } return QPushButton::event(e); //其他事件调用基类的 event()函数进行处理 }
在这里,我们把 button 称为目标对象,MainWindow 实现了 eventFilter()函数,用 MainWindow 来监视 button,称 MainWindow 为监视对象。
mainwindow.h 文件如下:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui/QMainWindow> #include "mybutton.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); protected: bool eventFilter(QObject *obj, QEvent *e); private: MyButton *button; }; #endif
mainwindow.cpp 文件如下:
#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { button = new MyButton; this->setCentralWidget(button); button->installEventFilter(this); //为 button 设置过滤器 } MainWindow::~MainWindow() { } bool MainWindow::eventFilter(QObject *obj, QEvent *e) { if (obj == button) { if (e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove) //屏蔽 MouseButtonRelease 和 MouseMove 事件 { return true; } else { return false; } } return QMainWindow::eventFilter(obj, e); }
运行程序,可以发现 button 的文本不管是点击、释放还是拖动鼠标,都只显示鼠标按下的文本,因为我们已经为 button 注册了事件过滤器,在监视对象 MainWindow 中,事件处理函数 eventFilter()函数屏蔽了 button 的 MouseButtonRelease 和 MouseMove 事件。所以目标对象 button 的 MouseButtonRelease 和 MouseMove 事件得不到响应。
故事件是先经过监视对象的 eventFilter()函数,然后在响应目标对象 button 的所有事件,程序运行界面为: