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

QT之事件系统

QT之事件系统

  • 1. 概述
  • 2. 事件的传递
  • 3. 事件类型
  • 4. 事件处理与事件过滤
  • 5. 自定义事件
    • 5.1 Demo
  • 6. 发送事件
  • 7. 参考

1. 概述

在QT中,事件均派生自QEvent抽象类,事件可以由任何派生自QObject的子类实例接收和处理。它们与widget关联性极强。

2. 事件的传递

当事件发生时,QT 通过构造适当的 QEvent 子类实例来创建一个事件对象来表示它,并通过调用其 event() 函数将其传递给 QObject 的特定实例

event() 函数本身不处理事件;它根据传递的事件类型,它会调用该特定类型事件的事件处理程序,并根据事件是被接受还是被忽略来发送响应。

传递的顺序如下:
在这里插入图片描述

3. 事件类型

大多数事件类型都有特殊的类,特别是 QResizeEvent、QPaintEvent、QMouseEvent、QKeyEvent 和 QCloseEvent。 每个类都是 QEvent 的子类并添加特定于事件的函数。 例如,QResizeEvent 添加了 size() 和 oldSize() 以使小部件能够发现它们的尺寸是如何改变的。

每个事件都有一个关联的类型,在 QEvent::Type 中定义,这可以用作运行时类型信息的方便来源,以快速确定给定事件对象是从哪个子类构造的。

具体的事件类型可参考,官网介绍

4. 事件处理与事件过滤

常用的事件处理方式如下:

  • 重写各种事件的虚函数
    如paintEvent()、mousePressEvent()等。这是最常见的方式,同时也是最简单和功能最弱的方式
  • 重写event()函数
    event()函数是所有对象的事件入口,QObject和QWidget中的实现,默认是把事件传递给特定的事件处理函数
  • 在特定对象上面安装事件过滤器
    该过滤器仅过滤该对象接收到的事件。
  • 在QCoreApplication::instance()上面安装事件过滤器
    该过滤器将过滤所有对象的所有事件,因此和notify()函数一样强大,但是它更灵活,因为可以安装多个过滤器。全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件。全局过滤器有一个问题:只能用在主线程。
  • 重写QCoreApplication::notify()函数
    这是最强大的,和全局事件过滤器一样提供完全控制,并且不受线程的限制。但是全局范围内只能有一个被使用(因为QCoreApplication是单例的)
    Qt 调用 QApplication 来发送一个事件,重新实现 notify()函数是在事件过滤器得到所有事件之前获得它们的唯一方法。事件过滤器使用更为便利。因为可以同时有多个事件过滤器。而 notify()函数只有一个。

5. 自定义事件

QT自定义事件的创建步骤如下:

  1. 继承QEvent类
  2. 定义一个事件类型的两种方式
    • QT中有两个宏用来定义了用户事件的最大边界(QEvent::MaxUser)和最小边界(QEvent::User)
    • QT事件系统注册自定义事件类型
      在上述步骤中可以创建出一个与系统事件类型不冲突的自定义事件类型,但是无法保证自定义事件类型不冲突。因此需要将自定义事件类型注册到QT事件系统中,这样若有相同的类型再次被注册时QT事件系统就可以处理自定义事件类型冲突的问题。注册函数如下:
      // 线程安全
      // registerEventType 若传入参数可用则返回此参数,否则返回QEvent::MaxUser和QEvent::User之间的值,若参数不在QEvent::MaxUser和QEvent::User之间则忽略参数
      static int QEvent::registerEventType ( int hint = -1 );
      

