当前位置: 首页 > news >正文

Qt 事件处理

文章目录

  • Qt 事件概述
    • Qt事件的表示
    • Qt 事件的处理顺序
  • 覆盖过滤器eventFilter
  • 覆盖事件处理函数

Qt 事件概述

  • 事件(event)是由窗口系统(操作系统)或者Qt自身产生的,用以响应所发生的各类事件。QT程序是事件驱动的, 程序的每个动作都是由内部某个事件所触发。QT事件的发生和处理成为程序运行的主线,存在于程序整个生命周期
  • 常见的事件如:
    • 键盘或鼠标事件, 用户按下或者松开键盘或鼠标上的按键,就可以产生一个键盘或者鼠标事件
    • 绘制事件,某个窗口第一次显示时就会产生一个绘制事件,用来告诉窗口需要重新绘制它本身,从而使得该窗口可见
    • Qt事件,Qt自身也会产生很多事件,比如QObject::startTimer()会触发QTimerEvent事件
  • 应用场景
    • 全局快捷键/热键
    • 输入验证和格式化
    • 鼠标手势和拖拽
    • 自定义控件行为

Qt事件的表示

  • QT将系统产生的消息转化为QT事件,QT事件被封装为对象,所有的QT事件均继承抽象类QEvent,用于描述程序内部或外部发生的动作

  • 特殊情况: 在复写 closeEvent 时,注意如果调用 event->ignore() ,意味着关闭事件没有被处理,窗口不关闭;不调用(默认)或者显式调用了另外一个函数 event->accept() 则代表接受事件, 窗口允许被关闭

Qt 事件的处理顺序

  • 谁来接受和处理事件:答案是QObject
  • QObject 类是整个Qt对象模型的心脏,事件处理机制是QObject三大职责(内存管理、内省(intropection)与事件处理制)之一。任何一个想要接受并处理事件的对象均须继承自QObject,可以选择重载QObject::event()函数或事件的处理权转给父窗口
  • Qt框架内部为我们提供了一系列的事件处理机制,当窗口事件产生之后,事件会经过:事件派发 -> 事件过滤->事件分发->事件处理几个阶段
  • Qt窗口中对于产生的一系列事件都有默认的处理动作,如果我们有特殊需求就需要在合适的阶段重写事件的处理动作

  • 每一个Qt应用程序都对应一个唯一的 QApplication应用程序对象,然后调用这个对象的exec()函数,这样Qt框架内部的事件检测就开始了(程序将进入事件循环来监听应用程序的事件)
#include"mainwindow.h"#include<QApplication>intmain(intargc,char*argv[]){QApplicationa(argc,argv);MainWindow w;w.show();returna.exec();//开启事件循环}
  • 事件在Qt中产生之后的分发过程如下:
    • 当事件产生之后,Qt使用用应用程序对象调用notify()函数将事件发送到指定的窗口
[overridevirtual]boolQApplication::notify(QObject*receiver,QEvent*e)
- 注意,事件在发送之前可以通过事件过滤器进行过滤,默认不对任何产生的事件进行过滤
[virtual]boolQObject::eventFilter(QObject*watched,QEvent*event)
- 当事件发送到指定窗口之后,窗口的事件分发器会对收到的事件进行分类
[virtual]boolQObject::event(QEvent*e)//QWidget中重写了该方法
- 事件分发器会将分类之后的事件(鼠标事件、键盘事件、绘图事件。。。)分发给对应的事件处理函数进行处理,每个事件处理函数都有默认的处理动作(我们也可以重写这些事件处理器函数),比如:鼠标事件
  • QWidget类是Qt中所有窗口类的基类,在这个类里边定义了很多事件处理器函数,它们都是受保护的虚函数。 各个子组件中可以覆盖这些虚函数,例如,QPushButton中:
// /opt/Qt/6.2.4/Src/qtbase/src/widgets/widgets/qabstractbutton.cppvoidQAbstractButton::mouseReleaseEvent(QMouseEvent*e){Q_D(QAbstractButton);if(e->button()!=Qt::LeftButton){e->ignore();return;}d->pressed=false;if(!d->down){// refresh is required by QMacStyle to resume the default button animationd->refresh();e->ignore();return;}if(hitButton(e->pos())){d->repeatTimer.stop();d->click();//发射 click()信号e->accept();}else{setDown(false);e->ignore();}}

覆盖过滤器eventFilter

  • 实现一个事件过滤包括两个步骤:
    • 在目标对象上调用installEventFilter(),注册监视对象
    • 在监视对象的eventFilter()函数中处理目标对象的事件
