前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >QT学习之如何使用Qthread(moveToThread方法)

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

作者头像
嵌入式小屋
发布2022-04-27 17:01:28
2.1K0
发布2022-04-27 17:01:28
举报

概述

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

文章目录
  • 概述
  • 一.QObject::moveToThread()
  • 二.QObject::moveToThread() 的使用例子

一.QObject::moveToThread()

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

下面是使用代码片段:

代码语言:javascript
复制
   QThread workThread;
   Worker worker = new Worker();
   worker->moveToThread(&workThread);
   workThread.start();

二.QObject::moveToThread()的使用例子

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

1. 首先先写一个继承自QObjectWorker类(为了使用信号和槽).

  • 在worker.h 中声明 doWork 槽函数,以及完成信号
代码语言:javascript
复制
#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
  • 在worker.cpp 中实现 doWork 槽函数
代码语言:javascript
复制
#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+"完成");
 }

2. 写一个控制Woker线程的 Boss

  • Boss.h 中实现
代码语言:javascript
复制
#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
  • Boss.cpp 中实现
代码语言:javascript
复制
#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); //直接调用

}

3. 最后实现main.cpp

代码语言:javascript
复制
#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();
}

4. 结果:

从上面可以看出:

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

下一篇文章将继续写关于QThread 的另一种使用方法

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 文章目录
  • 一.QObject::moveToThread()
  • 二.QObject::moveToThread()的使用例子
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档