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

相关推荐
QuantumStack8 分钟前
【C++ 真题】P1104 生日
开发语言·c++·算法
天若有情67320 分钟前
01_软件卓越之道:功能性与需求满足
c++·软件工程·软件
whoarethenext24 分钟前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
Jay_5152 小时前
C++多态与虚函数详解:从入门到精通
开发语言·c++
追风赶月、2 小时前
【QT】事件(鼠标、按键、定时器、窗口)
qt
xiaolang_8616_wjl2 小时前
c++文字游戏_闯关打怪
开发语言·数据结构·c++·算法·c++20
FrostedLotus·霜莲3 小时前
C++主流编辑器特点比较
开发语言·c++·编辑器
牵牛老人5 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
liulilittle7 小时前
深度剖析:OPENPPP2 libtcpip 实现原理与架构设计
开发语言·网络·c++·tcp/ip·智能路由器·tcp·通信
十年编程老舅8 小时前
跨越十年的C++演进:C++20新特性全解析
c++·c++11·c++20·c++14·c++23·c++17·c++新特性