1. 程式人生 > >利用qt 訊號槽傳遞自定義結構體--藉助QVariant

利用qt 訊號槽傳遞自定義結構體--藉助QVariant

在前面的部落格裡,我介紹了利用Q_DECLARE_METATYPE和qRegsterMetaType來傳遞自定義的結構體。但是這樣做有個缺點:qRegisterMetaType()只能在main()函式裡才能發揮作用。https://blog.csdn.net/Kelvin_Yan/article/details/70054282介紹了利用QVariant來傳遞自定義結構體的辦法。有了這個辦法,即使不在main()函式裡呼叫qRegisterMetaType也能傳遞自定義資料。

建立一個工程,包含兩個窗體:MainWindow和Emitter。兩者通過訊號sigVarnt()和槽OnRecvVarnt()傳遞QVariant,而QVariant實際上是一個自定義結構體。當MainWIndow::OnRecvVarnt()接收到訊號之後,會將QVariant重新轉化為結構體,並顯示在介面上。

標頭檔案:

#ifndef PROTOCOL_H
#define PROTOCOL_H

#include <QMetaType>

#pragma pack(push, 1)
#if !defined(DEF_ST_DUMMY)
typedef struct ST_DUMMY
{
    int i;
    float f;
    char arr[10];
} ST_DUMMY;

Q_DECLARE_METATYPE(ST_DUMMY)
#define DEF_ST_DUMMY
#endif

#pragma pack(pop)
#endif // PROTOCOL_H

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QVariant>
#include "emitter.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    Emitter         m_emitter;
public slots:
    void            OnRecvVarnt(QVariant);
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
#ifndef EMITTER_H
#define EMITTER_H

#include <QWidget>
#include <QVariant>

class Emitter : public QWidget
{
    Q_OBJECT
public:
    explicit Emitter(QWidget *parent = 0);

signals:
    void     sigVarnt(QVariant);
public slots:
    void     OnTrigger(void);
};

#endif // EMITTER_H

cpp檔案:

#include "emitter.h"
#include "protocol.h"

Emitter::Emitter(QWidget *parent) : QWidget(parent)
{

}

void Emitter::OnTrigger(void)
{
    ST_DUMMY stDummy;
    stDummy.i = 1;
    //char * p = "huii"
    memcpy(stDummy.arr, "abd", strlen("abd"));
    stDummy.f = 8.9;

    QVariant varnt;
    varnt.setValue(stDummy);
    emit sigVarnt(varnt);
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "protocol.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    connect(&m_emitter, SIGNAL(sigVarnt(QVariant)), this, SLOT(OnRecvVarnt(QVariant)));
    connect(ui->Btn, SIGNAL(clicked()), &m_emitter, SLOT(OnTrigger()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::OnRecvVarnt(QVariant vnrt)
{
    ST_DUMMY stDummy = vnrt.value<ST_DUMMY>();
    QString qstrMsg = QString("i = %1, f = %2, arr = %3").arg(stDummy.i, 10).arg(stDummy.f).arg(QString(stDummy.arr));
    ui->label->setText(qstrMsg);
}

效果:

點選pushubutton之後,介面上顯示出了stDummy的三個成員的取值: