目前Qt实现多线程有两种方法
1:继承QThrea
2:继承QObject
官方推荐的做法是继承QObject的写法
1.创建一个继承QObject的线程类。
2.实现线程函数,即开销比较大的一些过程。
3.创建线程类对象。
4.创建一个QThread类的子线程对象。
5.利用moveToThread()将自己创建的线程类对象移入QThread类的子线程对象。
下面是一个继承了QObject的多线程实例,其功能为:创建两个线程,进行世界线探测(即生成一个小数点后六位的随机数)
newthread.h文件
#ifndef NEWTHREAD_H
#define NEWTHREAD_H
#include <QObject>
#include<QTime>
#include <QThread>
#include<QTimerEvent>
class Detector1 : public QObject
{
Q_OBJECT
public:
explicit Detector1(QObject *parent = nullptr);
double res;
QTime time;
public slots:
void detection();
signals:
void finished(double result);
};
class Detector2 : public QObject
{
Q_OBJECT
public:
explicit Detector2(QObject *parent = nullptr);
double res;
public slots:
void detection();
signals:
void finished(double result);
private:
QTime time;
};
class Controller1 : public QObject
{
Q_OBJECT
QThread detectorthread;
public:
explicit Controller1(QObject *parent = nullptr);
//QThread detectorthread;
Detector1* detector1;
virtual void timerEvent(QTimerEvent *event);
public slots:
void action();
signals:
private:
int timerid;
};
class Controller2 : public QObject
{
Q_OBJECT
QThread detectorthread;
public:
explicit Controller2(QObject *parent = nullptr);
//QThread detectorthread;
Detector2* detector2;
public slots:
void action();
signals:
};
#endif // NEWTHREAD_H
这里模仿官方实例实现了worker类和controller类,因此可以在controller类里面实现一些资源回收的绑定,利用deleteLater可以实现线程安全的资源回收。
newthread.c文件
#include "newthread.h"
#include<QTime>
#include<QDebug>
#include <QThread>
#define TIMER_OUT 2*1000
Detector1::Detector1(QObject *parent) : QObject(parent)
{
}
Detector2::Detector2(QObject *parent) : QObject(parent)
{
}
Controller1::Controller1(QObject *parent) : QObject(parent)
{
detector1=new Detector1;
connect(&detectorthread,&QThread::finished,detector1,&QObject::deleteLater);
detector1->moveToThread(&detectorthread);
detectorthread.start();
}
Controller2::Controller2(QObject *parent) : QObject(parent)
{
detector2=new Detector2;
connect(&detectorthread,&QThread::finished,detector2,&QObject::deleteLater);
detector2->moveToThread(&detectorthread);
detectorthread.start();
}
//世界线变化率探测1
void Detector1::detection()
{
time=QTime::currentTime();
qsrand(time.msec()+time.minute()*1000);
res=(qrand()%9000+(qrand()%8+1)*10000)*10;
res=(res+qrand()%9+1)*0.000001;
emit finished(res);
}
//世界线变化率探测2
void Detector2::detection()
{
time=QTime::currentTime();
qsrand(time.msec()*100000+time.minute()*1000);
res=(qrand()%9000+(qrand()%8+1)*10000)*10;
res=(res+qrand()%9+1)*0.000001;
emit finished(res);
}
void Controller1::timerEvent(QTimerEvent *event)
{
if(event -> timerId()==timerid)
{
if(detector1->time.second()%5==0)
{
detector1->detection();
detector1->detection();
detector1->detection();
}
else
{
detector1->detection();
}
}
}
//控制器1
void Controller1::action()
{
timerid=this->startTimer(TIMER_OUT);
}
//控制器2
void Controller2::action()
{
detector2->detection();
}
widget.cpp文件
#include "widget.h"
#include "ui_widget.h"
#include <QThread>
#include"newthread.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//lcd set
ui->lcdNumber->setStyleSheet("border: 1px solid green; color: red; background: silver;");
ui->lcdNumber->setDigitCount(8);
ui->lcdNumber_2->setStyleSheet("border: 1px solid green; color: red; background: silver;");
ui->lcdNumber_2->setDigitCount(8);
ui->lcdNumber->display("0.000000");
ui->lcdNumber_2->display("0.000000");
//set thread
Controller1* c1=new Controller1;
Controller2* c2=new Controller2;
connect(ui->pushButton,&QPushButton::clicked,c1,&Controller1::action);
connect(ui->pushButton,&QPushButton::clicked,c2,&Controller2::action);
connect(c1->detector1,&Detector1::finished,[&](double res){
ui->lcdNumber->display(res);
});
connect(c2->detector2,&Detector2::finished,[&](double res){
ui->lcdNumber_2->display(res);
});
}
Widget::~Widget()
{
delete ui;
}
最终效果