Qt下多线程的实现

目前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;
}

最终效果世界线探测器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值