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;
}
相关推荐
jf加菲猫5 小时前
第15章 文件和目录
开发语言·c++·qt·ui
清风玉骨10 小时前
C++/Qt从零开始编译使用libxlsxwriter库
开发语言·qt
jingshaoqi_ccc11 小时前
使用QT6创建一个可编辑的表格并导出和载入
c++·qt·表格
机器视觉知识推荐、就业指导1 天前
Qt:真正的门槛不是入门,而是维护
开发语言·qt
米优1 天前
qgis电子地图二次开发---比例尺
qt·qgis
雾岛听蓝1 天前
Qt操作指南:状态栏、浮动窗口与对话框使用
开发语言·经验分享·笔记·qt
楚Y6同学1 天前
QT C++之保存界面设置为配置文件
c++·qt·保存配置
Ulyanov1 天前
《PySide6 GUI开发指南:QML核心与实践》 第十篇:综合实战——构建完整的跨平台个人管理应用
开发语言·python·qt·ui·交互·qml·雷达电子战系统仿真
-凌凌漆-1 天前
【QML】QQmlEngine::setObjectOwnership()的作用
qt