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

相关文章

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

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. 方法注