【Qt】Qt事件系统

2023-11-18

00. 目录

在这里插入图片描述

01. Qt事件系统概述

Qt 5.12

​ Qt Core

​ The Event System

在Qt中,事件是对象,派生自抽象 QEvent 类,表示应用程序内部发生的情况或应用程序需要了解的外部活动的结果。事件可以由任何 QObject 子类接收和处理,但它们与widgets控件特别相关。本文档介绍事件如何在典型应用程序中传递和处理。

02. 事件如何传递

当事件发生时,Qt创建一个事件对象来表示它,方法是构造一个适当的实例 QEvent 子类,并将其传递给 QObject (或其子类之一)通

过调用其 event() 函数。

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

一些事件,例如 QMouseEventQKeyEvent,来自窗口系统;有些,如 QTimerEvent,来自其他来源;有些来自应用程序本身。

03. 事件类型

大多数事件类型都有特殊类,特别是 QResizeEventQPaintEventQMouseEventQKeyEventQCloseEvent.每个 QEvent 子类并

添加特定事件的函数。例如 QResizeEvent 增加 size()oldSize() 以使widgets控件能够发现其尺寸是如何更改的。

某些类支持多个实际事件类型。 QMouseEvent 支持鼠标按钮按下、双击、移动和其它相关操作。

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

子类。

由于程序需要以各种复杂的方式做出反应,Qt的事件传递机制非常灵活。 QCoreApplication::notify()相关文档简明扼要地讲述整个过

程; Qt季刊 文章 Another Look at Events 简洁地重述它。在这里,我们将为95%的应用程序进行足够的解释。

04. 事件处理

传递事件的正常方法是调用虚函数。例如 QPaintEvent 被传递传递通过调用 QWidget::paintEvent()方法。这个虚函数负责做出适当的

反应,通常是通过重新绘制widget控件。如果在虚拟函数的实现中没有执行所有必要的工作,则可能需要调用基类的实现。

例如,以下代码处理在自定义复选框小部件上单击鼠标左键事件,同时将所有按钮其它单击事件传递到基 QCheckBox 类:

 void MyCheckBox::mousePressEvent(QMouseEvent *event)
 {
     if (event->button() == Qt::LeftButton) {
         // handle left mouse button here
     } else {
         // pass on other buttons to base class
         QCheckBox::mousePressEvent(event);
     }
 }

如果要替换基类的功能,则必须自己实现所有内容。但是,如果您只想扩展基类的功能,那么您可以实现您想要的内容,并调用基类来获

取您不想处理的任何情况的默认行为。

有时,没有这样的特定事件的函数,或者特定事件的函数是不够的。最常见的示例涉及 Tab 键按下。通常 QWidget 截获这些以移动键盘

焦点,但有一些控件需要 Tab 键。

这些对象可以重新实现 QObject::event(),常规事件处理程序,并且可以在常规处理之前或之后执行其事件处理,或者它们可以完全重

写函数。一个既解释Tab又具有特定于应用程序的自定义事件的非常不寻常的小部件可能包含以下event()函数

 bool MyWidget::event(QEvent *event)
 {
     if (event->type() == QEvent::KeyPress) {
         QKeyEvent *ke = static_cast<QKeyEvent *>(event);
         if (ke->key() == Qt::Key_Tab) {
             // special tab handling here
             return true;
         }
     } else if (event->type() == MyCustomEventType) {
         MyCustomEvent *myEvent = static_cast<MyCustomEvent *>(event);
         // custom event handling here
         return true;
     }

     return QWidget::event(event);
 }

注意,对于所有未处理的情况,仍然调用QWidget::event(),并且返回值指示是否处理了事件;true值防止将事件发送给其他对象。

05. 事件过滤器

有时,对象需要查看(可能还需要拦截)传递给另一个对象的事件。例如,对话框通常需要过滤某些Widget控件的按键; 例如,修改返回键

事件处理。

QObject::installEventFilter()函数通过设置一个事件过滤器来实现这一点,使指定的过滤器对象在其QObject::eventFilter()函数中接收目

标对象的事件。事件过滤器在目标对象处理事件之前处理事件,允许它根据需要检查和丢弃事件。现有的事件过滤器可以使用

QObject::removeEventFilter()函数删除。

当过滤器对象的eventFilter()被调用时,它可以接受或拒绝事件,并允许或拒绝事件的进一步处理。如果所有事件过滤器都允许对事件进

行进一步处理(每个过滤器通常返回false),则将事件发送到目标对象本身。如果其中一个停止处理(通过返回true),则目标和任何后续事

