qt多线程的两种方法run和movetothread

qt多线程的有什么用?

将耗时长的操作丢入专属线程执行,这样就不会影响主线程的界面操作,操作完再用信号槽等的方式返回结果

1.界面和部件相关都必须在主界面运行,不要用子线程调用或者操作,会引起奇怪的bug,子线程通过信号槽操作界面返回结果

2.线程转移不允许有父对象的线程转移,可能是因为父对象对象树销毁时无法保证子对象线程安全

3.对象必须包含QOBJECT

下面用两种方法介绍多线程的使用方法

假设有一种算法非常耗时,要消耗2s,我们设计一个界面求计算后的结果

经典方法:

转到按键信号槽,调用

当你计算的时候就会惊奇的发现,点击计算后计算完成前界面动不了了,连关都关不掉,点快了甚至还会无响应,因为所有gui相关组件和界面都在且只能在主线程进行

为了更直观的表现,我们修改一下代码,使用QThread::currentThreadID()看看主线程和执行算法的线程ID

可以看到算法是在主线程执行的,所以才会导致界面在执行算法中无法操作

为了防止出现这样的问题,采用子线程执行,这样就不会影响界面的操作,有两种方法

1.重写run

建立一个类,继承QThread,初步重写run函数

在QT中,对象与对象之间都是new的,所以无法相互调用,对象间操作都要通过信号槽或者元对象系统访问,我们的算法也不例外,算法对象由widget创立,需要通过信号槽完成算法对象对widget对象的数据结果返回(所以要继承QOBJECT),添加算法类内容

重写run的多线程方式有点像动态线程,即取即用

1,按键按下的槽函数

建立算法对象赋值,连接算法返回值槽函数,算法对象调用start函数

注意:重写的run函数为start()后新线程自动执行的函数,run函数执行完成后线程结束销毁

你可以直接调用run方法,仍会执行run函数内容,但是只会在调用run的线程里执行run的内容,不会创建新线程执行run内容,只能通过调用start方法才能真正在新线程里执行run函数的内容。

2.算法的run函数

因为算法没有绑定父对象,所以让它执行完后自己释放自己的内存

打印的槽函数:

执行 输入值后连点两次计算看看

发现连点两次创造了两个线程,我们的算法在线程里执行,如果是单线程执行第二次点的时候就直接卡死了。稍等一下结果出来后再点击一下计算看看

线程run函数执行完后释放,所以第三次点击的时候第一次和第二次的线程已经销毁了,可以又从第一次的线程ID创建,可以在run函数最后加上while(1)或者exec看看是否会释放

2.moveToThread

moveToThread更倾向于将计算丢进一个长期存在的算法线程,所以对构造函数进行改变并且在widget构造时就新建此线程,且不退出

创建一个简单的线程类对象

在主线程中创建这个类的对象并start,连接算法对象的接收发送信号槽,最后将算法对象移动到创建的线程对象

执行,点击两下计算,会发现一开始只打印了一次,因为此时算法线程在执行第一个信号槽函数的QThread::sleep,所以信号在事件里等待,然后过2s后第二个信号执行。两次的算法线程一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值