QT中多线程实现的三种方式

QT中多线程实现的三种方式

在Qt中经常会遇到耗时操作,需要并发执行,建立线程的主要目的就是为了用线程来处理那些耗时的后台操作

基类Widget

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

struct WidgetPrivate;

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
    struct WidgetPrivate *p;
};

#endif // WIDGET_H

第一种方式:继承QThread 重写run方法

需要定义一个新类,继承QThread,并且重写QThread类的run()方法,在run()方法中实现线程所需要处理的逻辑代码

generate.h

#ifndef GENERATE_H
#define GENERATE_H

#include <QThread>
#include <QObject>

class Generate : public QThread
{
    Q_OBJECT
public:
    explicit Generate(QObject *parent = nullptr);

signals:
    void GenerateFinished(std::vector<int> NumList);

protected:
    void run();
};

#endif // GENERATE_H

generate.cpp

#include "generate.h"

#include <QDebug>
#include <vector>
#include<QThread>

Generate::Generate(QObject *parent):QThread(parent)
{

}

void Generate::run()
{
//    qDebug()<<"生成随机数:"<<QThread::currentThread();
    std::vector<int> NumList;
    for(int i=0; i<100000; i++)
    {
       NumList.push_back(qrand()%100000);
    }
    emit GenerateFinished(NumList);
}

Widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QPushButton>
#include <QThreadPool>
#include "generate.h"

struct WidgetPrivate
{

};

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),p(new WidgetPrivate)
{
    ui->setupUi(this);

    //第一种方式  继承QThread 重写run方法
    Generate *g = new Generate;
    connect(ui->pushButton,&QPushButton::clicked,[=](){
        g->start();
    });

    //插入ListWidget
    connect(g,&Generate::GenerateFinished,[=](std::vector<int> NumList){
        for(int i=0; i<NumList.size(); i++)
            ui->listWidget->addItem(QString::number(NumList[i]));
    });
}

Widget::~Widget()
{
    delete ui;
    delete p;
}

注意,不要直接调用 UI 相关的操作

第二种方式:继承QObject,movetothread

该方式是通过继承 QObject并使用 movetothread 函数将对象移到指定线程中。这种方式允许你将任务逻辑放在一个单独的类中,然后将该类对象移动到新线程中执行。

movetothread.h

#ifndef MOVETOTHREAD_H
#define MOVETOTHREAD_H

#include <QObject>


class MoveToThread : public QObject
{
    Q_OBJECT
public:
    explicit MoveToThread(QObject *parent = nullptr);
    void Generate();

signals:
    void GenerateFinished(std::vector<int>NumList);

public slots:
};

#endif // MOVETOTHREAD_H

movetothread.cpp

#include "movetothread.h"

#include<QThread>
#include<QDebug>

MoveToThread::MoveToThread(QObject *parent) : QObject(parent)
{

}

void MoveToThread::Generate()
{
    qDebug()<<"生成随机数:"<<QThread::currentThread();
    std::vector<int>NumList;
    for(int i=0;i<100000;i++)
    {
        NumList.push_back(qrand()%100000);
    }
    emit GenerateFinished(NumList);
}

Widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QPushButton>
#include "movetothread.h"

struct WidgetPrivate
{

};

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),p(new WidgetPrivate)
{
    ui->setupUi(this);

    //第二种 继承QObject,movetothread
    QThread *t = new QThread;
    MoveToThread *m = new MoveToThread;

    //把整个类的对象都放到线程中
    m->moveToThread(t);

    //选择执行Generate
    connect(t,&QThread::started,[=]()
    {
        m->Generate();
    });
    //启动线程
    connect(ui->pushButton,&QPushButton::clicked,[=]()
    {
        t->start();
    });
    connect(m,&MoveToThread::GenerateFinished,[=](std::vector<int> NumList){
        for(int i=0; i<NumList.size(); i++)
            ui->listWidget->addItem(QString::number(NumList[i]));
    });
}

Widget::~Widget()
{
    delete ui;
    delete p;
}

第三种方式:使用QT的 QThreadPool 类, 继承QRunnable,重写run函数

QThreadPool可以管理多个线程,并且在线程中运行QRunnable对象的任务,更加灵活

poolgenerate.h

#ifndef POOLGENERATE_H
#define POOLGENERATE_H

#include <QObject>
#include <QWidget>
#include <QRunnable>
#include <vector>

class PoolGenerate : public QObject,public QRunnable
{
    Q_OBJECT
public:
    explicit PoolGenerate(QObject *parent = nullptr);
    void run() override;
signals:
    void GenerateFinished(std::vector<int>NumList);

public slots:
};

#endif // POOLGENERATE_H

poolgenerate.cpp

#include "poolgenerate.h"
#include<QDebug>
#include<QThread>

PoolGenerate::PoolGenerate(QObject *parent) : QObject(parent)
{

}

void PoolGenerate::run()
{
    qDebug()<<"生成随机数:"<<QThread::currentThread();
    std::vector<int>NumList;
    for(int i=0;i<100000;i++)
    {
        NumList.push_back(qrand()%100000);
    }
    emit GenerateFinished(NumList);
}

Widget.cpp

#include "widget.h"
#include "ui_widget.h"

#include <QPushButton>
#include <QThreadPool>
#include "poolgenerate.h"

struct WidgetPrivate
{

};

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget),p(new WidgetPrivate)
{
    ui->setupUi(this);

    //第三种 使用QT的 QThreadPool 类, 继承QRunnable,重写run函数
    PoolGenerate *pool = new PoolGenerate;
    connect(ui->pushButton,&QPushButton::clicked,[=]()
    {
        QThreadPool::globalInstance()->start(pool);
    });
    connect(pool,&PoolGenerate::GenerateFinished,[=](std::vector<int>NumList)
    {
        for(int i=0;i<NumList.size();i++)
        {
            ui->listWidget->addItem(QString::number(NumList[i]));
        }
    });
}

Widget::~Widget()
{
    delete ui;
    delete p;
}

三种方式的运行结果:

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值