件过滤器根本无法看到该事件。

 bool FilterObject::eventFilter(QObject *object, QEvent *event)
 {
     if (object == target && event->type() == QEvent::KeyPress) {
         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
         if (keyEvent->key() == Qt::Key_Tab) {
             // Special tab handling
             return true;
         } else
             return false;
     }
     return false;
 }

上面的代码显示了拦截发送到特定目标widget控件的Tab键按下事件的另一种方法。在这种情况下,过滤器处理相关事件并返回true以阻

止它们被进一步处理。所有其他事件都被忽略,过滤器返回false以允许它们通过安装在目标控件上的任何其他事件过滤器发送到目标控

件。

通过在QApplication或QCoreApplication对象上安装事件过滤器,也可以过滤整个应用程序的所有事件。在特定于对象的过滤器之前调用此类全局事件过滤器。这是非常强大的,但它也减慢了整个应用程序中每个事件的事件传递;通常应该讨论使用其他技术。

06. 事件发送

许多应用程序都希望创建和发送它们自己的事件。通过构造合适的事件对象并使用QCoreApplication::sendEvent()和

QCoreApplication::postEvent()发送事件,您可以以与Qt自己的事件循环完全相同的方式发送事件。

sendEvent()立即处理事件。当它返回时,事件过滤器和/或对象本身已经处理了事件。对于许多事件类,都有一个名为isAccepted()的函

数,它告诉您事件是被最后调用的处理程序接受还是拒绝。

postEvent()将事件发送到队列中以供以后调度。下次Qt的主事件循环运行时,它会调度所有发布的事件,并进行一些优化。例如,如果

有多个调整大小事件,它们将被压缩为一个事件。这同样适用于绘制事件:QWidget::update()调用postEvent(),这消除了闪烁并通过避免

多次重绘提高了速度。

postEvent()也在对象初始化期间使用,因为提交的事件通常会在对象初始化完成后很快被分派。在实现widget控件时,重要的是要认识到,事件可以在其生命周期的早期传递,因此,在其构造函数中,一定要在早期初始化成员变量,以免它有可能接收到事件。

要创建自定义类型的事件,您需要定义一个事件号,该事件号必须大于QEvent::User,并且您可能需要创建QEvent的子类,以便传递关

于自定义事件的特定信息。有关详细信息,请参阅QEvent文档。

附录

关键词: The Event System

