Qt中使用线程之moveToThread

步骤:

1、创建一个自定义Worker类,继承自QObject

2、主线程中创建QThread的对象,Worker类的对象

3、Worker类的对象调用moveToThread函数移动到QThread的对象中

4、主线程自定义一个信号,并使用信号槽连接到worker类对象的任务函数

5、启动线程

6、主线程发射自定义的信号,触发worker类对象的任务函数,这个函数就会在子线程中执行

7、找一个合适的时机或位置完成线程的退出和清理

如下面的例子

点击按钮,ui发射自定义信号,触发Worker的工作函数(工作在子线程中),然后Worker发射信号,主线程更新Label的值

cpp 复制代码
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QThread>
#include<QLabel>
#include<QPushButton>

class Worker:public QObject
{
    Q_OBJECT
public:
    Worker()=default;
    ~Worker()=default;


    //工作函数,在这个函数中编写业务逻辑
    void doWork()
    {
        //打印下线程id,看和主线程的线程id是否一样
        qDebug()<<"工作函数所在线程:"<<QThread::currentThreadId();
        int num=0;
        while(!stop)
        {
            //num循环自增,然后发射改变的信号
            emit changeString(QString::number(num++));
            QThread::msleep(500);
        }
    }

    //终止循环,结束工作函数
    void Stop()
    {
        stop=true;
    }
signals:
    void changeString(QString text);

private:
    bool stop=false;
};

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr): QWidget(parent)
    {
        qDebug()<<"UI界面所在线程:"<<QThread::currentThreadId();
        resize(400,300);
        QLabel* info=new QLabel("我是Label",this);
        QFont font;
        font.setPixelSize(18);
        font.setBold(true);
        info->setFont(font);
        info->setGeometry(10,20,400,100);

        QPushButton* btn=new QPushButton("更新Label",this);
        btn->setGeometry(10,140,100,30);


        //创建辅助线程,
        QThread* th=new QThread(this);

        //创建任务类,不能指定父指针为this,否则还是会在当前线程
        Worker* worker=new Worker;
        //移动到线程
        worker->moveToThread(th);

        //绑定worker发射的信号,来更新ui界面的label
        connect(worker,&Worker::changeString,this,[=](QString text){
            info->setText("当前num的值:"+text);
        });

        //绑定自定义的triggerWork信号,来触发worker的工作函数,工作函数就会在子线程中执行
        connect(this,&Widget::triggerWork,worker,&Worker::doWork);

        //绑定窗口的destroyed信号,窗口关闭时结束掉线程
        connect(this,&Widget::destroyed,this,[=](){
            worker->Stop();//终止工作函数
            th->exit();//线程退出事件循环
            th->wait();//等待线程退出
            qDebug()<<"线程退出了";
        });

        //点击按钮,发射triggerWork信号,通过信号来触发前面绑定的工作函数
        //(只能通过信号槽,用信号来触发工作函数,才会子线程中执行)
        connect(btn,&QPushButton::clicked,this,&Widget::triggerWork);


        //手动启动线程
        th->start();

    }

    ~Widget()=default;


signals:
    //自定义一个信号
    void triggerWork();
};
#endif // WIDGET_H

官方案例:QThread Class | Qt Core 5.15.17

相关推荐
mlidongfeng23 分钟前
[AI][C++26] SIMD 编程模型思考
开发语言·c++·人工智能
梓䈑24 分钟前
【用 Vibe Coding 实现的 C++17 在线判题系统】OpenCode 入门指南:从环境搭建到上下文管理
c++·ai编程
j7~24 分钟前
【Linux】二十七.线程篇四《Linux多线程编程:线程互斥(互斥量的底层到封装)、线程安全和冲入、死锁》---详解
linux·开发语言·c++·线程安全·死锁·线程互斥·重入
啦啦啦啦啦zzzz31 分钟前
贪心算法和动态规划
c++·算法·贪心算法·动态规划
我不是懒洋洋1 小时前
从零实现一个分布式数据集成:Airbyte的核心设计
c++
用户0510122572961 小时前
DAY 5-智能指针与 C++ 内存管理
c++·面试
(Charon)1 小时前
【C++】手写 MySQL 连接池(三):异步任务队列与工作线程
c语言·c++
Quz1 小时前
QML Tumbler 基础用法:多滚轮选择与自定义外观
qt
Quz1 小时前
QML SpinBox 动画效果:缩放反馈与数字滚动
qt
yyds_yyd_100861 小时前
877. 石子游戏(2026.08.02)& 486. 预测赢家(2026.08.01)
c++·leetcode