一、介绍
Qt中的QThread类提供了与平台无关的线程。一个QThread代表了一个在应用程序中可以独立控制的线程,它与进程中的其他线程分享数据,但是是独立执行的。
相对于一般的程序都从main()函数开始执行,QThread从run()函数开始执行。默认的,run()通过调用exec()来开启事件循环,并在线程内运行一个Qt事件循环。QThread的使用方法有如下两种:
1.使用QObject::moveToThread()
2.直接继承QThread类
二、使用moveToThread
首先新建一个work类,该类重点在于其doWork槽函数,这个函数定义了线程需要做的工作,需要向其发送信号来触发。
Worker.h
// work定义了线程要执行的工作
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include<QDebug>
#include<QThread>
class Worker :public QObject
{
Q_OBJECT
public:
Worker(QObject* parent = nullptr) {}
public slots:
// doWork定义了线程要执行的操作
void doWork(int parameter)
{
qDebug() << "receive the execute signal---------------------------------";
qDebug() << " current thread ID:" << QThread::currentThreadId();
// 循环一百万次
for (int i = 0; i != 1000000; ++i)
{
++parameter;
}
// 发送结束信号
qDebug() << " finish the work and sent the resultReady signal\n";
emit resultReady(parameter);
}
// 线程完成工作时发送的信号
signals:
void resultReady(const int result);
};
#endif // WORKER_H
然后定义一个Controller类,这个类中定义了一个QThread对象,用于处理worker对象的事件循环工作 。
Controller.h
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QObject>
#include<QThread>
#include<QDebug>
// controller用于启动线程和处理线程执行结果
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller(QObject *parent = nullptr);
~Controller();
public slots:
// 处理线程执行的结果
void handleResults(const int rslt)
{
qDebug() << "receive the resultReady signal---------------------------------";
qDebug() << " current thread ID:" << QThread::currentThreadId() << '\n';
qDebug() << " the last result is:" << rslt;
}
signals:
// 发送信号触发线程
void operate(const int);
};
#endif // CONTROLLER_H
Controller类的cpp文件,其构造函数中创建worker对象,并且将其事件循环全部交给workerThread对象来处理,最后启动该线程,然后触发其事件处理函数。
Controller.cpp
#include "Controller.h"
#include "Worker.h"
Controller::Controller(QObject *parent) : QObject(parent)
{
Worker *worker = new Worker;
//调用moveToThread将该任务交给workThread
worker->moveToThread(&workerThread);
//operate信号发射后启动线程工作
connect(this, SIGNAL(operate(const int)), worker, SLOT(doWork(int)));
//该线程结束时销毁
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
//线程结束后发送信号,对结果进行处理
connect(worker, SIGNAL(resultReady(int)), this, SLOT(handleResults(int)));
//启动线程
workerThread.start();
//发射信号,开始执行
qDebug() << "emit the signal to execute!---------------------------------";
qDebug() << " current thread ID:" << QThread::currentThreadId() << '\n';
emit operate(0);
}
//析构函数中调用quit()函数结束线程
Controller::~Controller()
{
workerThread.quit();
workerThread.wait();
}
main.cpp
#include <QCoreApplication>
#include "controller.h"
#include<QDebug>
#include<QThread>
int main(int argc, char *argv[])
{
qDebug()<<"I am main Thread, my ID:"<<QThread::currentThreadId()<<"\n";
QCoreApplication a(argc, argv);
Controller c;
return a.exec();
}
运行
三、继承QThread的方法
如果使用子类化QThread的方法,就是重写了QThread中的run()函数,在run()函数中定义了需要的工作。这样的结果是,我们自定义的子线程调用start()函数后,便开始执行run()函数
③定义TestThread对象并调用该对象的start方法运行
TestThread.h代码如下:
#ifndef TESTTHREAD_H
#define TESTTHREAD_H
#include <QObject>
#include <QThread>
class TestThread : public QThread
{
Q_OBJECT
public:
explicit TestThread(QObject *parent = nullptr);
private:
//重写run方法
void run();
signals:
//定义信号
void ShowDownloadProgress(int progress);
public slots:
};
#endif // TESTTHREAD_H
TestThread.cpp代码如下:
#include "TestThread.h"
TestThread::TestThread(QObject *parent) : QThread(parent)
{
}
void TestThread::run()
{
for(int i = 0 ; i <= 100 ; i++)
{
QThread::msleep(100);
ShowDownloadProgress(i);
}
}
新建MyController.h
#include <QObject>
#include <QThread>
#include <QDebug>
#include "TestThread.h"
class MyController : public QObject
{
Q_OBJECT
QThread workerThread;
public:
MyController() {
TestThread *workerThread = new TestThread();
connect(workerThread, SIGNAL(ShowDownloadProgress(int)), this, SLOT(ProgressLabelShow(int)));
workerThread->start();
}
~MyController() {
workerThread.quit();
workerThread.wait();
}
public slots:
void ProgressLabelShow(int value) {
qDebug() << " current thread value:" << value <<"%"<< '\n';
};
signals:
// 发送信号触发线程
void operate(const int );
};
在main.cpp中
#include <QVariant>
#include <QProcess>
#include<QDebug>
#include<QThread>
#include "MyController.h"
#include "TestThread.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "I am main Thread, my ID:" << QThread::currentThreadId() << "\n";
MyController c;
return a.exec();
}
运行
参考:
QThread介绍_雪易的博客-CSDN博客_qthread
QThread的用法_落霞与孤鹜亓飞的博客-CSDN博客_qthread