官方链接QThread Class | Qt Core 5.15.14
QThread::run()
简单来说就是继承QThread类,并重写run()函数,这样run()函数中的代码就会运行在子线程中。
QThread对象管理着一个线程,并通过start函数启动这个线程,线程要执行的代码都在run()里面,run()函数的进入和返回,就相当于子线程的启动和结束。
但是run()函数何时返回呢?一般有三种情况:
当run函数执行完毕的时候,新线程也就结束了,并且发出finished()信号。
#ifndef SOMETHINGTHREAD_H
#define SOMETHINGTHREAD_H
#include
#include
class SomethingThread : public QThread
{
Q_OBJECT
public:
explicit SomethingThread(QObject *parent = nullptr);
void run() override;//线程函数
private: signals:
void resultReady(const QString result);//如果有线程计算结果返回,可以通过这种方式
};
#endif // SOMETHINGTHREAD_H
#include "somethingthread.h"
#include "qdebug.h"
SomethingThread::SomethingThread(QObject *parent)
: QThread{parent}
{
}
void SomethingThread::run()
{
for(int i=0;i<10;i++)
{
qDebug()<<"doing something %d"<resultReady("finish");//触发信号,传递结果参数
}
SomethingThread* sth=new SomethingThread(this);
connect(sth,&SomethingThread::resultReady,this,&SIHToolBar::onResultReady);//使用接收结果
connect(sth,&SomethingThread::finished,sth,&QObject::deleteLater);
sth->start();
void SIHToolBar::onResultReady(const QString result)
{
qDebug()<<"onResultReady result="<doing something %d 0 thread_id 0x6188
doing something %d 1 thread_id 0x6188
doing something %d 2 thread_id 0x6188
doing something %d 3 thread_id 0x6188
doing something %d 4 thread_id 0x6188
doing something %d 5 thread_id 0x6188
doing something %d 6 thread_id 0x6188
doing something %d 7 thread_id 0x6188
doing something %d 8 thread_id 0x6188
doing something %d 9 thread_id 0x6188
onResultReady result= "finish" thread_id= 0x2f0
有几点需要注意:
QThread::run() { this->exec(); }
,也就是默认开启了事件循环。QObject::moveToThread()
moveToThread 方法,是把我们需要的工作全部封装在一个类中,将每个任务定义为一个槽函数,再建立触发这些槽函数的信号,然后连接信号和槽,最后调用 moveToThread 方法将这个类交给一个 QThread 对象,再调用 QThread 的 start() 函数使其全权处理事件循环。于是,任何时候我们需要让子线程执行某个任务,只需要发出对应的信号就可以。
#ifndef WORKER_H
#define WORKER_H
#include
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
signals:
void resultReady(const QString& result);//线程完成工作时发送的信号
public slots:
void doWork(const QString& param);//定义了线程要执行的操作
};
#endif // WORKER_H
#include "worker.h"
#include
#include
Worker::Worker(QObject *parent)
: QObject{parent}
{
}
void Worker::doWork(const QString ¶m)
{
for(int i=0;i<10;i++)
{
qDebug()<<"doWork %d"<resultReady("finish");//触发信号,传递结果参数
}
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include
#include
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
explicit Controller(QObject *parent = nullptr);
~Controller();
signals:
void doWork(const QString& param);//发送信号 触发线程
public slots:
void onResultReady(const QString& result);//处理子线程执行的结果
};
#endif // CONTROLLER_H
#include "controller.h"
#include "worker.h"
#include
Controller::Controller(QObject *parent)
: QObject{parent}
{
Worker* work=new Worker();
work->moveToThread(&this->workerThread);//调用moveToThread将该任务交给
connect(&this->workerThread,&QThread::finished,work,&QObject::deleteLater);//当线程结束的时候,销毁worker对象
connect(this,&Controller::doWork,work,&Worker::doWork);//通过controller的dowork信号 连接 worker对象的doworker槽函数
connect(work,&Worker::resultReady,this,&Controller::onResultReady);
workerThread.start();
qDebug()<<"main thread_id="<doWork("start");
//work->doWork("start");//这种直接调用的方式没有在子线程中执行
}
Controller::~Controller()
{
workerThread.quit();
workerThread.wait();
}
void Controller::onResultReady(const QString &result)
{
qDebug()<<"onResultReady result="<main thread_id= 0x7254
doWork %d 0 thread_id 0x5970
doWork %d 1 thread_id 0x5970
doWork %d 2 thread_id 0x5970
doWork %d 3 thread_id 0x5970
doWork %d 4 thread_id 0x5970
doWork %d 5 thread_id 0x5970
doWork %d 6 thread_id 0x5970
doWork %d 7 thread_id 0x5970
doWork %d 8 thread_id 0x5970
doWork %d 9 thread_id 0x5970
onResultReady result= "finish" thread_id= 0x7254
有几点需要注意: