Qt5.13中使用线程(moveToThread)

一般情况下,我们涉及的是单线程,那么在实际上使用的设备都是多线程的,如何利用Qt使用多线程呢?在Qt5后官方都建议使用继承QObject的方式moveToThread,我只讲第二种,既然官方都这么建议了。

在讲解前,我预设一个场景,界面显示摄像头画面(这是个主进程),发生一个耗时操作,这样的话,摄像头画面将会卡顿(直到耗时操作结束),这显然不是我们所希望的,当然应该将耗时操作放在工作线程中。

一: Qt的两种多线程的方法

1: 继承QThread的run函数,是个虚函数,会自动调用的
2: 继承于QObject的类用moveToThread函数转移到一个Thread里

二:分析官网文档的例程,按照下面的使用方法就没问题

2.1:创建一个新类,直接继承QObject,一定要选择QObject,不然类中不会有Q_OBJECT,一编译就报很多错。假如你忘了或者没有继承QObject,你可以把父类改成QObject,并添加Q_OBJECT,还会报错的,这是你把新类的.h .cpp先移除在添加进来即可。同时注意.pro文件SOURCES += 和 HEADERS += 有且只有一项新类的.h .cpp。我发现有时你重复添加/移除类文件,.pro文件会有重复。

可以看看我之前的错误:
https://blog.csdn.net/weixin_39956356/article/details/96108017

2.2:在工作线程中添加信号和槽,官方推荐这种方式进行进程间的交互。
2.3:在构造函数中连接工作线程
2.3.1: 在主进程的类中定义一个线程变量
#include <QThread>
//在主进程的类中定义一个线程变量
QThread _thread;                                        //工作线程--计算相似度
2.3.2: 流程分析
1. 创建一个新工作线程---------------------------- ----cameraThread* pWork = new cameraThread();
2. 将工作线程pWork丢到线程中--------------------------pWork->moveToThread(&_thread);
3. 由于new了一个对象,只需要在子进程结束时释放pWork---connect(&_thread, &QThread::finished, pWork, &QObject::deleteLater);
4.  主进程启动子进程,发送一个信号即可(信号可以带子线程需要的数据,多了就弄成结构体)---connect(this,SIGNAL(sendStruct(const similarityInfo)), pWork, SLOT(revStruct(const similarityInfo)));
5. 将子进程的结果传回到主进程---connect(pWork,SIGNAL(reuslt(float)), this, SLOT(resulted(float)));
cameraThread* pWork = new cameraThread();
pWork->moveToThread(&_thread);
connect(&_thread, &QThread::finished, pWork, &QObject::deleteLater);                    //由于这里发定义的是局部变量,所以需要在线程结束后释放这个变量
connect(this,SIGNAL(sendStruct(const similarityInfo)), pWork, SLOT(revStruct(const similarityInfo)));       //点击开始即可比对
connect(pWork,SIGNAL(reuslt(float)), this, SLOT(resulted(float)));                      //计算结果就返回
_thread.start();  //什么时候启动,看要求,也不是一开始就启动,也可能按下按才启动
2.3.3: 析构
    //结束线程并等待--固定操作
    _thread.quit();
    _thread.wait();

官方文档:

总之;
1 先建一个类,继承QObject即可
2 主进程类中定义一个线程变量
3 关联它们moveToThread
4 至少3个connect,一是子进程完成就删除1中变量,二是主到从,三是从到主

(0)

相关推荐