qt5-事件过滤器
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过滤器-->控件过滤器
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)