1、事件過濾器用於攔截傳遞到目標對象的事件,這樣可以實現監視目標對象事件的作用
2、Qt 實現事件過濾器的步驟如下:
①、Qt 調用void QObject::installEventFilter (QObject* filterObj),給filterObj 對象設置安裝(或注冊)事件過濾器,filterObj 也稱為過濾器對象。事件過濾器通常在構造函數中進行注冊。
②、在上一步注冊的 filterObj 對象,通過調用bool QObject::eventFilter(QObject* obj, QEvent* e);來接收攔截到的事件。也就是說攔截到的事件在 filterObj 對象中的 eventFilter 函數中處理。eventFilter 的第一個參數 obj 指向的是事件本應傳遞到的目標對象
這樣,該組件及其子組件的事件就會被監聽
③、使用 QObject::removeEventFilter(QObject *obj)函數可以刪除事件過濾器
3、事件過濾器處理事件的規則
①、過濾器對象的
eventFilter()函數可以接受或拒絕攔截到的事件,
若該函數返回 false,則表示事件需要作進一步處理,此時
事件會被發送到目標對象本身進行處理(注意:這里並未向父對象進行傳遞),
若 evetnFilter()返回 true,則表示停止處理該事件,此時目標對象和后面安裝的事件過濾器就無法獲得該事件
②、若同一對象安裝了多個事件過濾器,則最后安裝的過濾器首先被激活
a.h
#ifndef A_H #define A_H #include<QObject> #include<QMouseEvent> #include <QDebug> class A : public QObject //A類的對象用作過濾器對象,使用事件過濾器需繼承QObject { Q_OBJECT public: explicit A(QObject *parent = nullptr); bool eventFilter(QObject *w, QEvent *e);//重寫事件過濾函數 //w 事件接受者指針 signals: }; #endif // A_H
a.cpp
#include "a.h" A::A(QObject *parent) : QObject(parent) { } bool A::eventFilter(QObject *w, QEvent *e) { if(e->type()==QEvent::MouseButtonPress){ qDebug()<<w->objectName();//驗證 w 為事件本應到達的目標對象 qDebug()<<"A事件過濾函數"; return 1;//返回 1 表示該事件不再進一步處理 } return 0;/*返回 0 表示其余事件交還給目標對象處理,本例應返回 0,否則添加了該 過濾器的安鈕會無法顯示。*/ }
b.h
#ifndef B_H #define B_H #include "a.h" class B : public A { public: B(); bool eventFilter(QObject *w, QEvent *e); }; #endif // B_H
b.cpp
#include "b.h" B::B() { } bool B::eventFilter(QObject *w, QEvent *e) { if(e->type()==QEvent::MouseButtonPress){ qDebug()<<w->objectName(); qDebug()<<"B事件過濾函數"; return 0; //把事件傳遞給目標對象w } return 0; }
d.h
#ifndef D_H #define D_H #include <QPushButton> #include<QMouseEvent> #include <QDebug> class D : public QPushButton { public: D(); void mousePressEvent(QMouseEvent *e); }; #endif // D_H
d.cpp
#include "d.h" D::D() { } void D::mousePressEvent(QMouseEvent *e) { qDebug()<<"D按下了鼠標"; }
win.h
#ifndef WIN_H #define WIN_H #include <QWidget> #include <QDebug> class Win : public QWidget { Q_OBJECT public: Win(QWidget *parent = nullptr); ~Win(); void mousePressEvent(QMouseEvent *e); }; #endif // WIN_H
win.cpp
#include "win.h" Win::Win(QWidget *parent) : QWidget(parent) { } Win::~Win() { } void Win::mousePressEvent(QMouseEvent *e) { qDebug()<<"win你按下了鼠標"; }
main.cpp
#include "win.h" #include "d.h" #include "b.h" #include "a.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Win w; D* pd=new D; pd->setParent(&w); pd->setText("AAA"); pd->move(22,22); D *pd1=new D; pd1->setParent(&w); pd1->setText("BBB"); pd1->move(99,22); A ma; B mb; mb.setParent(&ma); pd->installEventFilter(&mb);//注冊過濾器對象 pd1->installEventFilter(&ma); ma.setObjectName("ma"); mb.setObjectName("mb"); w.setObjectName("mc"); pd->setObjectName("pd"); pd1->setObjectName("pd1"); w.resize(300,200); w.show(); return a.exec(); }
以上工程下載地址:鏈接:https://pan.baidu.com/s/18nl3rq2SWsrw7ZAAdPY4Cg 提取碼:6666
實例二:面向對象
win.h
#ifndef WIN_H #define WIN_H #include <QWidget> #include <QDebug> class Win : public QWidget { Q_OBJECT public: Win(QWidget *parent = nullptr); ~Win(); bool eventFilter(QObject *obj, QEvent *ev); //重寫事件過濾函數 }; #endif // WIN_H
win.cpp
#include "win.h" Win::Win(QWidget *parent) : QWidget(parent) { this->installEventFilter(this); } Win::~Win() { } bool Win::eventFilter(QObject *obj, QEvent *ev) { static int i=0; qDebug()<<"事件過濾函數:"<<i++; return 0;//交給目標對象處理 }
上面工程下載地址:鏈接:https://pan.baidu.com/s/1WuHzaavOrH_JNrGFWQ66Uw 提取碼:6666
注意:方法一:如果只是給控件注冊了過濾器,只是過濾控件
方法二:如果給
QApplication安裝了過濾器,那么對所有事件進行過濾

方法三:重寫notify(事件分發)函數
順序:notify(事件分發)函數-->QApplication過濾器-->控件過濾器