Qt源码剖析之事件循环系统(一)—事件系统
2025-3-16
| 2025-4-14
Words 835Read Time 3 min
type
status
date
slug
summary
tags
category
icon
password
事件系统是 Qt 核心机制,像多线程的信号和槽机制,也是基于事件以及事件循环系统驱动的。本文主要介绍 Qt 的事件系统的使用和基本概念,以便后续的源码分析。本文主要基于 Qt Quarterly —《Another Look at Events,加上一些自己的见解。

1. 事件的原理

根据创建和调度的方式,事件可以分为三种:
  • 自发事件(spontaneous event):由窗口系统产生的,在系统队列中由事件循环依次处理。
  • 被发布事件(Posted event):由 Qt 或应用产生,在队列中由事件循环按顺序处理
  • 被发送事件(Sent event):由 Qt 或应用产生,直接被发送到目标对象中。
一个 Qt 程序,通常在 main() 中,实例化一个应用(通常为 QCoreApplication 或其子类),并启动事件循环。事件循环的大致流程:
 

2. 合成事件

Qt 应用可以合成事件,预定义的事件类型的范围为(QEvent::None, QEvent::User),为系统预留的事件。但也可以合成自定义事件,自定义事件的类型范围为[QEvent::User, QEvent::UserMax]。
事件创建完成后,可通过 QCoreApplication::postEvent()QCoreApplication::sendEvent() 来分发。
  • QCoreApplication::postEvent()
    • postEvent(QObject* receiver, QEvent* event) 方法传入的事件必须在堆上分配,该事件被处理后会自动删除。该方法会将事件添加到 receiver 所在线程的事件队列中,由事件循环处理。
  • QCoreApplication::(QObject* receiver, QEvent* event)
    • sendEvent(QObject*, QEvent*) 方法传入
 

3. 自定义事件类型

Qt 允许创建自己的事件类型。事件在多线程应用中起到很大的作用。
  • 相比于信号和槽机制、函数调用,事件可以以同步(sendEvent)或异步(postEvent)的方式使用。
    • 注:信号和槽其实也可以以同步(Qt::BlockingQueuedConnection)或异步(Qt::QueuedConnection)的方式在多线程间使用。
  • 相比于信号和槽机制、函数调用,事件可以被过滤。
 

4. 事件处理和过滤

Qt中的事件可以在五个不同的层级上进行处理,由低到高分别为:
  • 重新实现特定的事件处理器, 比如 paintEvent()mousePressEvent()
  • 重新实现 QObject::event() 方法
  • QObject 对象上安装事件过滤器 eventFilter
  • QCoreApplication 或其子类 QGuiApplicationQApplication 上安装事件过滤器 eventFilter
  • 重写 QCoreApplication::notify() 方法。
    • 如果重写的方法没有覆盖所有事件,请最后调用默认的 notify() 方法
Qt 核心机制源码分析之元对象系统Qt源码剖析之事件循环系统(二)—事件循环系统的实现
Loading...