Qt两种线程QtThread实现方法

Qt两种线程实现方法

方法一基于Qt版本4

创建一个类,继承于QThread类,重写run函数。

// 1. 创建一个子类,继承于QThread
class MyThread : public QThread {
    // ...
};

// 2. 重写父类中的 run() 方法,该函数主要实现要,要处理复杂业务逻辑。
class MyThread : public QThread {
protected:
    void run();
};

// 3. 在主线程中创建一个子线程对象
MyThread *myThread = new MyThread(this);

// 4. 启动子线程
myThread->start();

使用这种方法子线程没办法直接调用界面部件类的控件需要使用信号与槽机制

threadwidget.h

#ifndef THREADWIDGET_H
#define THREADWIDGET_H

#include <QThread>

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

protected:
    virtual void run() override;

signals:
    void isDone();

};


#endif // THREADWIDGET_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

threadwidget.cpp

#include "threadwidget.h"

#include <QDebug>

ThreadWidget::ThreadWidget(QObject *parent)
    : QThread{parent}
{

}

/**
 * @brief 子线程的程序入口
 * 注意:子线程没办法直接访问界面部件类的
 */
void ThreadWidget::run() {

    qDebug() << QThread::currentThreadId();
    QThread::sleep(5);
    qDebug() << "子线程ID : " << QThread::currentThreadId();

    emit isDone();

    return ;
}

widget.cpp

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

#include "threadwidget.h"

#include <QTimer>
#include <QThread>

#include <QDebug>

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

#if 0
    QTimer *timer = new QTimer(this);
    static int i = 0;
    connect(timer, &QTimer::timeout, this, [=](){
        ui->label->setNum(i++);
    });

    connect(ui->pushButton, &QPushButton::clicked, this, [=](){
        // 判断计时器有没有开启
        if(!timer->isActive()) timer->start(500);

        // 模拟一个复杂的处理, 5s
        QThread::sleep(5);
//        timer->stop();
    });
#endif

    // 创建线程对象
    ThreadWidget *thread = new ThreadWidget(this);

    QTimer *timer = new QTimer(this);
    static int i = 0;
    connect(timer, &QTimer::timeout, this, [=](){
       ui->label->setNum(i++);
    });

    connect(ui->pushButton, &QPushButton::clicked, this, [=](){
        if(!timer->isActive()) {
            timer->start(500);
            // 开启子线程
            thread->start();
        }
        qDebug() << "主线程的ID" << QThread::currentThreadId();
    });

    // 通过信号与槽机制修改窗口控件
    connect(thread, &ThreadWidget::isDone, this, [=](){
        if(timer->isActive())timer->stop();
    });

    // 窗口关闭的话关闭线程
    connect(this, &QWidget::destroyed, this, [=](){

        // 等待子线程处理完成后才能退出
        thread->quit();
        thread->wait();

    });
}

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

方法一基于Qt版本5

创建一个类,继承于QObject类,将此类移动到线程中运行。

// 1. 创建一个类,继承于QObject
class MyThread : public QObject {
    // ...
};

// 2. 在此类中添加公共的成员函数,此函数体就是要执行的业务逻辑
class MyThread : public QObject {
public:
    void handler();
};

// 3. 在主线程中创建一个 QThread 对象
QThread *sub = new QThread(this);
// 4. 在主线程中创建一个工作对象,不允许指定父对象
MyThread *work = new MyThread;
// 5. 将创建好的 sub 对象移动到 word 对象中
work->moveToThread(sub);
// 6. 启动子线程,还需要调用handler函数,才能运行work线程
sub->start();
connect(this, &Widget::startThread, work, &MyThread::fun, Qt::QueuedConnection);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值