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

相关文章

SpringApplication的run方法主要代码步骤

一、图片流程图 二、主要代码  /*** Run the Spring application, creating and refreshing a new* {@link ApplicationContext}.* @param args the application arguments (usually passed from a Java main method)* @return

读《C语言陷阱与缺陷》一书后的一些注意事项

1.一般而言,赋值运算相对于比较运算出现得更频繁,因此字符数较少的符号=就被赋予了更常用的含义——赋值操作 2.' '不等于零(' '的ASCII码值为32) 3.需要注意的是,除了字符串与字符常量,符号的中间不能嵌有空白(空格符,制表符和换行符)。例如,如果/是为了判断下一个符号而读入的第一个字符,而/之后紧接着* , 那么无论上下文如何,这两个字符都将被当做一个符号 而实

Android UI 之 下拉刷新和上拉加载

前言: 下拉刷新和上拉加载,在很多应用中,我们都可以看到,其目的是为了通过刷新,分批次去加载一些数据量大的数据, 从而保证我们获取及显示在listView条目上及时,且又能保证获取的数据不会有遗漏,下面我们就来看一下下拉刷新和 上拉加载的特效是如何做的...... 效果图:                          下拉刷新的步骤: 步骤一:添加一个头部到lis

iOS 环信UI集成步骤

新建项目, 把环信的依赖库以及SDK导入到项目中, 添加pch文件, 把项目的Other Linker Flags 改成 -ObjC把环信demo的几个文件导入项目: 3rdparty, Category, Custom, Resources, Class ->Chat -> ChatView, 还有它的define文件ChatDemoUIDefine.h在pch文件导入头文件

element-ui dialog form 弹框表单组件封装

在使用 element-ui 进行后端管理系统开发时,在封装弹框表单时,遇到两个问题,这里进行简单记录: 1、问题一:点击关闭按钮及遮罩层关闭弹框时,页面报错,如下: 子组件封装: <template><el-dialog title="dialog form" :visible.sync="visible" width="432px"><el-form ref="formRef" :m

UI网站

http://ui.dtmao.cc/

java版数字藏品深色UI仿鲸探数藏盲盒合成短视频卡牌模式支持高并发功能介绍

根据您提供的艺术品发售系统的需求,以下是一个更为详细和全面的系统设计概述: 1. 藏品发售 藏品分类:藏品可以按照不同的类别进行分类,如绘画、雕塑、摄影等。稀有度设置:后台可以为每个藏品设置不同的稀有度,如普通、稀有、史诗、传说等,并设置相应的售价。购买限制:可以设定购买数量限制、用户等级限制等。 2. 二级市场 交易系统:用户可以将自己的藏品直接挂售到二级市场商城,并设定售价。交易记录:

【GoLang基础】函数体的注意事项和细节讨论

在 Go 语言(Golang)中,函数是程序的基本构建块之一。理解函数的定义和使用是掌握 Go 语言的重要步骤。下面是关于 Go 语言中函数体的详细解释,包括函数的定义、参数传递、返回值以及闭包等方面。 1. 函数的定义 在 Go 语言中,函数使用关键字 func 来定义。函数的基本语法如下: func functionName(parameterList) (returnTypeList)

C#thread线程传参数更新UI的文本框

C#线程的用法有几个不同的地方: 1、怎么启动线程? 2、是不是需要传入参数? 3、是不是要调用到UI中的控件,并对其进行更新? 关于启动线程,这里一个示例是在form中启动: 定义一个private:static Form1^ instance;变量并在构造函数中赋值为this:Form1(void){instance = this;InitializeComponent();

Android SDK版本号与API级别的对应关系以及创建工程时选择API版本的注意事项

API 3:android 1.5 API 4:android 1.6 API 5:android 2.0 API 6:android 2.0.1 API 7:android 2.1 API 8:android 2.2 API 9:android 2.3 API 10:android 2.3.3 API 11:android 3.0(这个比较重要,fragment,loader,A