子类化QThread
这个用法很简单,首先创建一个Worker类继承QThread,重写run()函数即可。常见的用法伪代码如下:
// 定义线程
class Worker : public QThread{
protected:
void run(){
// do something
}
}
// 使用线程
Worker *worker = new Worker;
worker->start(); // run函数开始运行
这样写的线程有以下缺点:
1、线程中的对象必须在run函数中创建
2、线程无法接收信号,只能发送信号
对象moveToThread
顾名思义是将一个对象移动到某个线程中去运行。大概的用法流程是创建一个Worker类继承QObject,定义一些你想做的槽函数,然后new一个QThread对象,并把Worker的实例化move到这个线程中去,连接好相应的信号和槽就可以在线程中跑起来了。以下给出一个用法示例代码及其运行结果:
Worker.h
#pragma once
#include <QObject>
#include <qDebug>
class Worker : public QObject
{
Q_OBJECT
public:
Worker();
~Worker();
public slots:
void EatApple();
void EatBanana();
void EatOrange();
private:
};
Worker.cpp
#include "Worker.h"
#include <QThread>
Worker::Worker()
: QObject()
{
}
Worker::~Worker()
{
}
void Worker::EatApple(){
qDebug() << "Apple" << QThread::currentThreadId();
}
void Worker::EatBanana(){
qDebug() << "Banana" << QThread::currentThreadId();
}
void Worker::EatOrange(){
qDebug() << "Orange" << QThread::currentThreadId();
}
QtMoveToThread.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtMoveToThread.h"
#include "Worker.h"
class QtMoveToThread : public QWidget
{
Q_OBJECT
public:
QtMoveToThread(QWidget *parent = Q_NULLPTR);
public slots:
void EatApple();
void EatBanana();
void EatOrange();
private:
Ui::QtMoveToThreadClass ui;
Worker *worker;
};
QtMoveToThread.cpp
#include "QtMoveToThread.h"
#include <QThread>
QtMoveToThread::QtMoveToThread(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
worker = new Worker;
connect(ui.bAppleWorker, SIGNAL(clicked()), worker, SLOT(EatApple()));
connect(ui.bBananaWorker, SIGNAL(clicked()), worker, SLOT(EatBanana()));
connect(ui.bOrangeWorker, SIGNAL(clicked()), worker, SLOT(EatOrange()));
connect(ui.bAppleMain, SIGNAL(clicked()), this, SLOT(EatApple()));
connect(ui.bBananaMain, SIGNAL(clicked()), this, SLOT(EatBanana()));
connect(ui.bOrangeMain, SIGNAL(clicked()), this, SLOT(EatOrange()));
QThread *eatTsk = new QThread; // New 一个QThread
worker->moveToThread(eatTsk); // worker实例化 move进去
eatTsk->start();
}
void QtMoveToThread::EatApple(){
worker->EatApple(); // 主线程调用worker
}
void QtMoveToThread::EatBanana(){
worker->EatBanana(); // 主线程调用worker
}
void QtMoveToThread::EatOrange(){
worker->EatOrange(); // 主线程调用worker
}
运行结果
和子类化QThread对比
优点是克服了重写run的缺点,比较灵活简洁,但是不能在线程里面实现常驻任务(死循环的任务)。
总结
1、常驻任务使用继承QThread重写run
2、其他的一次性任务或者间歇性任务尽量都用moveToThread