Qt 多线程的两种实现方式
Qt 多线程的两种实现方式
1. 从QThread类继承再重写 run 函数
实现流程:
- 继承自QThread类
- 重写run函数,其中run函数里面的代码为线程的执行代码
- 调用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()函数
实现流程:
- 创建一个工作类继承自QObject;
- 创建一个工作类线程对象和一个QThread对象,调用QObject::moveToThread()将工作对象移至线程中;
- 调用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;
}