5.1 Demo

  • myevent.h
    #ifndef MYEVENT_H
    #define MYEVENT_H#include <QEvent>class MyEvent : public QEvent
    {
    public:MyEvent();int getValue();static Type eventType;
    private:int m_value;
    };#endif // MYEVENT_H
  • myevent.cpp
    #include "myevent.h"QEvent::Type MyEvent::eventType = (QEvent::Type)QEvent::registerEventType();
    MyEvent::MyEvent(): QEvent(eventType),m_value(1)
    {
    }int MyEvent::getValue()
    {return m_value;
    }
  • mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACEclass MainWindow : public QMainWindow
    {Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();virtual bool event(QEvent *event) override;
    protected:// 自定义事件的处理(专门处理自定义事件的),也可以用event()函数处理virtual void customEvent(QEvent *event) override;
    private:Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
  • mainwindow.cpp
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "myevent.h"
    #include <QDebug>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
    {ui->setupUi(this);MyEvent* myEvent = new MyEvent;// 事件只能定义在堆上,不用手动释放,系统会自动释放qApp->postEvent(this,myEvent);
    }MainWindow::~MainWindow()
    {delete ui;
    }bool MainWindow::event(QEvent *event)
    {QEvent::Type eventType = event->type();if(eventType == MyEvent::eventType){MyEvent* myEvent = dynamic_cast<MyEvent*>(event);qDebug() << "event" << eventType ;qDebug() << "event" << myEvent->getValue() ;event->ignore();}// 处理完成后继续传播事件,这样customEvent就会收到自定义事件return QObject::event(event);
    }void MainWindow::customEvent(QEvent *event)
    {QEvent::Type eventType = event->type();if(eventType == MyEvent::eventType){// 这里默认是trueqDebug() << "customEvent" << event->isAccepted();MyEvent* myEvent = dynamic_cast<MyEvent*>(event);qDebug() << "customEvent" << eventType ;qDebug() << "customEvent" << myEvent->getValue() ;//event->accept();}
    }
    

event()处理事件的时机比customEvent()处理的早

6. 发送事件

  1. sendEvent()
    sendEvent() 立即处理事件。 当它返回时,事件过滤器和/或对象本身已经处理了该事件。
    对于许多事件类,有一个名为 isAccepted() 的函数可以告诉您事件是被调用的最后一个处理程序接受还是拒绝。
  2. postEvent()
    postEvent() 将事件发布到队列中以供稍后分派。 下次 Qt 的主事件循环运行时,它会调度所有已发布的事件,并进行一些优化。 例如,如果有多个调整大小事件,它们将被压缩为一个。
    这同样适用于绘制事件:QWidget::update() 调用 postEvent(),它通过避免多次重绘来消除闪烁并提高速度。

7. 参考

  1. QT事件处理–notify()
  2. https://blog.csdn.net/qq_40729688/article/details/89500394
  3. 官方事件系统介绍文档

相关文章:

QT之事件系统

QT之事件系统1. 概述2. 事件的传递3. 事件类型4. 事件处理与事件过滤5. 自定义事件5.1 Demo6. 发送事件7. 参考1. 概述 在QT中&#xff0c;事件均派生自QEvent抽象类&#xff0c;事件可以由任何派生自QObject的子类实例接收和处理。它们与widget关联性极强。 2. 事件的传递 …...

Python中__init__.py文件深入理解

Python中文件__init__.py深入理解1. 简介1.1 模块&#xff08;Module&#xff09;和包&#xff08;Package&#xff09;的概念1.2 __init__.py文件简介2. __init__.py内容写法2.1 __init__.py文件内容2.2 __init__.py内容解释1. 简介 1.1 模块&#xff08;Module&#xff09;和…...

Jmeter之实现参数化的不同方式详解

参数化简介 定义&#xff1a;动态的获取、设置或生成数据&#xff0c;是一种由程序驱动代替人工驱动的数据设计方案&#xff0c;提高脚本的编写效率以及编写质量 适用场景&#xff1a;当提交的数据量较大时&#xff0c;每次修改太麻烦&#xff0c;可以使用参数化 本文介绍实现…...

Matlab论文插图绘制模板第76期—半对数刻度折线图(Semilogx和Semilogy)

在之前的文章中&#xff0c;分享了Matlab双对数刻度折线图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一下半对数刻度折线图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;Matlab论文插图绘制模板系列&#xff0c;旨在降低大家使用Matlab进行科研…...

【找工作】永善县政务服务管理局公开招聘5名公益性岗位人员

【找工作】永善县政务服务管理局公开招聘5名公益性岗位人员 为贯彻落实《中华人民共和国就业促进法》《就业服务和就业管理规定》&#xff0c;帮助有劳动能力和就业愿望的就业困难人员实现就业&#xff0c;永善县政务服务管理局拟向社会公开招聘公益性岗位人员5名&#xff0c;…...

【C++】从0到1入门C++编程学习笔记 - 提高编程篇:STL常用算法(拷贝和替换算法)

文章目录一、copy二、replace三、replace_if四、swap学习目标&#xff1a; 掌握常用的拷贝和替换算法 算法简介&#xff1a; copy // 容器内指定范围的元素拷贝到另一容器中replace // 将容器内指定范围的旧元素修改为新元素replace_if // 容器内指定范围满足条件的元素替换…...

C语言程序环境剖析——探究从.c到.exe之路

程序环境1.程序的翻译环境和执行环境2. 详解编译 链接2.1 翻译环境2.2 编译的三部分预编译编译汇编2.3链接3.运行环境1.程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;都存在两个不同的环境。 翻译环境&#xff0c;在这个环境中源代码被转换成可执行的机器指…...

【软件测试】8年资深测试总结出的测试学习经验,从入门到测试开发......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试圈子里有一句话…...

【博学谷学习记录】超强总结,用心分享|Spark的RDD算子分类

概念 RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做弹性分布式数据集&#xff0c;是Spark中最基本的数据抽象&#xff0c;代表一个不可变、可分区、里面的元素可并行计算的集合&#xff0c;它是一种抽象的数据模型&#xff0c;本身并不存储数据&#xff0c;仅…...

云原生系列之使用 prometheus监控远程主机实战

文章目录前言一. 实验环境二. 安装node_exporter2.1 node_exporter的介绍2.2 node_exporter的安装三. 在prometheus服务端配置监控远程主机3.1 在server端配置拉取node的信息3.2 重启prometheus3.3 通过浏览器查看prometheus总结前言 大家好&#xff0c;又见面了&#xff0c;我…...

2023年地方两会政府工作报告汇总(各省市23年重点工作)

新年伊始&#xff0c;全国各地两会密集召开&#xff0c;各省、市、自治区2023年政府工作报告相继出炉&#xff0c;各地经济增长预期目标均已明确。相较于2022年&#xff0c;多地经济增长目标放缓&#xff0c;经济不断向“高质量”发展优化转型。今年是二十大后的开局之年&#…...

第一章 企业管理概论

目录 一、企业及其形式 二、企业管理概述 三、企业管理理论与实践的产生与发展 四、网络时代的企业环境 五、网络时代企业管理的变革 一、企业及其形式 1、企业的概念 企业以市场为导向&#xff0c;以价值增值作为经济活动的目的&#xff1b; 企业是从事商品生产和流通的…...

独立图片服务器有什么突出之处

服务器是网络中非常重要的设施&#xff0c;承载着不同流量的访问&#xff0c;这就要求服务器具有快速的吞吐量、高稳定性和高可靠性。独立图片服务器作为独立服务器的衍生品&#xff0c;在数据利用方面的应用可以为企业在数据处理和分析方面带来一场革命。本文就将介绍独立图片…...

Linux驱动开发基础__mmap

目录 1 引入 2 内存映射现象与数据结构 3 ARM 架构内存映射简介 3.1 一级页表映射过程 3.2 二级页表映射过程 4 怎么给 APP 新建一块内存映射 4.1 mmap 调用过程 ​编辑4.2 cache 和 buffer 4.3 驱动程序要做的事 5 编程 5.1 app编程 5.2 hello_drv_test…...

若依框架---为什么把添加和更新分成两个接口

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 &#x1f4…...

图论算法:Floyd算法

文章目录Floyd算法例题&#xff1a;灾后重建Floyd算法 Floyd算法用于求图中任意两点之间的最短路径&#xff0c;该算法主要运用了动态规划的思想。 思考&#xff1a; 给你几个点与边&#xff0c;可以组成一张图&#xff0c;那么如何求得任意两点之间的最短路径呢&#xff1f;…...

回顾 | .NET MAUI 跨平台应用开发 - 用 .NET MAUI 开发一个无人机应用(下)

点击蓝字关注我们编辑&#xff1a;Alan Wang排版&#xff1a;Rani Sun微软 Reactor 为帮助广开发者&#xff0c;技术爱好者&#xff0c;更好的学习 .NET Core, C#, Python&#xff0c;数据科学&#xff0c;机器学习&#xff0c;AI&#xff0c;区块链, IoT 等技术&#xff0c;将…...

部署有多个仓库的svn服务

centos7自带svn服务&#xff0c;现需要创建多个仓库&#xff0c;并实现用户读写功能 创建svn版本库 mkdir /home/svn mkdir /home/svn/confmkdir /home/svn/yk1 mkdir /home/svn/yk2 svnadmin create /home/svn/yk1 svnadmin create /home/svn/yk2 进入版本库yk1的配置文件路…...

Mapper文件注入问题

Mapper文件注入问题UserMapper that could not be found.原因分析解决方案程序正常运行&#xff0c;但是注入类爆红问题原因分析解决方法UserMapper’ that could not be found. 原因分析 撰写了mapper文件&#xff0c;但是没有注入spring容器 解决方案 添加mybatis.mapper-…...

基于微信小程序的国产动漫论坛小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...