当前位置: 首页 > article >正文

Qt 多线程的两种实现方式

Qt 多线程的两种实现方式

1. 从QThread类继承再重写 run 函数

实现流程:

  1. 继承自QThread类
  2. 重写run函数,其中run函数里面的代码为线程的执行代码
  3. 调用start函数启动线程

程序示例:

  • WorkThread.h 文件
#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>

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

public:
    void StartThread();
    void StopThread();
    void TerminateThread();

protected:
    void run() override;				// 重写run函数

private:
    void DealValue(int& nValue);

signals:
    void SignalSendValue(QString, int);

private:
    bool m_bRunFlag;

};

#endif // WORKTHREAD_H

  • WorkThread.cpp 文件
#include "WorkThread.h"
#include <QDebug>

WorkThread::WorkThread(QObject *parent) : QThread(parent), m_bRunFlag(false)
{

}

WorkThread::~WorkThread()
{
    qDebug() << "Release WorkThread!";
}

void WorkThread::StartThread()
{
    m_bRunFlag = true;
    start();
}

void WorkThread::StopThread()
{
    m_bRunFlag = false;
    quit();
    wait();
}

void WorkThread::TerminateThread()
{
    terminate();
    wait();
}

void WorkThread::run()
{
    int nValue = 0;

    while (m_bRunFlag)
    {
        DealValue(nValue);
        Qt::HANDLE hHandle = QThread::currentThreadId();
        emit SignalSendValue(QString::number(reinterpret_cast<quintptr>(hHandle), 16), nValue);
        QThread::msleep(100);
    }
}

void WorkThread::DealValue(int &nValue)
{
    nValue++;

    if (nValue > 100)
        nValue = 1;
}

  • MainWindow.h文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "WorkThread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    void SlotRecieveValue(QString strThreadID, int nValue);

private slots:
    void on_btnStart_clicked();
    void on_btnStop_clicked();
    void on_btnTerminate_clicked();

private:
    Ui::MainWindow *ui;
    WorkThread* m_pWorkThread;
};
#endif // MAINWINDOW_H


  • MainWindow.cpp文件
#include "MainWindow.h"
#include "ui_MainWindow.h"

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

    ui->labelMainThreadID->setText(QString("Thread ID = 0x%1").arg(QString::number(reinterpret_cast<quintptr>(QThread::currentThreadId()), 16)));

    m_pWorkThread = new WorkThread(this);
    connect(m_pWorkThread, &WorkThread::SignalSendValue, this, &MainWindow::SlotRecieveValue);
}

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

void MainWindow::SlotRecieveValue(QString strThreadID, int nValue)
{
    ui->labelValue->setText(QString("Thread ID = 0x%1, Value = %2").arg(strThreadID).arg(nValue));
}


void MainWindow::on_btnStart_clicked()
{
    m_pWorkThread->StartThread();
}

void MainWindow::on_btnStop_clicked()
{
    m_pWorkThread->StopThread();
}

void MainWindow::on_btnTerminate_clicked()
{
    m_pWorkThread->TerminateThread();
}

2. 使用QObject::moveToThread()函数

实现流程:

  1. 创建一个工作类继承自QObject;
  2. 创建一个工作类线程对象和一个QThread对象,调用QObject::moveToThread()将工作对象移至线程中;
  3. 调用QThread对象的start函数,通过发送信号,后续工作对像的槽函数都会在独立的线程中执行;

文字解释流程相对比较抽象,下面看一个基于上面例子改造的示例;

  • ThreadWorker.h 文件 (线程工作者对象)
#ifndef THREADWORKER_H
#define THREADWORKER_H

#include <QObject>

class ThreadWorker : public QObject
{
    Q_OBJECT

public:
    explicit ThreadWorker(QObject *parent = nullptr);
    ~ThreadWorker();

public:
    void SetRunFlag(bool bRunFlag);

public slots:
    void SlotDoWork();          // 槽函数,通过外部的信号关联,其执行会在独立的线程中

private:
    void DealValue(int& nValue);

signals:
    void SignalDoWork();
    void SignalSendValue(QString, int);

private:
    bool m_bRunFlag;
};