voidQObject::installEventFilter(QObject*filterObj)//filterObj, 实现了eventFilter(QObject *obj, QEvent *event)的对象//在一个对象上安装事件过滤器filterObj//这样发往monitoredObj对象的所有事件,都会调用filterObj.eventFilter()进行过滤monitoredObj->installEventFilter(filterObj);
MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);//给pushbutton添加过滤器ui->pushButton->installEventFilter(this);}//过滤器中覆盖默认的eventFilterboolMainWindow::eventFilter(QObject*obj,QEvent*event){if(event->type()==QEvent::MouseButtonPress){qDebug()<<QString("%1 is press!").arg(obj->objectName());QPushButton*btn=static_cast<QPushButton*>(obj);qDebug()<<QString("%1 is press!").arg(btn->text());// 返回 true 表示事件已被处理,不再传递// 返回 false 表示继续传递returntrue;}returnQWidget::eventFilter(obj,event);}

覆盖事件处理函数

  • 覆盖closeEvent resizeEvent
voidMainWindow::closeEvent(QCloseEvent*ev){QMessageBox::Button btn=QMessageBox::question(this,"关闭窗口","您确定要关闭窗口吗?");if(btn==QMessageBox::Yes){// 接收并处理这个事件ev->accept();}else{// 忽略这个事件ev->ignore();}}voidMainWindow::resizeEvent(QResizeEvent*ev){qDebug()<<"oldSize: "<<ev->oldSize()<<"currentSize: "<<ev->size();}
http://www.jsqmd.com/news/558534/

相关文章:

  • 2026年靠谱的脑波注意力训练系统供应商/特殊学校脑波注意力训练系统/脑波注意力训练系统哪家好口碑优选公司 - 品牌宣传支持者
  • 【信息科学与工程学】【制造工程】第十篇 机床加工刀具(超高强度/超高硬度/超强应力/超耐高温/超精密)02
  • 2026年比较好的生涯测评系统软件/生涯测评系统平台/生涯测评系统解决方案靠谱公司推荐 - 品牌宣传支持者
  • YOLO-v5小目标检测:微小物体识别效果惊艳展示
  • MATLAB实战:手把手教你用HOPC算法搞定多模态遥感影像配准(附完整代码)
  • C语言学习笔记(一)从指针出发,打通数组与字符串
  • Nano-Banana效果展示:多款产品高清拆解图生成作品集
  • YOLOv9官方镜像深度体验:开箱即用,效果超出预期
  • 《与AI的妄想对话:如何给机器人造灵魂?》
  • 【数据库 面试突击 · 01】大厂高频面试题:从SQL执行原理到 InnoDB 全解析
  • 2026川酒贴牌代加工优质厂家推荐榜:散酒贴牌/散酒连锁加盟/泸州酒贴牌代加工/浓香白酒贴牌/清香白酒贴牌/白酒 OEM 贴牌/选择指南 - 优质品牌商家
  • Xshell隧道实战:5分钟搞定内网机器与数据库直连(附常见错误排查)
  • SNOMED CT入门指南:从概念、关系到数据文件,手把手带你理解这个医学术语标准
  • Windows下纯Python解析激光雷达pcap数据包:无需ROS和PCL的极简方案
  • 2026成都专业市场调查机构推荐榜:成都消费者市场调查公司、成都的市场调查公司排名、第三方市场调查公司推荐、第三方市场调查机构推荐选择指南 - 优质品牌商家
  • Z-Image-Turbo_Sugar脸部Lora技术栈解读:从AI模型到Web应用的全链路技术
  • Qwen3-TTS-Tokenizer-12Hz一文详解:Qwen3-TTS系列架构中的定位
  • Qwen3-0.6B-FP8模型服务化:使用Git进行版本管理与CI/CD集成
  • VideoAgentTrek-ScreenFilter极限压力测试:应对高并发视频流请求的稳定性表现
  • AUTOSAR CANTP:ISO 15765协议如何重塑车载诊断数据传输
  • ANSYS接触分析实战:从法兰连接案例看MPC绑定与标准接触设置技巧
  • Qwen-Image-Edit快速入门:上传模糊图片,一键生成高清人像
  • 5分钟掌握全平台资源下载神器:res-downloader终极配置与实战指南
  • 2026成都小规模代理记账公司评测报告:成都个体户注册公司、成都代理记账价格、成都代理记账报税、成都代理记账收费标准选择指南 - 优质品牌商家
  • CPU内部总线架构解析:数据通路设计与性能优化
  • 开源!比claude和codex的CLI更好用10倍的工具
  • Spring Boot集成AI推理服务全链路实践,从模型加载、线程池隔离到GPU资源抢占应对策略
  • OpenCV插值方法实战指南:从原理到性能优化
  • Xinference-v1.17.1在医疗领域的创新应用:智能预约系统开发
  • 实战指南:利用Python可视化常见激活函数(Sigmoid、Tanh、ReLU、PReLU)及其特性对比