QtConcurrent::run操作界面ui的注意事项(1)

2024-05-06 10:12

本文主要是介绍QtConcurrent::run操作界面ui的注意事项(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先说结论:QtConcurrent::run启动的耗时处理函数,不允许处理ui界面对象,如控件,如进度条等等!

QtConcurrent::run非常好用,胜过QThead的两种方式(run和moveToThread),例如下面是非常直观和简单的使用方式:

QT += concurrent#include <QtConcurrent>
#include <QThread>void MainWindow::doSomeWork()//死循环操作,代替原有代码的函数功能
{int i=0;while(myEnable){i++;qDebug()<<i;QThread::msleep(10);}
}void MainWindow::myStart()//启动函数是需要在原有代码基础上增加
{myEnable=1;QtConcurrent::run(this,&MainWindow::doSomeWork);//多线程执行死循环启动,可以带参数void MainWindow::myExit()
{myEnable=0;//
}

但是,但是,上述的MainWindow::doSomeWork函数中不能访问ui对象,会引起程序崩溃!!原因后面解释。先说解决办法:

一种方法是,MainWindow::doSomeWork能读写简单类型的数值变量,int,float类型,则可以借助这些简单类型变量做个过渡中转一下。既然是ui界面对象,是给人看的,延时几十个ms,人的眼睛不会有感觉,因此,开一个定时器,轮询这些简单的数值int、float变量,在定时器里去更新ui界面对象,这是最简单的方法;

另一种方法是,在调用QtConcurrent::run(this,&MainWindow::doSomeWork)的地方,检查返回值,开一个循环等待完成。在循环里完成对界面ui的操作,如下面在按钮点击事件中:

void MainWindow::on_pushButton_clicked()
{ui->progressBar->setRange(0, 100); //使用进度条QFuture<void> future = QtConcurrent::run(this,&MainWindow::doSomeWork);//多线程执行死循环启动,可以带参数while(!future.isFinished()){ui->progressBar->setValue(m_curVal); //设置进度条当前值,m_curVal在doSomeWork中被更新QApplication::processEvents(QEventLoop::AllEvents, 100); //避免ui挂死}
}

上面依然是第一种方式的变种,只不过在循环里,借助了QApplication::processEvents(QEventLoop::AllEvents, 100),避免将ui挂死。

小结上述两种方法,第一种其实就是“共享全局变量”的变形;第二种是把循环直接写在ui的按钮事件里,让ui保持“灵活”;

再回到上述的:MainWindow::doSomeWork函数中不能访问ui对象,会引起程序崩溃!!

原因是,QtConcurrent::run本质是开启了另外一个子线程,该子线程和ui线程不相同,可以用:

qDebug()<<"当前线程 "<<QThread::currentThread();

分别加入到MainWindow的构造函数、on_pushButton_clicked()函数、doSomeWork()函数里验证,会发现,不在同一个线程里。这是qt的“跨线程”问题。

因为涉及到“跨线程”问题,总的来说,QtConcurrent::run并不好用,如果开启的线程里,要读写套接字tcp/udp、串口,是有问题的。

这篇关于QtConcurrent::run操作界面ui的注意事项(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

MySQL 获取字符串长度及注意事项

《MySQL获取字符串长度及注意事项》本文通过实例代码给大家介绍MySQL获取字符串长度及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql 获取字符串长度详解 核心长度函数对比⚠️ 六大关键注意事项1. 字符编码决定字节长度2

C++链表的虚拟头节点实现细节及注意事项

《C++链表的虚拟头节点实现细节及注意事项》虚拟头节点是链表操作中极为实用的设计技巧,它通过在链表真实头部前添加一个特殊节点,有效简化边界条件处理,:本文主要介绍C++链表的虚拟头节点实现细节及注... 目录C++链表虚拟头节点(Dummy Head)一、虚拟头节点的本质与核心作用1. 定义2. 核心价值二

详解MySQL中DISTINCT去重的核心注意事项

《详解MySQL中DISTINCT去重的核心注意事项》为了实现查询不重复的数据,MySQL提供了DISTINCT关键字,它的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据... 目录DISTINCT 六大注意事项1. 作用范围:所有 SELECT 字段2. NULL 值的特殊处

MySQL 打开binlog日志的方法及注意事项

《MySQL打开binlog日志的方法及注意事项》本文给大家介绍MySQL打开binlog日志的方法及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、默认状态二、如何检查 binlog 状态三、如何开启 binlog3.1 临时开启(重启后失效)

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

QT6中绘制UI的两种方法详解与示例代码

《QT6中绘制UI的两种方法详解与示例代码》Qt6提供了两种主要的UI绘制技术:​​QML(QtMeta-ObjectLanguage)​​和​​C++Widgets​​,这两种技术各有优势,适用于不... 目录一、QML 技术详解1.1 QML 简介1.2 QML 的核心概念1.3 QML 示例:简单按钮

在 PyQt 加载 UI 三种常见方法

《在PyQt加载UI三种常见方法》在PyQt中,加载UI文件通常指的是使用QtDesigner设计的.ui文件,并将其转换为Python代码,以便在PyQt应用程序中使用,这篇文章给大家介绍在... 目录方法一:使用 uic 模块动态加载 (不推荐用于大型项目)方法二:将 UI 文件编译为 python 模

电脑死机无反应怎么强制重启? 一文读懂方法及注意事项

《电脑死机无反应怎么强制重启?一文读懂方法及注意事项》在日常使用电脑的过程中,我们难免会遇到电脑无法正常启动的情况,本文将详细介绍几种常见的电脑强制开机方法,并探讨在强制开机后应注意的事项,以及如何... 在日常生活和工作中,我们经常会遇到电脑突然无反应的情况,这时候强制重启就成了解决问题的“救命稻草”。那

Kotlin 作用域函数apply、let、run、with、also使用指南

《Kotlin作用域函数apply、let、run、with、also使用指南》在Kotlin开发中,作用域函数(ScopeFunctions)是一组能让代码更简洁、更函数式的高阶函数,本文将... 目录一、引言:为什么需要作用域函数?二、作用域函China编程数详解1. apply:对象配置的 “流式构建器”最