参考:The Event System

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Qt】Qt事件系统 的相关文章

  • 如何通过 Qt 创建网络服务 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在 QT 安装程序框架中区分每用户安装与系统范围安装?

    我正在使用一些名为 pgModeler 的应用程序 它的当前版本提供了一个基于 QT 安装程序框架的安装程序 Windows 上该安装程序的问题是它安装每个用户的开始菜单条目 https github com pgmodeler pgmod
  • QPainter 性能高帧率

    我试图在 QPainter 中以 60fps 的速度显示视频 在 OpenGLwidget 中 我遇到一个问题 有时绘图花费的时间太长 并且在使用 QPainter 时发生下一个重绘事件 这会生成警告和随机崩溃 有几个问题 是否有一种 Qt
  • 如何从浮点数组创建新的 QImage

    我有一个代表图像的浮点数数组 列在前 我想在 QGraphicsSecene 上将图像显示为 QPixmap 为了做到这一点 我尝试使用 QImage 构造函数 QImage const uchar data int width int h
  • PyQt - 如何从给定的小部件获取顶级父级?

    给定的小部件如何访问它最旧的父级 即顶级小部件 我需要 showMinimized it 现在我正在使用 self parent parent parent showMinimized 但这似乎不是最好的方法 如果它移动了 我需要手动更改父
  • 在哪里可以找到 QT 5.3.0 命令提示符

    用于学习Qt的书 C gui programming with qt 4 2nd 版 我需要Qt的命令提示符 我已经安装了Qt 5 3 0 creator 5 3 0开源 但不知道它的命令提示符在哪里 有人可以帮助我吗 我认为您正在寻找的是
  • 仅在发布模式下使用 glGenBuffer 时出现未处理的异常 - QT

    我在 Windows 7 上使用 Qt 4 8 发布模式编译项目时遇到了一些问题 调试时一切正常 但在发布时我收到未处理的异常 0xC0000005 访问冲突 我将范围缩小到发生这种情况的行 即生成像素缓冲区的时间 我的第一个猜测是 DLL
  • Qt 人工鼠标点击无法正常工作

    小玩具应用程序可以在这里找到 http gist github com 517445 http gist github com 517445 我正在尝试将人工鼠标事件发送到小部件 我使用QApplication sendEvent为此 接下
  • 如何使用 Qt DOM 通过此语法获取 xml 属性

    我正在使用 Qt DOM XML 解析器 并且遇到了如下属性定义的问题
  • 用 C++/Qt 编写的程序中的 RTF / doc / docx 文本提取

    我正在写一些程序Qt https en wikipedia org wiki Qt 28software 29 C 我需要从中读取文本微软Word https en wikipedia org wiki Microsoft Word RTF
  • QStyledItemDelegate 绘制自定义小部件失败

    在我的一个项目中 我使用的是QTableWidget为了显示一些复杂的计算结果 为了提高表格的可读性 我需要在单个表格单元格内显示两个对齐的值 后来我想通过使用颜色或箭头等来进一步自定义小部件 为此我源自QStyledItemDelegat
  • 清除pyqt中布局中的所有小部件

    有没有办法清除 删除 布局中的所有小部件 self plot layout QtGui QGridLayout self plot layout setGeometry QtCore QRect 200 200 200 200 self r
  • 如何声明一个带有成员函数指针的函数

    我有一个类 其中的成员变量指向库对象 class myClassA private libraryClass libraryObject 该库类发出事件 以字符串为特征 并提供一种机制 允许客户端类指定在发出事件时应调用的成员函数 因此在m
  • 如何去除QWizard中的水平线?

    我正在研究一个样式表QWizard我想删除按钮上方的水平线 我尝试递归浏览所有小部件并将其边框设置为无 但似乎没有任何小部件具有此边框 这是我的代码 可以找到完整的可构建示例here https gist github com ardeid
  • 如何在针对 Windows XP 的情况下使用 VS2012 构建 Qt 4/5?

    我正在尝试使用 Visual Studio 2012 构建 Qt 4 8 5 Qt 5 2 1 针对 Windows XP SDK v7 1a 使用 VS2102 编译时 源代码与 SDK v7 1a 存在各种不兼容性 因此无法开箱即用 这
  • 在 Qt 中使用多个不同的流读取同一文件

    使用 Qt 是否可以使用多个流读取文件以同时访问其中的不同数据部分 请注意 Qt 中的流 QTextStream QDataStream 不处理底层设备中的位置 流类只是一个包装器 用于更轻松地解析设备 QFile 实例 内的二进制数据 因
  • QTableView 并双击一个单元格

    我正在开发测试用例编辑器 该编辑器包含 USART 传输和接收数据包格式 编辑器是一个表格视图 发送和接收数据包的长度为八个字节 例如 0x01 0x02 0x03 0x08 它在我的第五和第六栏中 现在 我希望此列中的单元格为只读 但是当
  • Qt:不完整类型和前向声明的使用无效

    我有一些误解 A h ifndef A H define A H include B h class A public B Q OBJECT public A endif A cpp include A h A A B ui gt blan
  • 无法运行 Qt 应用程序:找不到版本“Qt_5”

    我运行 Ubuntu 16 04 LTS 我的问题是我无法运行可以编译的 Qt5 应用程序 这是我尝试运行它时得到的结果 home user Desktop sconfig dist Release GNU Linux SCongif us
  • Qt(在 Windows 上)将权限级别设置为“requireAdministrator”

    我正在使用 Qt Creator 并努力制作 exe文件默认以管理员身份运行 在线阅读所有解决方案我试图将这一行放入我的 pro file QMAKE LFLAGS MANIFESTUAC level requireAdministrato

