上文列举了qt中线程的几种方法,其中2种方法最为常见。
这两种方法都少不了QThread类,前者继承于QThread类,后者复合QThread类。
本文以实例的方式描述了movetothread()这种线程的方法,将QObject的子类移动到指定的线程。
一、例子
1. Worker类
1.1Worker类头文件
#ifndef WORKER_H
#define WORKER_H
#include <QObject>
#include<QDebug>
#include <QThread>
class Worker : public QObject
{
Q_OBJECT
public:
explicit Worker(QObject *parent = nullptr);
public slots:
void doWork(const QString ¶meter);
signals:
void resultReady(const QString &result);
};
#endif // WORKER_H
1.2 Worker类cpp文件
#include "worker.h"
Worker::Worker(QObject *parent)
: QObject{parent}
{}
void Worker::doWork(const QString ¶meter)
{
// 在这里写入你的线程代码
qDebug() << "Thread2 is running";
qDebug() << parameter;//收到的参数
//一个简单的循环
for (int i = 0; i < 5; i++)
{
QThread::msleep(500); ; // 休眠1秒
qDebug() << "!!!";
}
qDebug() << "end2";
emit resultReady("======");//发结果
}
2.Controller类
2.1Controller类头文件
#ifndef CONTROLLER_H
#define CONTROLLER_H
#include <QObject>
#include "worker.h"
#include <QThread>
class Controller : public QObject
{
Q_OBJECT
public:
explicit Controller(QObject *parent = nullptr);
QThread workerThread;//复合了QThread类
signals:
void operate(const QString ¶meter);
public slots:
void handleResult(const QString & str);
};
#endif // CONTROLLER_H
2.2Controller类cpp文件
#include "controller.h"
Controller::Controller(QObject *parent)
: QObject{parent}
{
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this,&Controller::handleResult);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
workerThread.start();
}
void Controller::handleResult(const QString & str)
{
qDebug()<<str;//取结果
}
3.在窗口类的按钮函数里放入
void MainWindow::on_pushButton_xxx_clicked()//你自己的按钮函数
{
Controller *controller = new Controller();
controller->operate("parameter");
}
二、优缺点
优点:克服了重写run的缺点,比较灵活简洁,
缺点:但是不能在线程里面实现常驻任务(死循环的任务)。
轻量级的函数可以用movethread,无需创建独立线程类,例如你有多个小函数要在线程内做, 全部扔给一个QThread。还有一开始没使用线程,但是后边发觉这些代码还是放线程比较好,如果用子类化QThread的方法重新设计代码,将会有可能让你把这一段推到重来,这个时候,moveThread的好处就来了,你可以把这段代码的从属着movetothread,把代码移到槽函数,用信号触发它就行了。