QT实现线程4种方法

QT实现线程4种方法

  • QThread:重、长生命周期、独立线程、一直跑
  • moveToThread:最推荐、最安全、Qt 官方标准写法
  • QRunnable+QThreadPool:轻量任务、自动销毁、线程池、不能随便发信号
  • QtConcurrent:最简单、一行代码跑异步、适合批量计算

QRunnable+QThreadPool

  • 任务型线程,不是线程本身

  • 丢进线程池,自动分配线程

  • 任务执行完 自动删除

  • 优点:轻、快、省资源

  • 缺点:

    默认不是 QObject,不能直接发信号

    不适合长周期轮询(100ms 一直跑)

QRunnable 自带的行为,不需要你手动写 delete task,没有内存泄露风险

1、把 task 加入任务队列QThreadPool

2、在线程中执行 task->run ()

3、run () 执行完 → 自动 delete task

c 复制代码
#ifndef TASKRUNNABLE_H
#define TASKRUNNABLE_H

#include <QRunnable>
#include <QThreadPool>
#include <QDebug>

class TaskRunnable : public QRunnable
{
public:
    // 必须声明构造函数
    TaskRunnable(){}

    ~TaskRunnable(){
        qDebug() << "~TaskRunnable called";
    }

    TaskRunnable(int taskId);

    // 必须重写 run()
    void run() override;

private:
    int m_taskId;
};

#endif // TASKRUNNABLE_H
bash 复制代码
#include "taskrunnable.h"

TaskRunnable::TaskRunnable(int taskId) : m_taskId(taskId)
{

}

void TaskRunnable::run()
{
    qDebug() << "Running task" << m_taskId << "in thread:" << QThread::currentThreadId();

    // 模拟任务执行
    for (int i = 0; i < 30; ++i) {
        qDebug() << "Task" << m_taskId << "step" << i;
        QThread::msleep(50);
    }

    qDebug() << "Task" << m_taskId << "completed";
}
bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "taskrunnable.h"

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

    QThreadPool *pool = QThreadPool::globalInstance();
    qDebug() << "Max thread count:" << pool->maxThreadCount();

    TaskRunnable *task = new TaskRunnable();
    pool->start(task);  // 任务完成后自动删除

    /*
     * QRunnable 自带的行为,不需要你手动写 delete task,没有内存泄露风险
        1、把 task 加入任务队列QThreadPool
        2、在线程中执行 task->run ()
        3、run () 执行完 → 自动 delete task
    */
}

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

QThread

自定义QThread继承至QThread,重写run方法,子线程处理逻辑放在run方法中。

完全控制线程生命周期,适合长时间运行的任务

bash 复制代码
#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QObject>
#include <QThread>
#include <QDebug>

class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr) : QThread(parent) {}

protected:
    void run() override {
        qDebug() << "Thread started:" << QThread::currentThreadId();

        for (int i = 0; i < 10; ++i) {
            qDebug() << "Processing in thread:" << i;
            msleep(100);  // 模拟工作
        }

        qDebug() << "Thread finished:" << QThread::currentThreadId();
    }
};

#endif // MYTHREAD_H
bash 复制代码
#include "mainwindow.h"
#include "mythread.h"
#include "ui_mainwindow.h"

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

    // 1. 直观易懂,类似传统线程编程
    // 2. 完全控制线程生命周期
    // 3. 适合长时间运行的任务
    // 4. 可以重写run()方法自定义行为

    MyThread thread;
    thread.start();
    thread.wait();  // 等待线程完成
}

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

moveToThread

  • 把一个 普通 QObject 类丢进子线程
  • 所有函数、变量、槽函数 全部自动进子线程
  • 信号槽安全、跨线程没问题
  • 线程一直跑,不销毁
  • 优点:
    结构清晰
    信号槽完美
    长生命周期
    不阻塞 UI
    适合一直运行的后台任务(PLC 轮询、串口、网口)
bash 复制代码
#ifndef WORKER_H
#define WORKER_H

#include <QObject>
#include <QDebug>
#include <QThread>

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

public slots:
    void doWork() {
        qDebug() << "Worker started in thread:" << QThread::currentThreadId();

        for (int i = 0; i < 10; ++i) {
            qDebug() << "Worker processing:" << i;
            QThread::msleep(100);
        }

        emit workFinished();
    }

signals:
    void workFinished();
};

#endif // WORKER_H
bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "worker.h"

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

    // 使用moveToThread的方式
    Worker *worker = new Worker;
    QThread *workerThread = new QThread;

    worker->moveToThread(workerThread);

    //将线程创建后并start开启线程,发送started信号,触发子线程doWork具体处理逻辑
    QObject::connect(workerThread, &QThread::started, worker, &Worker::doWork);
    //子线程处理结束后发送workFinished信号,通知线程quit退出
    QObject::connect(worker, &Worker::workFinished, workerThread, &QThread::quit);
    //工作完成后安全删除Worker对象
    QObject::connect(worker, &Worker::workFinished, worker, &QObject::deleteLater);
    //线程结束后安全删除QThread对象
    QObject::connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);

    workerThread->start();
}

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

QtConcurrent

QT += concurrent # QtConcurrent 必须加这个模块

1、QtConcurrent::run执行具体子线程处理逻辑

2、QFutureWatcher监控子线程任务完成状态

3、QFutureWatcher链接QFutureWatcher::finished子线程结束信号进行进一步处理

bash 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private:
    int calcFunction();


private slots:
    // 任务完成后回到主线程更新UI
    void onTaskFinished(int result);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
bash 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtConcurrent>  // 必须包含
#include <QFuture>       // 接收返回值
#include <QFutureWatcher> // 监听任务完成
#include <QThread>

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

    // 一行代码启动子线程
    QFuture<int> future = QtConcurrent::run(this, &MainWindow::calcFunction);

    // 监听任务完成
    QFutureWatcher<int> *watcher = new QFutureWatcher<int>(this);
    watcher->setFuture(future);

    // 任务完成 → 自动调用槽函数(主线程安全更新UI)
    connect(watcher, &QFutureWatcher<int>::finished, this, [=]() {
        onTaskFinished(watcher->result());
        watcher->deleteLater(); // 自动释放
    });
}

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

int MainWindow::calcFunction()
{
    qDebug() << "计算运行在线程:" << QThread::currentThread();

    // 模拟耗时任务(比如读取文件、网络、计算)
    QThread::msleep(1000);

    return 100;
}

void MainWindow::onTaskFinished(int result)
{
    qDebug() << "任务完成,结果:" << result;
}
相关推荐
用户805533698032 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 小时前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz5 天前
QML Hello World 入门示例
qt
xcyxiner8 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner9 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner9 天前
DicomViewer (添加模型类)3
qt
xcyxiner10 天前
DicomViewer (目录调整) 2
qt
xcyxiner10 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能12 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G12 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt