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

相关推荐
liulilittle33 分钟前
深度剖析:OPENPPP2 libtcpip 实现原理与架构设计
开发语言·网络·c++·tcp/ip·智能路由器·tcp·通信
十年编程老舅1 小时前
跨越十年的C++演进:C++20新特性全解析
c++·c++11·c++20·c++14·c++23·c++17·c++新特性
-凌凌漆-2 小时前
【Qt】QStringLiteral 介绍
开发语言·qt
想要入门的程序猿2 小时前
Qt写入excel
数据库·qt·excel
小刘同学3213 小时前
C++11 特性
c++·c11新特性
真的想上岸啊3 小时前
学习C++、QT---18(C++ 记事本项目的stylesheet)
开发语言·c++·学习
m0_552200823 小时前
《UE5_C++多人TPS完整教程》学习笔记40 ——《P41 装备(武器)姿势(Equipped Pose)》
c++·游戏·ue5
丁劲犇4 小时前
用 Turbo Vision 2 为 Qt 6 控制台应用创建 TUI 字符 MainFrame
开发语言·c++·qt·tui·字符界面·curse
charlie1145141915 小时前
深入理解Qt的SetWindowsFlags函数
开发语言·c++·qt·原理分析