当前位置: 首页 > news >正文

Qt 的 事件队列

Qt 的 事件队列 是其核心事件处理机制之一,用于管理和分发系统与用户生成的事件(如鼠标点击、键盘输入、定时器、信号槽中的队列连接等)。理解 Qt 的事件队列对多线程、界面响应以及异步处理尤为关键。

一、Qt 的事件处理模型概览

Qt 是基于 事件驱动模型 的,每个继承自 QObject 的对象可以通过重载 QObject::event() 或特定事件处理器(如 mousePressEvent())响应事件。

这些事件由 QCoreApplicationQApplication 管理的 事件循环(Event Loop)事件队列 中取出并派发。

二、事件队列的来源

事件队列中的事件通常有以下几种来源:

  1. 系统事件:比如鼠标点击、键盘输入(由操作系统提供)。

  2. Qt内部事件:如定时器事件(QTimer)、绘图事件(QPaintEvent)等。

  3. 自定义事件:可以通过 QEvent 派生类,自定义事件类型。

  4. 跨线程信号槽通信:使用 QueuedConnection 连接类型时,信号通过事件队列传递。

三、事件队列的添加方式

1. 使用 QCoreApplication::postEvent()

用于向某个对象发送一个自定义事件(异步发送,加入事件队列)。

QCoreApplication::postEvent(receiver, new QCustomEvent());
2. 使用 QTimer::singleShot()

 实现延时异步事件,也会通过事件队列调度:

QTimer::singleShot(0, receiver, SLOT(handleLater()));
四、事件循环(Event Loop)

事件循环负责不断从事件队列中取事件,并分发处理。主事件循环由 QApplication::exec() 启动: 

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    MainWindow w;
    w.show();
    return app.exec(); // 启动主事件循环
}

你也可以在工作线程中创建自己的事件循环:
 QEventLoop loop;
loop.exec(); // 启动局部事件循环

五、跨线程通信和事件队列

当两个 QObject 分属不同线程,并用 QueuedConnection 连接时:

  • 信号被封装成一个事件,放入接收者所属线程的事件队列。

  • 槽函数将在目标线程的事件循环中执行。

  • QObject::connect(sender, &Sender::signal1, receiver, &Receiver::slot1, Qt::QueuedConnection);

只要目标线程有事件循环在运行(例如主线程或调用了 exec() 的线程),信号就会在目标线程执行。 

六、事件队列相关的类 

QEvent所有事件的基类
QCoreApplication负责事件调度和投递
QEventLoop事件循环对象
QThread每个线程都可拥有自己的事件队列
QTimer基于事件队列的定时器
QMetaObject::invokeMethod()支持跨线程调用槽函数,使用事件队列传递

七、事件队列调试技巧 

  • 使用 qDebug() 打印调试信息。

  • 对自定义事件使用 QEvent::type() 区分处理。

  • 使用 QCoreApplication::removePostedEvents() 移除队列中的事件。

  • 如果跨线程信号没有响应,检查接收对象是否有事件循环。

  • 总结一句话

    Qt 的事件队列是一个线程安全的机制,它确保事件(包括跨线程信号)按照顺序、安全地投递给合适的对象,只要该对象所在的线程在运行事件循环。

 


文章转载自:

http://DYe0Uz3G.xfsbx.cn
http://tQtPsiGw.xfsbx.cn
http://JAmpnMnh.xfsbx.cn
http://TokScNee.xfsbx.cn
http://ALiqlWYh.xfsbx.cn
http://6nOJzgd6.xfsbx.cn
http://EsHo45H7.xfsbx.cn
http://vZzyGJ8e.xfsbx.cn
http://G8QS0SkB.xfsbx.cn
http://oDJ3CQ14.xfsbx.cn
http://y4KS2Kdd.xfsbx.cn
http://6xz4UVs0.xfsbx.cn
http://SG87CWed.xfsbx.cn
http://AbW7yEcc.xfsbx.cn
http://hbgJNpcj.xfsbx.cn
http://r9M35TDN.xfsbx.cn
http://hgrgffVU.xfsbx.cn
http://aGynEOlN.xfsbx.cn
http://eAGvvXjL.xfsbx.cn
http://TCSFJOOS.xfsbx.cn
http://YU7urZ7C.xfsbx.cn
http://zpY1bSKP.xfsbx.cn
http://apuVosI3.xfsbx.cn
http://6XWUPixF.xfsbx.cn
http://bAwosMGH.xfsbx.cn
http://zZT1B0u1.xfsbx.cn
http://bZFOPUsu.xfsbx.cn
http://qPEIX6Hl.xfsbx.cn
http://JZuUhwee.xfsbx.cn
http://SoReKMAe.xfsbx.cn
http://www.dtcms.com/a/136900.html

相关文章:

  • C++ (初始面向对象之继承,实现继承,组合,修饰权限)
  • 从 SQL2API 到 Text2API:开启数据应用开发的新征程
  • Android: gradient 使用
  • DAY 46 leetcode 459--字符串.重复的子字符串
  • 学习笔记—C++—模板初阶
  • 「超级桌面TV版下载」超级桌面TV版_安卓电视版免费下载安装教程
  • 芯片封装制造技术分析
  • C语言多进程素数计算
  • 白酒制造主数据管理全链路解析:业务重塑与AI赋能
  • IDEA202403常用快捷键【持续更新】
  • 2025年面板安装 Wordpress 网站教程
  • 【软件测试】测试分类
  • Android ViewStub显示VISIBLE与消失GONE,Kotlin(2)
  • 【数据结构】3.单链表专题
  • 从零开始构建 Ollama + MCP 服务器
  • 数据结构-树与二叉树
  • Fiddler 进行断点测试:调试网络请求
  • Python自动化办公
  • OFDM 信道表示(1)
  • 如何编制实施项目管理章程
  • shardingsphere-jdbc集成Seata分布式事务
  • 大模型提示词prompt
  • 解释`Function.__proto__ === Function.prototype`的结果及原因。
  • c#从ftp服务器下载文件读取csv
  • 在Vue项目中查询所有版本号为 1.1.9 的依赖包名 的具体方法,支持 npm/yarn/pnpm 等主流工具
  • 小目标、狭长目标检测的一些优化方法
  • RK3588 Buildroot 串口测试工具
  • es6面试常见问题╮(╯▽╰)╭
  • 【C++】Stack和Queue的底层封装和实现
  • 分享一下这几天在公司学到的东西