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

相关推荐
weixin_428498491 小时前
Visual Studio 中使用 Clang 作为 C/C++ 编译器时,设置优化选项方法
c语言·c++·visual studio
SunkingYang1 小时前
QT中怎么隐藏或显示最大化、最小化、关闭按钮
qt·关闭按钮·隐藏·显示·最大化按钮·最小化按钮
菜鸡中的奋斗鸡→挣扎鸡1 小时前
第十四届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组
c语言·c++·蓝桥杯
六bring个六1 小时前
QT上位机笔记
开发语言·笔记·qt
步木木1 小时前
Qt 5.14.2入门(一)写个Hello Qt!程序
开发语言·qt
流星白龙3 小时前
【C++算法】50.分治_归并_翻转对
c++·算法
q567315233 小时前
使用libcurl编写爬虫程序指南
开发语言·c++·爬虫
矛取矛求3 小时前
C++ STL 详解 ——list 的深度解析与实践指南
c++·list
杰杰批4 小时前
第十四届蓝桥杯大赛软件赛国赛C/C++研究生组
c语言·c++·蓝桥杯
aaaweiaaaaaa5 小时前
蓝桥杯c ++笔记(含算法 贪心+动态规划+dp+进制转化+便利等)
c语言·数据结构·c++·算法·贪心算法·蓝桥杯·动态规划