Qt事件event分发,事件和信号关系,事件过滤

一. Qt 的事件分发 event

1. 核心知识点:

event(QEvent *e) 是 Qt 事件系统的总入口函数,所有事件(鼠标、键盘、绘制等)都会先进入这个函数,再分发到具体的事件处理函数(如 mousePressEvent)

2. 核心作用:

统一拦截 / 处理多种类型事件

处理没有专属虚函数的事件(如自定义事件)

决定事件是否继续传递给父对象

3. 过程的理解

知识点是 Qt 交互的 "底层逻辑",核心是理解事件怎么从 "发生" 到 "被处理":

event () 当作事件的 "总接待处",专门处理事件的

事件分发返回真:当前事件处理完成

返回假:未处理,自动触发自动上传机制告诉副控件

event()函数进行事件分发,根据具体事件情况进行强类型转换,转换成对应指针,

// 在调用受保护的虚函数(这些虚函数叫做受保护的事件函数)

// 意思就是类型转换成对应子事件的类型,在调用该事件函数

4.应用

处理底层输入事件(鼠标 / 键盘 / 触摸)

Qt 没有将「鼠标移动、键盘按键、鼠标滚轮」等事件封装为通用信号(因为这类事件高度定制),需要重写对应的事件函数

需要手写的(举例)

捕获鼠标移动 / 点击 / 释放的精确坐标;

监听特定键盘按键(比如按 ESC 关闭窗口、按方向键控制界面元素);

处理触摸屏幕的多点触控事件;

拦截窗口关闭事件(比如关闭前弹出确认框)

二.事件和信号关系

任务分发时,默认先实现设置的内容,在完成对应分发内容

1. 机制

子类提示处理不了,交给父类处理

事件是核心机制,把操作系统能力封装起来,主要是异步操作,实现程序员和操作系统的衔接

信号是为了实现对象间的耦合性(不关心做什么,只关心要不要发出来这个信号 )

2. 信号事件区别

信号面向的是群体主键,事件面向的是核心机制(先有事件,再根据情况分发信号)

三.事件过滤

1.事件过滤和事件分发

是事件分发函数之前提供的一个机制

事件分发是直接作用到哪个对象,事件过滤是全局过滤

2. 举例

void QObject::installEventFilter(QObject *filterObj)

事件过滤器:eventFilter()

2.1 规则

return true :事件被吃掉,目标对象收不到

return false / 交给父类:事件继续传递

2.2 核心作用

让 filterObj 成为当前对象的「事件监听器」,当前对象的所有事件都会先经过 filterObj 的 eventFilter 函数

参数 filterObj 事件过滤器对象(必须是 QObject 子类,且重写了 eventFilter 函数)

所属类 QObject(Qt 所有对象的基类,包括所有控件:QLabel、QWidget、QPushButton 等)

2.3 筛选的作用

相当于给 InnerLabel(当前对象)装了一个 "监控摄像头"(filterObj 即 Widget),InnerLabel 的所有 "动作"(事件)都会先被摄像头拍到,摄像头可以选择 "放行"(事件继续传递)或 "拦截"(事件终止)

3. 使用场景与注意事项

(1)适用场景

监听第三方控件事件:无法修改控件源码(比如 Qt 原生 QLabel),但需要监听其事件;

统一管控多个控件:一个过滤器监听多个控件(比如同时监听 Label、Button、LineEdit);

临时拦截事件:比如 "权限不足时禁止点击按钮 / Label";

调试事件:快速打印某个控件的所有事件,定位问题。

(2)注意事项

必须重写 eventFilter:只安装过滤器但不重写 eventFilter,相当于没装(事件直接放行);

不要漏写父类返回:最后必须 return QWidget::eventFilter(...),否则会影响其他控件的事件;

避免循环过滤:不要在 eventFilter 里给当前 watched 对象再次安装过滤器,会导致死循环;

记得移除过滤器:如果过滤器对象(Widget)先于目标对象(InnerLabel)销毁,需提前移除,否则可能崩溃

过滤安装到父对象上

4. 过滤器函数(必须和安装过滤器搭配用)

4.1过滤器函数

bool eventFilter(QObject *watched, QEvent *event) override{}

// watched:触发事件的对象(比如 in_label)

// event:具体的事件(鼠标点击、键盘输入、绘制等)

使用: watched == ui->pushButton

只处理这个按钮的事件,避免干扰别的控件

4.2 在构造函数中给主控件安装过滤器

// 让 this(当前窗口)去监听 ui->pushButton

ui->pushButton->installEventFilter(this);

installEventFilter(用于给函数安装过滤) → 给住户装监控的动作(告诉安保:"我要监控这个住户的所有进出");

eventFilter → 安保的监控规则 / 处理逻辑(安保看到住户进出时,判断 "放行 / 拦截 / 记录")

5.流程图

相关推荐
载数而行5203 小时前
Qt鼠标处理的项目,包含事件分发、处理机制
qt
qq_283720053 小时前
Qt QML 中为 ComBox设置鸿蒙字体(HarmonyOS Sans)——适配 Qt 5.6.x 与 Qt 5.12+
c++·qt·harmonyos
小郭学习之路3 小时前
Qt vs tools的一个编译问题
开发语言·qt
C++ 老炮儿的技术栈5 小时前
Qt 开发机器人客户端程序
c语言·开发语言·c++·windows·qt·机器人
Ronin3055 小时前
【Qt系统相关】Qt系统相关
网络·qt·音视频·多线程·定时器·事件·qt文件
娇娇yyyyyy21 小时前
QT编程(15): Qt 按键事件和定时器事件
开发语言·qt
GIS阵地1 天前
QgsDataSourceUri解析
数据库·c++·qt·开源软件·qgis
载数而行5201 天前
Qt事件常用类,QLabel的QFrame交互
qt
娇娇yyyyyy1 天前
QT编程(16): Qt Model
开发语言·qt