随机推荐

  • 江波龙深化存储技术优势 紧密结合物联网应用需求创新

    转自 http www chinaflashmarket com Producer Netcom News 142127 云计算 大数据以及移动互联网时代下 全球存储容量以爆发式的速度在增长 根据市场调研机构预测 2020年全球存储容量将从
  • servlet编程会话管理技术

    1 会话管理 浏览器与服务器之间会话过程中产生的会话数据 Cookie特点 1 会话数据放在浏览器端 2 数据类型只能string 而且有大小限制的 3 相对数据存放不安全 Session特点 1 会话数据放在服务器端 服务
  • MES的数据采集方式

    为实现生产车间现场数据的采集 制造业MES系统数据采集方法有手工录入方式和自动化提取采集两大类 主要有以下几类 一 手动方式 1 手工方式 操作员或编程员在MES系统控制面板上 输入特定的触发程序 经DNC服务器的自动翻译 就可得到机床端的
  • Jenkins集成Sonar与Gitlab代码质量检测

    前提默认 安装docker19 与docker compose 安装Jenkins 1 docker compose yaml配置 version 3 services jenkins network mode host 镜像 image
  • 3、Java的If语句与For循环

    一 语句 条件语句 根据不同的条件 执行不同的语句 if if else if else if if else if else if else switch 循环语句 重复执行某些动作 for while do while 1 1 if语句
  • 深度学习算法面试常问问题(三)

    pooling层是如何进行反向传播的 average pooling 在前向传播中 就是把一个patch的值取平均传递给下一层的一个像素 因此 在反向传播中 就是把某个像素的值平均分成n份 分配给上一层 max pooling 在前向传播中
  • 用Odoo创建一个网站

    原贴地址 https www odoo com documentation 10 0 howtos website html 声明 这篇指导假设你有python的知识并安装了Odoo 请注意文件的目录结构 本文的目录结构与原文不同 创建一个
  • 快速打开CMD的几个方法

    1 在开始菜单里面找CMD EXE 很快的哟 2 在资源管理器的地址栏直接键入CMD按回车也能启动CMD 3 资源管理器 按住Shift点右键也能召唤CMD哦 选 在此处打开命令窗口 就行了
  • squirrel-foundation状态机的使用细节

    上一篇文章介绍了stateless4j spring statemachine以及squirrel foundation三款状态机引擎的实现原理 以及我为何选择squirrel foundation作为解决方案 本文主要介绍一下项目中如何使
  • sqlloader出现SQL*Loader-704和ORA-12154的错误

    1 错误描述 生成的sqlloder各个文件完好 权限也具备 但是就是导入oracle数据库的时候报错 错误为 SQL Loader 704 Internal error ulconnect OCIServerAttach 0 ORA 12
  • vue3+ts实现todolist功能

    先看一下实现效果 可以看到内部实现的内容有enter输入 单项删除 全选 以及删除选中项等功能 具体在实现前需要常见有ts的vue3项目 项目创建 具体项目创建 就是 vue create 项目名称 在创建后 选择的时候有vue2和vue3
  • CUDA10.0官方文档的翻译与学习之介绍

    背景 从这次开始 我将用数篇博客来分享前一阵我对CUDA10 0官方文档之编程指南的翻译与学习的笔记 由于内容非常多 我将每一章单独分享出来 可能有地方翻译得词不达意 所以建议大家参考原文 https docs nvidia com cud
  • 多线程实现事务回滚

    多线程实现事务回滚 特别说明CountDownLatch CountDownLatch的用法 CountDownLatch num 简单说明 主线程 mainThreadLatch await 和mainThreadLatch countD
  • 剑指 offer第62题-圆圈中最后剩下的数

    让小朋友们围成一个大圈 然后 随机指定一个数 m 让编号为 0 的小朋友开始报数 每次喊到 m 1 的那个小朋友要出列唱首歌 然后可以在礼品箱中任意的挑选礼物 并且不再回到圈中 从他的下一个小朋友开始 继续 0 m 1 报数 这样下去 直到
  • Proc批量处理需要注意的问题

    ProC中批量读取游标中的数据的时候 需要注意 最后一次批量读取游标中的数据的时候 数据被取到HostArray中 同时sqlca sqlcode被置为1403 NO DATA FOUND 如果在fetch后立即判断sqlca sqlcod
  • 隐藏selenium的特征

    1 chromedriver exe中的 cdc asdjflasutopfhvcZLmcfl 特征 cdc 是chromedriver exe的一个特征之一 很多网站会通过检测是否有这个特征来判断是否是selenium 解决方案 wind
  • centos7安装mate

    http www 45drives com wiki index php Installing MATE on CentOS 7 Note This guide assumes you have a CentOS 7 minimal ins
  • Python基础知识之5

    Python基础知识之5 文件操作 1 文件的打开与关闭 文件打开 在python 使用open函数 可以打开一个已经存在的文件 或者创建一个新文件 基本格式 open 文件名 访问模式 实例如下 f open test txt w 文件关
  • 关于soot静态分析的学习(一)

    本文中关于soot的研究使用 仅代表本人理解程度 因本人为0基础 所以如有出错 欢迎指出 一 soot是什么 Soot Java静态分析框架 其实Soot最开始设计的时候 主要目的就是为了对Java字节码程序进行优化 这里的优化就是指执行效
  • 【Qt】Qt事件系统

    00 目录 文章目录 00 目录 01 Qt事件系统概述 02 事件如何传递 03 事件类型 04 事件处理 05 事件过滤器 06 事件发送 附录 01 Qt事件系统概述 Qt 5 12 Qt Core The Event System