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

2024-04-30 08:12

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

先说结论: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的注意事项的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

bytes.split的用法和注意事项

当然,我很乐意详细介绍 bytes.Split 的用法和注意事项。这个函数是 Go 标准库中 bytes 包的一个重要组成部分,用于分割字节切片。 基本用法 bytes.Split 的函数签名如下: func Split(s, sep []byte) [][]byte s 是要分割的字节切片sep 是用作分隔符的字节切片返回值是一个二维字节切片,包含分割后的结果 基本使用示例: pa

Golang GUI入门——andlabs ui

官方不提供gui标准库,只好寻求第三方库。 https://github.com/google/gxui 这个gui库是谷歌内部人员提供的,并不是谷歌官方出品,现在停止维护,只好作罢。 第三方gui库 找了好多,也比较了好多,最终决定使用的是还是 https://github.com/andlabs/ui 相信golang gui还会发展的更好,期待更优秀的gui库 由于andlabs

Vue项目开发各种注意事项

1、eCharts引入方式(单页面) import * as echarts from 'echarts'Vue.prototype.$echarts = echarts 2、Sass引入 sass和node-sass 中 node-sass不要引入最新版本  引入@7.x 否则会报错 可能是语法规则改变 3、严格模式不要随意开启、将eslint文件中 extends: 中的vue去除

Exchange 服务器地址列表的配置方法与注意事项

Exchange Server 是微软推出的一款企业级邮件服务器软件,广泛应用于企业内部邮件系统的搭建与管理。配置 Exchange 服务器地址列表是其中一个关键环节。本文将详细介绍 Exchange 服务器地址列表的配置方法与注意事项,帮助系统管理员顺利完成这一任务。 内容目录 1. 引言 2. 准备工作 3. 配置地址列表 3.1 创建地址列表 3.2 使用 Exchange

API28_OKgo_get注意事项

1: implementation 'com.lzy.net:okgo:2.1.4' 2:在BaseApplication中onCreate()中初始化initOKgo() private void initOKgo() {//---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//HttpHeaders headers

移动UI:分类列表页、筛选页的设计揭秘。

移动UI的列表页设计需要考虑用户体验和界面美观性,以下是一些建议的设计要点: 1. 列表项的展示: 列表页应该清晰地展示各个列表项,包括标题、副标题、缩略图等内容,以便用户快速浏览和识别。可以使用卡片式布局或者简洁的列表布局。 2. 搜索和筛选: 如果列表项较多,应该提供搜索和筛选功能,方便用户查找感兴趣的内容。搜索框和筛选条件可以放置在页面顶部或者底部,以便用户方便操作。

【VueJS】live-server 快速搭建服务 及 注意事项

本地开发常常需要搭建临时的服务,第一时间我们会想到用 http-server。 但现在流行修改文件浏览器自动刷新,这里可以使用 live-server 很简单就能启动一个看起来很专业的本地服务。 你只需要全局安装live-server: npm install -g live-server 并在项目根目录执行这条命令: PS E:\AblazeProject\Vue> live-serv

UI自动化测试常见面试题

1、什么是UI自动化测试? UI自动化测试是一种通过模拟用户交互并自动执行UI操作的软件测试方法。它用于验证用户界面的功能和稳定性,以确保在不同的操作系统、浏览器和设备上的一致性。 2、UI自动化测试的优势和劣势是什么? 优势: 可以节省时间和成本,提高测试效率。 可以自动执行大量的重复测试任务,减少人为错误。 可以实现广泛的测试覆盖,包括不同的操作系统、浏览器和设备。 可以提供稳定

element-ui打包之后图标不显示,woff、ttf加载404

1、bug 起因 昨天在 vue 项目中编写 element-ui 的树形结构的表格,发现项目中无法生效,定位问题之后发现项目使用的 element-ui 的版本是 2.4.11 。看了官方最新版本是 2.15.14,然后得知 2.4.11 版本是不支持表格树形结构的。于是决定升级 element-ui 的版本,方便后续的开发。 升级之后本地简单的过了一遍系统功能,并没有发现有什么不妥,于