QT学习之如何使用Qthread(moveToThread方法)

概述

​ 通常在程序中需要同时做好几件事情,这时不可避免的会涉及到多线程的学习,QT学习过程中亦是如此,而QT中提供了 QThread,因为涉及到信号与槽,线程的使用也有些变化。在QThread的文档中有两种使用方法。

一.QObject::moveToThread()的使用

​ 这个是第一种方式,直接调用 QObject::moveToThread() 函数,将继承自 QObject 的对象移到线程里面。此时该对象的 槽函数运行在另一个线程里面。 也就是说,当有信号绑定到该对象的槽函数的时候,并发送信号,该槽函数就运行在另一个线程里,否则该函数仍然运行在对象所在的线程中.

下面将参照文档,举一个例子来说明线程的使用并验证上述说法(可直接先看下面结果,再看过程):

  • 首先先写一个继承自QObjectWorker类(为了使用信号和槽).
  1. 在worker.h 中声明 doWork 槽函数,以及完成信号
#include <QObject>
class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr);
    Worker(QString name , QObject *parent = nullptr);

signals:
    void resultReady(const QString &resultReady); //工作完成信号

public slots:
    void doWork(const QString &parameter); //工作函数

private:
    QString name;
};

#endif // WOKER_H
  1. 在worker.cpp 中实现 doWork 槽函数
#include "worker.h"
#include <QDebug>
#include <QThread>
Worker::Worker(QObject *parent) : QObject(parent)
{

}

Worker::Worker(QString name , QObject *parent )
{
    this->name = name;
}

void Worker::doWork(const QString &parameter)
{
    qDebug()<<"当前Worker线程ID:"<<QThread::currentThreadId()	
    <<endl<<name + "正在"+ parameter<<endl;
    emit resultReady(name + parameter+"完成");
}
  • 写一个控制Woker线程的 Boss
  1. Boss.h 中实现
#ifndef BOSS_H
#define BOSS_H

#include <QObject>
#include <QThread>
#include "worker.h"
class Boss : public QObject
{
    Q_OBJECT
public:
    explicit Boss(QObject *parent = nullptr);
    ~Boss();
    void order2(const QString order); //用于测试是否使用了线程

signals:
    void order(const QString order); //用于测试是否使用了线程

public slots:
    void handleResult(const QString result);\
private:
    QThread workThread; //worker 线程
    Worker *worker;		//worker 对象指针 
};

#endif // BOSS_H
  1. Boss.cpp 中实现
#include "boss.h"
#include <QDebug>
Boss::Boss(QObject *parent) : QObject(parent)
{
    worker = new Worker("A");
    worker->moveToThread(&workThread);
    connect(&workThread, &QThread::finished, worker, &QObject::deleteLater);
    connect(this, &Boss::order, worker, &Worker::doWork); //用信号和槽的方式调用doWork()函数
    connect(worker, &Worker::resultReady, this, &Boss::handleResult);
    workThread.start();
}
Boss::~Boss()
{
    workThread.quit();
    workThread.wait();
}

void Boss::handleResult(const QString result)
{
   qDebug()<<"Boss got it :"<<result<<endl;

}

void Boss::order2(const QString order)
{
   qDebug()<<"order2:";
   worker->doWork(order); //直接调用

}
  • 最后实现main.cpp
#include <QCoreApplication>
#include <boss.h>
#include <QDebug>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug()<<"当前Boss线程ID:"<<QThread::currentThreadId()<<endl;
    Boss *boss = new Boss();
    boss->order("整理资料(order)");//用信号触发槽函数的方式
    boss->order2("整理资料(order2)");//直接调用函数的方式
    return a.exec();
}
  • 结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qX8yqhrJ-1616320379008)(./image/moveToThread测试结果.png)]

从上面可以看出:

  1. order2 是通过直接调用doWork 的函数,该函数会直接执行在调用对象所在线程
  2. order 是通过信号触发doWork 函数,工作在新的线程中。
  • 使用moveToThread总结:
    1. worker 对象的函数要工作在其他线程,要通过信号和槽的方式进行调用

项目代码已上传,欢迎下载!
后续也将分享QT的学习,欢迎点赞,关注,赞赏我!

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_33974167

有价值,请赏瓶水喝

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值