使用流程
1.创建一个由QObject派生的子类MyWork
2.创建MyWork对象,注意不要指定父对象
3.创建一个子线程
4.用QObject提供的moveToThread()函数将Work对象移到子线程中
5.start()启动子线程
6.调用MyWork对象的工作函数
流程实例
1.mywork.h
#ifndef MYWORK_H
#define MYWORK_H
#include <QObject>
class MyWork : public QObject
{
Q_OBJECT
public:
explicit MyWork(QObject *parent = nullptr);
// 工作函数
void working();
};
#endif
2.mywork.cpp
#include "mywork.h"
#include <QDebug>
#include <QThread>
MyWork::MyWork(QObject *parent) : QObject(parent)
{
}
void MyWork::working()
{
qDebug() << "当前线程对象的地址: " << QThread::currentThread();
int num = 0;
while(1)
{
if(num == 10000000)
{
break;
}
QThread::usleep(1);
}
qDebug() << "run() 执行完毕, 子线程退出...";
}
3.main.cpp
#include <QThread>
#include "mywork.h"
#include <QDebug>
int main()
{
qDebug() << "主线程对象的地址: " << QThread::currentThread();
// 创建线程对象
QThread* sub = new QThread;
// 创建工作的类对象
// 千万不要指定给创建的对象指定父对象
// 如果指定了: QObject::moveToThread: Cannot move objects with a parent
MyWork* work = new MyWork;
// 将工作的类对象移动到创建的子线程对象中
work->moveToThread(sub);
//信号和槽
connect(sub,&Qthread::started,work,&MyWork::working);
// 启动线程
sub->start();
//调用工作函数,这样是指定主线程运行的
//work->working();
}
注意:
1.在使用的时候发现不用信号和槽的方式去调用任务,任务运行的线程id一直是主线程。
错误方式:
work->moveToThread(sub);
// 启动线程
sub->start();
//调用工作函数
work->working();
正确方式:
work->moveToThread(sub);
//信号和槽
connect(sub,&Qthread::started,work,&MyWork::working);
// 启动线程
sub->start();
//错误示范❌,原因在于下面两个都是指定working由主线程来触发,本质是执行主线程的槽函数
void Widget::on_pbStart_clicked() //本质上这是个槽函数,点击按钮就执行这个槽函数
{
work->working(); //因为work对象在主线程里定义的,如此执行working也是在主线程
}
//或者
connect(sub,&Qthread::started,this,[=](){
work->working(); //这和上面on_pbStart_clicked()里被调用没有区别
});
更新
2024-9-10
//创建子线程
thread = new QThread;
//任务类
mMyThread = new MyThread;
mMyThread->moveToThread(thread);
connect(thread,&QThread::started,mMyThread,&MyThread::Worker);
thread->start();
//发现这样使用connect,匿名函数内的代码是在子线程中运行的;
//创建子线程
thread = new QThread;
//任务类
mMyThread = new MyThread;
mMyThread->moveToThread(thread);
connect(thread,&QThread::started,mMyThread,[this](){
qDebug()<<"````````"<<QThread::currentThreadId();
QString path = "1.bmp";
ui->widget_4->setImage(path);
});
thread->start();