轉載至:https://www.deeplearn.me/349.html
一、說明
Qt 處理事件的方式之一:”繼承 QApplication 並重新實現 notify()函數”。Qt 調用 QApplication 來發送一個事件,重新實現 notify()函數是在事件過濾器得到所有事件之前獲得它們的唯一方法。事件過濾器使用更為便利。因為可以同時有多個事件過濾器。而 notify()函數只有一個。
二、函數的使用
重新實現的 QApplication 類 MyApplication 的頭文件 myapplication.h 如下:
#ifndef MYAPPLICATION_H #define MYAPPLICATION_H #include <QApplication> #include <QEvent> class MyApplication : public QApplication { public: MyApplication(int & argc, char ** argv); public: bool notify(QObject *receiver, QEvent *e); }; #endif
myapplication.cpp 文件如下:
#include "myapplication.h" #include <QMouseEvent> MyApplication::MyApplication(int & argc, char ** argv) : QApplication(argc, argv) { } bool MyApplication::notify(QObject *receiver, QEvent *e) { //屏蔽 MouseButtonPress、MouseButtonRelease 和 MouseMove 事件 if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonRelease || e->type() == QEvent::MouseMove) { return true; } return QApplication::notify(receiver, e); }
mainwindow.h 文件如下:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui/QMainWindow> #include <QPushButton> #include <QMouseEvent> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); protected: bool eventFilter(QObject *obj, QEvent *e); private: QPushButton *button; }; #endif
mainwindow.cpp 文件如下:
#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { button = new QPushButton; this->setCentralWidget(button); } MainWindow::~MainWindow() { } bool MainWindow::eventFilter(QObject *obj, QEvent *e) { if (obj == button) //響應 button 的 MouseButtonPress 和 MouseButtonRelease 事件 { if (e->type() == QEvent::MouseButtonPress) { QMouseEvent *event = static_cast<QMouseEvent*> (e); button->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); button->setText(QString("Release: %1, %2").arg(QString::number(event->x()), QString::number(event->y()))); return true; } else { return false; } } return QMainWindow::eventFilter(obj, e); }
main.cpp 文件如下:
#include <QtGui/QApplication> #include <QtCore/QTextCodec> #include "mainwindow.h" #include "myapplication.h" int main(int argc, char *argv[]) { MyApplication a(argc, argv); QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030")); MainWindow mainwindow; a.installEventFilter(&mainwindow); //為 QApplication 注冊過濾器 mainwindow.setWindowTitle(QObject::tr("繼承 QApplication 並重新實現 notify()函數")); mainwindow.resize(400, 200); mainwindow.show(); return a.exec(); }
運行程序,可以發現 button 不管是點擊、釋放還是拖動鼠標,都不會顯示任何文本。因為我們已經子類化 QApplication,事件在到達 QApplication 的事件過濾器之前,會先到達 QApplication 的 notify()函數,我們已經在子類化的 MyApplication 中屏蔽了 MouseButtonPress、MouseButtonRelease 事件。所以為 MyApplication 對象注冊的事件過濾器不起作用。程序運行界面為: