Qt 多线程的两种实现方式

Qt 多线程的两种实现方式

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

实现流程:

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

程序示例:

  • WorkThread.h 文件
cpp 复制代码
#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 文件
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文件
cpp 复制代码
#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文件
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 文件 (线程工作者对象)
cpp 复制代码
#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 文件
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 文件
cpp 复制代码
#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 文件
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;
}
相关推荐
编码小笨猪23 分钟前
[ C++ ] | C++11 从左值引用到右值引用
开发语言·c++
jk_10131 分钟前
MATLAB中rmfield函数用法
开发语言·matlab
m0_5557629033 分钟前
单例模式(Singleton Pattern)
开发语言·javascript·单例模式
无影无踪的青蛙1 小时前
[Python] 贪心算法简单版
开发语言·python·贪心算法
yufei-coder1 小时前
配置Next.js环境 使用vscode
开发语言·javascript·vscode·next.js
电科_银尘1 小时前
【Matlab】-- 基于MATLAB的飞蛾扑火算法与反向传播算法的混凝土强度预测
开发语言·算法·matlab
wen__xvn2 小时前
Codeforces Round 1014 (Div. 2)2092A - Kamilka and the Sheep c++
开发语言·c++·算法
编程之升级打怪2 小时前
自定义C语言变量转换库
c语言·开发语言
_乐多_2 小时前
python:将mp4视频快进播放,并保存新的视频
开发语言·python·音视频