Qt消息循环与模态对话框和线程关系整理

2024-08-27 04:18

本文主要是介绍Qt消息循环与模态对话框和线程关系整理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

问题

之前在分析Qt事件循环源码时,相比很多人都会有疑问,当主线程(GUI 线程)在接受到某些命令时会弹出一个对话框,这个对话框会阻塞主界面的响应,这时候是不是有个子线程在处理弹出对话框的消息(毕竟这和多线程处理很像)?

概念普及

什么是模态对话框?

对于用户分成模态对话框非模态对话框(如下解释源于百度百科)

  • 模态对话框:又叫做模式对话框,是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。
  • 非模态对话框:又叫做无模式对话框,当用户打开非模态对话框时,依然可以操作其他窗口。例如,Windows提供的记事本程序中的【查找】对话框。【查找】对话框不会垄断用户的输入,打开【查找】对话框后,仍可与其他用户界面对象进行交互。
Qt中的模态对话框
  • 模态对话框,会阻塞当前主界面及其他窗体,后续代码必须等到当前窗体关闭后方可执行
    QDialog* pDialog = new QDialog(this);pDialog->setWindowTitle(QString::fromUtf8("模态对话框"));//以模态方法显示对话框pDialog->exec();// 关闭模态对话框后,才会继续执行下面的代码qDebug() << __FUNCTION__ <<"模态对话框";
  • 非模态对话框,不会阻塞当前主界面及其他窗体,不影响后续代码立即执行
    QDialog* pDialog = new QDialog(this);pDialog->setWindowTitle(QString::fromUtf8("非模态对话框"));//以非模态方法显示对话框pDialog->show();//无需关闭弹出对话框,下面的代码会立即运行qDebug() << __FUNCTION__ <<"非模态对话框";
  • 半模态对话框,会阻塞当前主界面及其他窗体,同时不影响后续代码立即执行
    QDialog* pDialog = new QDialog(this);pDialog->setWindowTitle(QString::fromUtf8("半模态对话框"));//以半模态方法显示对话框pDialog->open();//无需关闭弹出对话框,下面的代码会立即运行qDebug() << __FUNCTION__ <<"半模态对话框";
问题解析

解析的问题会从浅到深

弹出的窗体是什么?

模态对话框/非模态对话框

是否有子线程在处理弹出对话框的消息?

没有!且只有一个主线程

是否可以在子线程中更新UI?

不可以!和很多GUI开发类似,均不支持在子线程中更新GUI,如果想更新,可以通过信号槽机制,在槽函数(主线程)中更新UI

弹出的对话框上是如何响应各种事件的?

如果是QDialog::exec()(模态对话框),主线程的事件循环(QEventLoop)处于挂起状态,并且会在主消息循环上开一个子消息循环,直到这个消息循环被退出,外部的主消息循环才会继续。整个过程可以类比成两个嵌套的while循环

    while(主事件循环){processEvents(创建对话框事件){dialog new_dlg; while(子事件循环){};};    }
事件循环与线程的关系?

一个线程可以有多个事件循环 (1对多)

事件循环的特点?
  • 一个线程可以有多个事件循环,但所有的事件循环是嵌套关系,一层套一层。当前QEventLoop被激活时,父QEventLoop会被中断,直到子事件循环结束,父QEventLoop才会继续执行;
  • 子事件循环会拥有父事件循环的所有功能,这也是当弹出dialog,GUI不会被卡住的原因

总结

作为Qt开发经常会搞混线程和事件(消息)循环的关系,如果你真的想让你的程序避免出现异常(crash),那你必须理解这两个的关系。(多看源码,多写demo)

  • 主线程=GUI线程
  • 一个线程可以有多个事件循环
  • 事件循环之间的关系是嵌套

这篇关于Qt消息循环与模态对话框和线程关系整理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1110607

相关文章

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

MySQL 删除数据详解(最新整理)

《MySQL删除数据详解(最新整理)》:本文主要介绍MySQL删除数据的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、前言二、mysql 中的三种删除方式1.DELETE语句✅ 基本语法: 示例:2.TRUNCATE语句✅ 基本语

java中新生代和老生代的关系说明

《java中新生代和老生代的关系说明》:本文主要介绍java中新生代和老生代的关系说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、内存区域划分新生代老年代二、对象生命周期与晋升流程三、新生代与老年代的协作机制1. 跨代引用处理2. 动态年龄判定3. 空间分

Qt QCustomPlot库简介(最新推荐)

《QtQCustomPlot库简介(最新推荐)》QCustomPlot是一款基于Qt的高性能C++绘图库,专为二维数据可视化设计,它具有轻量级、实时处理百万级数据和多图层支持等特点,适用于科学计算、... 目录核心特性概览核心组件解析1.绘图核心 (QCustomPlot类)2.数据容器 (QCPDataC

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

Java中的for循环高级用法

《Java中的for循环高级用法》本文系统解析Java中传统、增强型for循环、StreamAPI及并行流的实现原理与性能差异,并通过大量代码示例展示实际开发中的最佳实践,感兴趣的朋友一起看看吧... 目录前言一、基础篇:传统for循环1.1 标准语法结构1.2 典型应用场景二、进阶篇:增强型for循环2.

Qt如何实现文本编辑器光标高亮技术

《Qt如何实现文本编辑器光标高亮技术》这篇文章主要为大家详细介绍了Qt如何实现文本编辑器光标高亮技术,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录实现代码函数作用概述代码详解 + 注释使用 QTextEdit 的高亮技术(重点)总结用到的关键技术点应用场景举例示例优化建议

Python循环结构全面解析

《Python循环结构全面解析》循环中的代码会执行特定的次数,或者是执行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都执行一次,这篇文章给大家介绍Python循环结构解析,感兴趣的朋友跟随... 目录for-in循环while循环循环控制语句break语句continue语句else子句嵌套的循