#endif // THREADWORKER_H

  • ThreadWorker.cpp 文件
#include "ThreadWorker.h"
#include <QDebug>
#include <QThread>

ThreadWorker::ThreadWorker(QObject *parent) : QObject(parent), m_bRunFlag(false)
{

}

ThreadWorker::~ThreadWorker()
{
    qDebug() << "Release ThreadWorker!";
}

void ThreadWorker::SetRunFlag(bool bRunFlag)
{
    m_bRunFlag = bRunFlag;
}

void ThreadWorker::SlotDoWork()
{
    int nValue = 0;

    while (m_bRunFlag)
    {
        DealValue(nValue);
        Qt::HANDLE hHandle = QThread::currentThreadId();
        emit SignalSendValue(QString::number(reinterpret_cast<quintptr>(hHandle), 16), nValue);
        QThread::msleep(100);
    }
}

void ThreadWorker::DealValue(int &nValue)
{
    nValue++;

    if (nValue > 100)
        nValue = 1;
}

  • MainWindow.h 文件
#ifndef WORKTHREAD_H
#define WORKTHREAD_H

#include <QThread>

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

public:
    void StartThread();
    void StopThread();
    void TerminateThread();

protected:
    void run() override;

private:
    void DealValue(int& nValue);

signals:
    void SignalSendValue(QString, int);

private:
    bool m_bRunFlag;

};

#endif // WORKTHREAD_H

  • MainWindow.cpp 文件
#include "WorkThread.h"
#include <QDebug>

WorkThread::WorkThread(QObject *parent) : QThread(parent), m_bRunFlag(false)
{

}

WorkThread::~WorkThread()
{
    qDebug() << "Release WorkThread!";
}

void WorkThread::StartThread()
{
    m_bRunFlag = true;
    start();
}

void WorkThread::StopThread()
{
    m_bRunFlag = false;
    quit();
    wait();
}

void WorkThread::TerminateThread()
{
    terminate();
    wait();
}

void WorkThread::run()
{
    int nValue = 0;

    while (m_bRunFlag)
    {
        DealValue(nValue);
        Qt::HANDLE hHandle = QThread::currentThreadId();
        emit SignalSendValue(QString::number(reinterpret_cast<quintptr>(hHandle), 16), nValue);
        QThread::msleep(100);
    }
}

void WorkThread::DealValue(int &nValue)
{
    nValue++;

    if (nValue > 100)
        nValue = 1;
}

在这里插入图片描述


http://www.kler.cn/a/612646.html

相关文章:

  • C# 属性(Property)‌详解
  • 南京审计大学:《 面向工程审计行业的DeepSeek大模型应用指南》.pdf(免费下载)
  • LabVIEW IMAQdx相机接口重命名
  • 深入理解建造者模式:从披萨到电商订单系统的优雅设计实践
  • kafka_exporter服务安装并启动
  • 鸿蒙生态圈暗战:数字孪生三强争霸谁将主宰消费电子未来?
  • Docker Hub Mirror 终极解决方案——0成本,超高速!
  • MOSN(Modular Open Smart Network)-08-MOSN 扩展机制解析
  • 如何快速备份你的 API 吗? Postman 批量导出接口
  • 【Git】基础使用
  • 3.17-3.23 Web3 游戏周报:Pixudi 双榜领跑,The Forgotten Runiverse 登陆三大主机平台
  • 智能家居物联网中2.4G芯片的通信协议应用
  • 跨语言语言模型预训练
  • 企业微信实现“关联外部选项“、“审批控件中的外部选项“
  • 食品计算—MetaFood3D: 3D Food Dataset with Nutrition Values
  • 【HTML 基础教程】HTML 编辑器
  • 【Git】git cherry-pick(将某个分支的 commit 改动复制到当前分支)
  • 文件分片上传demo(ant design vue 的a-upload)
  • HarmonyOS:解决UIAbility调用terminateSelf()后设置不保留最近任务列表中的快照
  • 108.在 Vue 3 中使用 OpenLayers 加载 XYZ 地图的示例