Qt Event Dispatcher学习

本文深入探讨Qt事件系统的三种类型:自发事件、发布事件和发送事件。解析不同事件类型的触发方式及处理流程,并介绍Qt如何整合底层事件。

距离上次整理Qt事件系统已经过了14个月了。重新理理思绪:

Qt中的事件大致可分为3类:

Spontaneous events

从系统得到的消息:鼠标按键、键盘按键、定时器事件等。转化为QEvent后被Qt事件系统依次处理

Posted events

由Qt或应用程序直接生成,放入Qt消息队列
QCoreApplication::postEvent()

Sent events

由Qt或应用程序产生,不放入队列直接被派发和处理
QCoreApplication::sendEvent()

本文中,先简单看一下后两种,然后重点看看第一种。

Sent events

比如,发送按键"X"的事件到 mainWin 窗口。

QKeyEvent event(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X", 0
);
QApplication::sendEvent(mainWin, &event);

如果没有过滤器的话,这其实就是直接调用 mainWin 的 keyPressEvent()函数。

(图片来源:http://www.slideshare.net/mariusbu/qt-widgets-in-depth,下同)


这个东西不涉及事件队列、事件循环等等东西。但是事件过滤在这个过程中正常起作用。而且除过滤器外,下面三个函数在派生类中都可以被覆盖(以处理这个事件):

  • QApplication::notify()
  • QWidget::event()
  • QWidget::keyPressEvent()

Posted events

比如,同样是发送按键"X"的事件到 mainWin 窗口,我们可以使用postEvent()。

QApplication::postEvent(mainWin, new QKeyEvent(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X", 0
));

这会将该事件放入Qt自己的事件队列中,事件循环QEventLoop空闲时会判断该队列是否为空。最终使用 sendEvent() 依次派发事件队列中的这些事件。


也可以手动使用

  • QCoreApplication::sendPostedEvents()

清空当前线程事件队列(即派发队列中的事件)

注意:每一个线程有一个事件队列。

Spontaneous events

系统底层事件是通过 QAbstractEventDispatcher 整合进Qt的事件循环的。

Event dispatcher接受窗口系统以及其他源中的事件。它对事件的传递提供了一种精细控制的能力。

QAbstractEventDispatcher

  • QEventDispatcherUNIX
    • QEventDispatcherX11
    • QEventDispatcherQWS
    • QEventDispatcherQPA
  • QEventDispatcherGlib
    • QGuiEventDispatcherGlib
    • QWSEventDispatcherGlib
  • QEventDispatcherWin32
    • QGuiEventDispatcherWin32
  • QEventDispatcherMac
  • ...

这堆东西还挺多,不过下面三个属于QtCore模块

QEventDispatcherGlib

使用glib事件循环,有助于和Gtk的集成

QEventDispatcherUNIX

默认的glib不可用时,就用这个喽

QEventDispatcherWin32

Qt 创建一个带回调函数的隐藏窗口来处理事件。

我们能看的到的就是,它们提供

  • Timer
  • SockerNotifer

的注册、反注册功能。并将系统底层对应事件转换成Qt事件。


其他的属于QtGui模块。就是和窗口系统(重绘、移动等等事件)以及键鼠事件有关了。

参考


<think>嗯,用户现在想在Qt程序中调用与event相关的环境变量,需要示例或方法。首先,我得确定Qt中是否有专门用于事件处理的环境变量。根据之前的知识,Qt的环境变量通常涉及调试、插件路径或图形渲染等,比如QT_DEBUG_PLUGINS或者QT_QPA_PLATFORM。但事件相关的环境变量可能不是直接存在的,可能需要通过其他方式实现。用户可能误解了环境变量在事件处理中的作用。或许他们想通过环境变量来动态调整事件处理的行为,比如启用事件日志或调整事件队列的大小。这时候可能需要检查Qt的文档,看看是否有相关的环境变量支持。例如,查找是否有类似QT_EVENT_LOOP_TIMEOUT或者QT_EVENT_DEBUG这样的变量。如果没有现成的环境变量,可能需要通过编程方式来读取自定义的环境变量,并在事件处理中使用。比如,用户设置一个环境变量QT_EVENT_LOG,然后在代码中用qgetenv读取,并根据其值来开启日志功能。同时,还要注意环境变量的设置方法,比如在启动程序前通过命令行设置,或者在代码中临时设置。另外,用户可能需要示例代码,展示如何在Qt中获取和使用环境变量。例如,在main函数中读取环境变量,并传递给事件过滤器或事件处理函数。还要注意跨平台的问题,比如在Windows和Linux下设置环境变量的不同方式。还要考虑Qt的事件机制,比如事件循环、事件过滤器和自定义事件。如果用户想通过环境变量来影响事件处理流程,可能需要结合这些机制。例如,根据环境变量的值安装不同的事件过滤器,或者调整事件派发的策略。最后,提醒用户环境变量的配置注意事项,比如作用域和持久性,以及不同Qt版本之间的差异。确保用户理解如何正确设置和使用这些变量,避免因为配置错误导致程序无法正常运行。</think>在Qt中调用与事件(event)相关的环境变量,通常涉及以下方法: ### 一、Qt事件相关的常用环境变量 1. **`QT_LOGGING_RULES`** 用于控制事件调试日志输出,例如: ```bash export QT_LOGGING_RULES="qt.event*.debug=true" ``` 在代码中通过`qputenv`设置: ```cpp qputenv("QT_LOGGING_RULES", "qt.event*.debug=true"); ``` 2. **`QT_EVENT_DISPATCHER_CORE_FALLBACK`** 强制Qt使用核心事件分发器: ```cpp qputenv("QT_EVENT_DISPATCHER_CORE_FALLBACK", "1"); ``` ### 二、自定义环境变量与事件联动示例 ```cpp #include <QApplication> #include <QDebug> #include <QKeyEvent> class MyWidget : public QWidget { protected: bool eventFilter(QObject* obj, QEvent* event) override { if (event->type() == QEvent::KeyPress) { // 读取环境变量控制行为 if (qEnvironmentVariableIntValue("ENABLE_EVENT_LOG")) { qDebug() << "KeyPress event captured"; } } return QWidget::eventFilter(obj, event); } }; int main(int argc, char* argv[]) { QApplication app(argc, argv); // 设置自定义事件环境变量 qputenv("ENABLE_EVENT_LOG", "1"); // 启用日志 MyWidget widget; widget.installEventFilter(&widget); widget.show(); return app.exec(); } ``` ### 三、环境变量配置注意事项 1. **作用域** 环境变量需在**程序启动前**设置,或在代码中通过`qputenv`动态修改[^1]。 2. **跨平台差异** Windows下使用`set`命令,Linux/macOS用`export`: ```bash # Linux/macOS export ENABLE_EVENT_LOG=1 # Windows set ENABLE_EVENT_LOG=1 ``` 3. **调试工具** 结合`QLoggingCategory`实现更精细的事件日志控制: ```cpp QLoggingCategory::setFilterRules("qt.event*.debug=true"); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值