Qt 学习之路 2(23):自定义事件_qt学习之路(23): 自定义事件-程序员宅基地

技术标签: Qt 学习之路  Qt事件过滤器  QEvent  Qt自定义事件  Qt入门  Qt-学习之路  

尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的。例如,我要支持一种新的设备,这个设备提供一种崭新的交互方式,那么,这种事件如何处理呢?所以,允许创建自己的事件 类型也就势在必行。即便是不说那种非常极端的例子,在多线程的程序中,自定义事件也是尤其有用。当然,事件也并不是局限在多线程中,它可以用在单线程的程序中,作为一种对象间通讯的机制。那么,为什么我需要使用事件,而不是信号槽呢?主要原因是,事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的。事件的另外一个好处是,它可以使用过滤器。

Qt 自定义事件很简单,同其它类库的使用很相似,都是要继承一个类进行扩展。在 Qt 中,你需要继承的类是QEvent

继承QEvent类,最重要的是提供一个QEvent::Type类型的参数,作为自定义事件的类型值。回忆一下,这个 type 是我们在处理事件时用于识别事件类型的代号。比如在event()函数中,我们使用QEvent::type()获得这个事件类型,然后与我们定义的实际类型对比。

QEvent::TypeQEvent定义的一个枚举。因此,我们可以传递一个 int 值。但是需要注意的是,我们的自定义事件类型不能和已经存在的 type 值重复,否则会有不可预料的错误发生。因为系统会将你新增加的事件当做系统事件进行派发和调用。在 Qt 中,系统保留 0 – 999 的值,也就是说,你的事件 type 要大于 999。这种数值当然非常难记,所以 Qt 定义了两个边界值:QEvent::UserQEvent::MaxUser。我们的自定义事件的 type 应该在这两个值的范围之间。其中,QEvent::User的值是 1000,QEvent::MaxUser的值是 65535。从这里知道,我们最多可以定义 64536 个事件。通过这两个枚举值,我们可以保证我们自己的事件类型不会覆盖系统定义的事件类型。但是,这样并不能保证自定义事件相互之间不会被覆盖。为了解决这个问题,Qt 提供了一个函数:registerEventType(),用于自定义事件的注册。该函数签名如下:

这个函数是 static 的,因此可以使用QEvent类直接调用。函数接受一个 int 值,其默认值是 -1;函数返回值是向系统注册的新的 Type 类型的值。如果 hint 是合法的,也就是说这个 hint 不会发生任何覆盖(系统的以及其它自定义事件的),则会直接返回这个值;否则,系统会自动分配一个合法值并返回。因此,使用这个函数即可完成 type 值的指定。这个函数是线程安全的,不必另外添加同步。

我们可以在QEvent子类中添加自己的事件所需要的数据,然后进行事件的发送。Qt 中提供了两种事件发送方式:


  1. 直接将event事件发送给receiver接受者,使用的是QCoreApplication::notify()函数。函数返回值就是事件处理函数的返回值。在事件被发送的时候,event对象并不会被销毁。通常我们会在栈上创建event对象,例如:

  2. event事件及其接受者receiver一同追加到事件队列中,函数立即返回。

    因为 post 事件队列会持有事件对象,并且在其 post 的时候将其 delete 掉,因此,我们必须在堆上创建event对象。当对象被发送之后,再试图访问event对象就会出现问题(因为 post 之后,event对象就会被 delete)。

    当控制权返回到主线程循环时,保存在事件队列中的所有事件都通过notify()函数发送出去。

    事件会根据 post 的顺序进行处理。如果你想要改变事件的处理顺序,可以考虑为其指定一个优先级。默认的优先级是Qt::NormalEventPriority

    这个函数是线程安全的。

    Qt 还提供了一个函数:

    这个函数的作用是,将事件队列中的接受者为receiver,事件类似为 event_type 的所有事件立即发送给 receiver 进行处理。需要注意的是,来自窗口系统的事件并不由这个函数进行处理,而是processEvent()。详细信息请参考 Qt API 手册。

现在,我们已经能够自定义事件对象,已经能够将事件发送出去,还剩下最后一步:处理自定义事件。处理自定义事件,同前面我们讲解的那些处理方法没有什么区别。我们可以重写QObject::customEvent()函数,该函数接收一个QEvent对象作为参数:

我们可以通过转换 event 对象类型来判断不同的事件:

当然,我们也可以在event()函数中直接处理:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lmhuanying1012/article/details/78081625

智能推荐

(2,1,2)卷积码BCJR译码matlab仿真_matlab bcjr-程序员宅基地

文章浏览阅读3.6k次,点赞6次,收藏45次。仿真(2,1,2)卷积码的性能,BCJR译码,级联的调制方式采用QPSK。每个码块信息比特长度为1000,要求编码最终状态归0。要求输出的结果为译码后信息比特的BER。_matlab bcjr

python 读取鼠标选中文本_送书 | 选择文本的神技-程序员宅基地

