【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事件系统 的相关文章

  • 通过对 XmlHttpRequest (REST) 的响应在 QML 中显示图像

    我需要从 REST API 调用中获取 jpeg 图像 我使用 XMLHttpRequest 因为请求需要身份验证标头 即我不能只创建一个图像并将源设置为带有 user passwd url 的 URL 我认为我可以通过将 REST 数据设
  • QT 中的应用程序->处理消息?

    在 Borland 6 中 我经常使用它来解除程序操作的卡住 Application gt Processmessages 现在 对于 QT 4 8 1 我在这个外国 对我来说 QT 文档中找不到 谁能帮我 在 Qt 中 您可以使用静态函数
  • 如何获取 QIcon 的文件/资源​​路径

    假设我做了这样的事情 QIcon myIcon resources icon ico 我稍后如何确定该图标的路径 例如 QString path myIcon getPath 问题是 没有getPath 会员 我找不到类似的东西 但肯定有办
  • qt项目如何设置安装路径

    我正在寻找与 qmake configure prefix 等效的内容 基本上 我想覆盖默认的安装 部署目录 这是如何用命令行 qmake 指定的 我还使用 QtCreator 构建了很多 gui 项目 并且我想知道如何在 QtCreato
  • QTableView 中的虚拟列?

    我开始学习 Qt4 模型 视图编程 我有初学者问题 我有一个简单的应用程序 其中显示 sqlite 表QTableView class Model QtSql QSqlTableModel def init self parent None
  • 为什么下面的重叠比较总是评估为 true

    我不明白为什么以下代码有警告 指出重叠比较始终评估为真 接下来的语句永远不会被执行 QVariant MainModel data const QModelIndex index int role const if index isVali
  • 如何在 Qt-Embedded 中(正确)输出多语言文本?

    我的目标系统是 linux 3 3 7 Qt Embedded 开源版 4 8 Droid 字体 取自 fonts droid 20111207 git 1 all deb Debian 软件包并复制到 usr lib fonts目录 主要
  • QSpinBox 输入 NaN 作为有效值

    我正在尝试扩展 QSpinBox 以能够输入 NaN 或 nan 作为有效值 根据文档 我应该使用 textFromValue valueFromText 和 validate 函数来完成此操作 但我无法让它工作 因为它仍然不允许我输入除数
  • 如何在按下托盘图标菜单操作时执行功能?

    int main int argc char argv QApplication oApp argc argv QAction action1 QMenu menu QSystemTrayIcon TrayIcon QIcon favico
  • Qt mouseReleaseEvent() 未触发?

    我有一个显示图片的库 我们称之为 PictureGLWidget 其中 class PictureGLWidget public QGLWidget 所以 PictureGLWidget 扩展了 QGLWidget 在PictureGlWi
  • Qt:将拖放委托给子级的最佳方式

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • Qt 创建者 + MITK (Linux)

    我正在尝试使用MITK 与 Qt Creator 我已经通过 ccmake 成功编译并使用了 VTK 和 ITK 我已经编译了 MITK超级建造模式 它下载 CTK VTK ITK 等 然后我就配置好了 我已经用 make 编译了 大约两个
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • 如何使用 Qtimer 添加 1 秒延迟

    我目前有一个方法如下 void SomeMethod int a Delay for one sec timer gt start 1000 After one sec SomeOtherFunction a 这个方法实际上是一个附加到信号
  • 重定向 python 交互式帮助()

    我正在为使用 Qt 的应用程序开发交互式 python shell 但是我似乎无法获得重定向的交互式帮助 我的 python 代码中有这个 class OutputCatcher def init self self data def wr
  • QToolButton:更改菜单位置

    使用菜单时QToolButton菜单显示在按钮的正下方 有没有办法在按钮的左侧 右侧显示菜单 我知道这个问题不久前已得到回答 但我想为此问题添加新答案 因为接受的答案不再有效 实际上 更改 QToolButton 上的菜单位置非常容易 您需
  • QCombobox 向下箭头图像

    如何更改Qcombobox向下箭头图像 现在我正在使用这个 QSS 代码 但这不起作用 我无法删除向下箭头边框 QComboBox border 0px QComboBox down arrow border 0px background
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • QTimer 一点也不准确?

    运行在 Windows7 64 位机器上 具有非常强大的 CPU 8 核 16 线程 我使用 QTimer 以 50Hz 触发函数调用 但我最终得到了 30Hz 函数调用本身肯定需要不到 10 毫秒才能完成 整个过程发生在一个单独的线程中

随机推荐

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

    转自 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