Qt主线程获取子线程中自定义类型的数据

0x00 本文通过子线程产生的数据传递给主程,需要掌握如下知识

  •  <QMetaType>,向Qt的元对象系统中注册用户自定义数据类型。
  • <QThread>,创建子线程处理数据分担界面主线程占用的资源。
  • signal & slot 利用带参数的信号与槽来传递子线程到主线程的数据,信号槽机制是Qt最大的特色功能,用于实例对象之间的通信;信号和槽都是成员函数,绑定一个对象的信号和另一个对象的槽函数,当前者发射出信号时,与之相对应的会触发后者的槽函数,这样两个对象间就完成了一次通信过程。

0x01 创建用户自定义结构体类型,并向Qt元对象系统声明该类型

  •  以下代码声明了一个自定义的结构体类型。
  • TransData结构体类型已经声明好了,要想在Qt某个类(一般是用户从Qt类中继承过来的类)中使用,还必须得注册该类型即qRegisterMetaType<TransData>("TransData");
//workthread.h

#ifndef USERDEFINE_H
#define USERDEFINE_H

#include <QMetaType>    //Qt元类型系统头文件
struct TransData{
    bool checkNework;
};

Q_DECLARE_METATYPE(TransData)

#endif // USERDEFINE_H

0x02 创建子线程,用自定义的结构体接收产生的数据

  •  由于当前的子线程类中需要用到自定义的结构体类型,所以我们必须得在该类中注册要使用的自定义结构体类型,在子线程的构造函数中注册 TransData 数据类型。
  • 我们需要把子线程中产生的数据传递给主线程,就要使用信号与槽机制,利用带参数的信号与槽进行传递数据,所以需要在子线程中声明一个信号,并在线程的任务函数中发射信号。
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
#include <QProcess>
#include "UserDefine.h"

class WorkThread : public QThread
{
    Q_OBJECT
public:
    WorkThread();
    ~WorkThread();

signals:
    void sigTransData(TransData data); //自定义信号

private:
    void run() override;
    TransData data;
};

#endif // WORKTHREAD_H
#include "workthread.h"
#include <QDebug>

WorkThread::WorkThread()
{
    //注册自定义结构体数据类型
    qRegisterMetaType<TransData>("TransData");
}

WorkThread::~WorkThread()
{
    qDebug() << __func__ << ":" << QThread::currentThreadId() << endl;
}

void WorkThread::run()
{
    if(QProcess::execute("ping 127.0.0.1 -w 1") == 0){
        data.checkNework = true;
        emit sigTransData(data);
    }else{
        data.checkNework = false;
        emit sigTransData(data);
    }
}

 0x03 在主线程中使用子线程产生的数据

  •  我们要接收来自子线程产生的数据,需要声明并定义一个带参数的槽函数接收数据并处理数据。
  • 下面代码中用到了Label控件和Push Button控件。
#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include "workthread.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWidget; }
QT_END_NAMESPACE

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = nullptr);
    ~MainWidget();

private slots:
    void slotShowNetworkStatus(TransData data); //自定义槽函数
    void on_btnStart_clicked();

private:
    Ui::MainWidget *ui;
    WorkThread* workThread;
};
#endif // MAINWIDGET_H
#include "mainwidget.h"
#include "ui_mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MainWidget)
{
    ui->setupUi(this);
    ui->lblNetworkStatus->setText("");
    ui->btnStart->setText("start");

    workThread = new WorkThread();
    //关联信号和槽
    connect(workThread, &WorkThread::sigTransData, this, &MainWidget::slotShowNetworkStatus);
}

MainWidget::~MainWidget()
{
    delete ui;
    delete workThread; //未指定父对象,手动销毁内存
}

void MainWidget::slotShowNetworkStatus(TransData data)
{
    if(data.checkNework == true){
        ui->lblNetworkStatus->setText("网络正常!!!");
    }else{
        ui->lblNetworkStatus->setText("网络存在故障!!!");
    }
}

void MainWidget::on_btnStart_clicked()
{
    if(ui->btnStart->text() == "start"){
        workThread->start();
        ui->btnStart->setText("stop");
    }else{
        workThread->terminate();
        ui->btnStart->setText("start");
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晓琴儿

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值