文章浏览阅读1.5k次。“欢迎关注【雷哥office】,为了回馈粉丝,最近几个月每周都会有送书活动,想要书的朋友不要错过哦~本周第二弹福利, 详情见文末”1使用鼠标⑴选中区域。将鼠标光标放在要选择的文本的开始位置,按住鼠标左键并拖曳,这时选中的文本会以阴影的形式显示,选择完成后,释放鼠标左键,鼠标光标经过的文字就被选定了。⑵选中词语。将鼠标光标移动到某个词语或单词中间,双击鼠标左键即可选中该词语或单词。⑶..._python获取鼠标选取的内容

Bootloader工作流程、MCU启动流程-程序员宅基地

文章浏览阅读1.6k次。https://www.csdn.net/tags/MtTaMg3sNjI1MTk4LWJsb2cO0O0O.html【2.0】bootloader工作流程、MCU启动流程_夜色稠的博客-程序员宅基地_mcu启动流程stm32程序跑飞_详解 | MCU上电到启动应用程序前的工作流程_weixin_39946657的博客-程序员宅基地STM32F0单片机快速入门三 MCU启动过程_TopSemic嵌入式的博客-程序员宅基地M3的MCU的启动过程_jacklondonjia的博客-CSD..._mcu启动流程

Linux Centos系统安装LibreOffice_centos 安装 libreoffice-程序员宅基地

文章浏览阅读1.3k次,点赞8次,收藏12次。官网安装指南:官网首页帮助与支持——>安装指南——>选择你自己系统的点击进入。译文:不凭空臆测,不武断绝对,不固执拘泥,不自以为是。2、centos系统:作者使用7+版本。下载好的安装包,选择系统匹配的安装包。centos系统根目录opt文件夹下。原文:勿意、勿必、勿固、勿我。_centos 安装 libreoffice

#list 标签获取下标_<#list>-程序员宅基地

文章浏览阅读5.3k次。<#list>标签<#list>能是CMS里面的标签。<#list>获取下标,怎么获取下标 ${c_index}获取下标 例子: [#list tag_list as c] ======> ${c_index} [#list tag_list as a] ======> ${a_index}代码例子:<div class="tabs fn-clear"> [@cms_conten_<#list>

Python可视化matplotlib&seborn14-普通热力图heatmap_python matplotlib 热力图浅色-程序员宅基地

文章浏览阅读2.1k次,点赞2次,收藏21次。详细介绍python seaborn绘制热图。_python matplotlib 热力图浅色

随便推点

Stata 数据分析_stata主成分分析结果解读-程序员宅基地

文章浏览阅读7.5k次,点赞2次,收藏13次。最近在学习STATA做分析的时候,发现这个软件很多功能很强大,但是背后的统计学知识要求也比较高,作为一边深入学习统计知识一遍用软件的小白,好多东西只是知其然不知其所以然,因此尝试自己把STATA的一些运算分解出来。因此这里记录一下学习内容。在做STATA的主成分分析和因子分析的时候,觉得这两个东西很像,但是其中的原理好像也不太清楚,网上查了一些文章,花了不少时间才明白怎么做的,这里演示一下具体_stata主成分分析结果解读

javaee学习笔记1_javaee的学习摘要-程序员宅基地

文章浏览阅读338次。为什么需要JavaEE我们编写的JSP代码中,由于大量的显示代码和业务逻辑混淆在一起,彼此嵌套,不利于程序的维护和扩展。当业务需求发生变化的时候,对于程序员和美工都是一个很重的负担。为了程序的易维护性和可扩展性,这就需要我们使用JavaEE技术来进行项目开发2、 什么是JavaEEJavaEE是一个开发分布式企业级应用的规范和标准。Java语言的平台有3个版本:适用于小型设备和智能卡的JavaME(Java Platform Micro Edition,Java微型版)、适用于桌面系统的Java_javaee的学习摘要

DM大规模并行处理MPP_dm mpp-程序员宅基地

文章浏览阅读316次。DM大规模并行处理MPP_dm mpp

FreeScale-SD-5舵机中值-程序员宅基地

文章浏览阅读9.6k次,点赞14次,收藏81次。SD-5舵机 舵机中值求取_舵机中值

【VSCode】在Linux下使用VSCode编译调试C/C++环境配置(使用g++作为编译器)_vscode远程登陆linux中运行调试attach to chrome怎么改成build g++-程序员宅基地

文章浏览阅读4k次,点赞5次,收藏29次。【VSCode】在Linux下使用VSCode编译调试C/C++环境配置(使用g++作为编译器)一、安装必要插件二、编译运行程序三、调试环境配置四、调试参考链接1: https://blog.csdn.net/ii0789789789/article/details/95026208.参考链接2: https://blog.csdn.net/qq_37968132/article/detai..._vscode远程登陆linux中运行调试attach to chrome怎么改成build g++

树莓派养成之路 ——esp-01智能开关2(硬件篇)_esp-01原理图-程序员宅基地

文章浏览阅读4.1k次,点赞3次,收藏14次。树莓派养成之路 ——esp-01智能开关2(硬件篇)很久没更新了,继续esp智能开关。本文讲述esp-01智能开关的硬件和原理图(PS:本人不是电子专业,只是开了头不得不去搞,如有误请多包含)硬件材料 设备 价格 esp8266-01 11元 220V转3.3v模块 5元 5V继电器(低电平触发) 8元 洞洞板 1元..._esp-01原理图

推荐文章

热门文章

相关标签