序言

如何识别自定义类型,并将自定义类型对象通过信号槽传递给接收对象,需要依靠Q_DECLARE_METATYPE(Type)宏进行修饰,其中你的类必须包含该类型必须有公有的 构造、析构、复制构造 函数,如果想在(queued)信号和槽系统中使用或者想在QObject的属性系统中使用,就必须使用qRegisterMetaType()这个函数注册到元对象系统中,这个在qml中调用C++时常用到。

整理如下:
Q_DECLARE_METATYPE
如果要使自定义类型或其他非QMetaType内置类型在QVaiant中使用,必须使用该宏。
该类型必须有公有的 构造、析构、复制构造 函数

qRegisterMetaType 必须使用该函数的两种情况
如果非QMetaType内置类型要在 Qt 的属性系统中使用
如果非QMetaType内置类型要在 queued 信号与槽 中使用

代码

struct tempInfo
{
    unsigned int tag;
    unsigned int message;
};
Q_DECLARE_METATYPE(tempInfo)    //申明为元对象类型 但是不一定会注册到元对象类型
#ifndef STRUCTTESTPROPERTY_H
#define STRUCTTESTPROPERTY_H

#include <QObject>
#include <QVariantMap>
#include <QMetaObject>

struct tempInfo
{
    unsigned int tag;
    unsigned int message;
};
Q_DECLARE_METATYPE(tempInfo)

class StructTestProperty : public QObject
{
    Q_OBJECT
public:
    struct WeatherInfo
    {
        float tmp;              // 温度
        int day_code;           // 白天天气代码
        QString day_text;       // 白天天气情况
        int night_code;         // 夜间天气代码
        QString night_text;     // 夜间天气情况
    };
    explicit StructTestProperty(QObject *parent = nullptr);
    // 通过QVariantMap 传值
    Q_INVOKABLE QVariantMap getCurrentWeatherInfo();
    //test
    void test();

signals:
    void sendSig(tempInfo tmpInfo);
private:
    // 天气信息
    WeatherInfo m_WeatherInfo;
    //test
    tempInfo m_tempInfo;

};

class JsonPropertyTest: public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString jsonData READ getJsonData WRITE setJsonData)
public:
    explicit JsonPropertyTest(QObject *parent = nullptr);
    QString getJsonData()
    {
        return m_jsonData;
    }
    void setJsonData(const QString &json)
    {
        m_jsonData = json;
    }
 signals:
    void sigSendJsonData(const QString &data);

public slots:
    void onSlotReceive(tempInfo info);
private:
    QString m_jsonData;
};

#endif // STRUCTTESTPROPERTY_H


#include "structtestproperty.h"
#include <QFile>
#include <QDebug>
#include <QJsonParseError>

StructTestProperty::StructTestProperty(QObject *parent)
    : QObject(parent)
{
    m_WeatherInfo.tmp = 23;
    m_WeatherInfo.day_code = 100;
    m_WeatherInfo.day_text = QString(u8"晴");
    m_WeatherInfo.night_code = 200;
    m_WeatherInfo.night_text = QString(u8"小雨");
    JsonPropertyTest* m_ptest = new JsonPropertyTest;
    connect(this,SIGNAL(sendSig(tempInfo)),m_ptest,SLOT(onSlotReceive(tempInfo)));
    test();
}

QVariantMap StructTestProperty::getCurrentWeatherInfo()
{
    QVariantMap map;
    map.clear();
    map.insert("tmp", m_WeatherInfo.tmp);
    map.insert("day_code", m_WeatherInfo.day_code);
    map.insert("day_text", m_WeatherInfo.day_text);
    map.insert("night_code", m_WeatherInfo.night_code);
    map.insert("night_text", m_WeatherInfo.night_text);
    return map;
}

void StructTestProperty::test()
{
    QVariant temp1;
    m_tempInfo.tag = 0;
    m_tempInfo.message = 20;
    temp1 = QVariant::fromValue(m_tempInfo);

    //
    tempInfo info;
    info = temp1.value<tempInfo>();
    qDebug()<<" test tag= "<<info.tag;
    qDebug()<<" test message= "<<info.message;

    emit sendSig(m_tempInfo);
}


JsonPropertyTest::JsonPropertyTest(QObject *parent)
    :QObject(parent)
{
    QFile loadFile("E:\\program\\Test\\Test\\TestPropertyQML\\QMLPropertyTest\\test.json");
    if(!loadFile.open(QIODevice::ReadOnly))
    {
        qDebug()<<"Could't open json data file!";
    }
    QByteArray allData = loadFile.readAll();
    loadFile.close();
    QJsonParseError json_error;
    QJsonDocument jsonDoc(QJsonDocument::fromJson(allData, &json_error));
    if(json_error.error != QJsonParseError::NoError)
    {
        qDebug() << "Parse json error!";
        return;
    }
    m_jsonData = QString::fromLocal8Bit(allData);
    //将Json格式标定数据以QString的形式传给QML界面,这里的callQmlLoadCali是一个带QString参数的信号,这里为了方便直接用了读取的数据,
    //如果是QJsonObject的话也可先转成QJsonDocument,再转成QString
    //    emit sigSendJsonData(QString::fromLocal8Bit(allData));
}

void JsonPropertyTest::onSlotReceive(tempInfo info)
{
    qDebug() << __FUNCTION__;
    qDebug()<<" test tag= "<<info.tag;
    qDebug()<<" test message= "<<info.message;
}

结果:
在这里插入图片描述

如果将代码注释

struct tempInfo
{
    unsigned int tag;
    unsigned int message;
};
//Q_DECLARE_METATYPE(tempInfo)

则在编译过程中会报如下错误
在这里插入图片描述

参考博客:
https://blog.csdn.net/res518357/article/details/51387578
https://blog.csdn.net/unclerunning/article/details/70282298
https://blog.csdn.net/weixin_30546933/article/details/96978804
https://blog.csdn.net/ipfpm/article/details/88699398

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