如何将json对象转换为QObject? JSON结构是C++结构体(Struts、数组和基本类型的结构或数组)。 我需要将JSON对象转换为具有指定属性的指定QObject(通过QObject字段)

如何将json对象转换为QObject? JSON结构是C++结构体(Struts、数组和基本类型的结构或数组)。 我需要将JSON对象转换为具有指定属性的指定QObject(通过QObject字段),c++,json,qt,serialization,reflection,C++,Json,Qt,Serialization,Reflection,例如,json: { "name": "Andrew", "age" 33, "identifiers": [32, 45, 67, 78], "more": { "gps": "44.9064', W073° 59.0735'", "valid": true } } 质量目标: class FMoreInfo : public QObject { Q_OBJECT Q_PROPERTY( QString gps ); Q_PROPE

例如,json:

{
  "name": "Andrew",
  "age" 33,
  "identifiers": [32, 45, 67, 78],
  "more": {
     "gps": "44.9064', W073° 59.0735'",
     "valid": true
  }
}
质量目标:

class FMoreInfo : public QObject {
   Q_OBJECT

   Q_PROPERTY( QString gps );
   Q_PROPERTY( bool valid );
}

class FPersonInfo : public QObject {
   Q_OBJECT

   Q_PROPERTY( QString name );
   Q_PROPERTY( int32 age );
   Q_PROPERTY( QVector<int32> identifiers );
   Q_PROPERTY( FMoreInfo more );

}
class FMoreInfo:public QObject{
Q_对象
Q_属性(QString gps);
Q_属性(bool有效);
}
FPersonInfo类:公共QObject{
Q_对象
Q_属性(QString名称);
Q_地产(int32 age);
Q_属性(QVector标识符);
Q_财产(FMoreInfo更多);
}
JSON是一个字符串,我需要通过一个模板函数将其转换为FPersonInfo。
有已知的算法吗?

我自己也在研究这个问题,到目前为止,我已经得到了一个非常粗略的实现,不幸的是它根本不支持列表,没有通用的方法来确定列表的类型,然后再向其添加内容,如果这对您有用,您可以硬编码支持您需要的特定列表类型

QObject* Utils::fromJson(const QMetaObject& meta, QString& json)
{
    auto jsonObject = QJsonDocument::fromJson(json.toLatin1()).object();
    return fromJson(&meta, jsonObject);
}

QObject* Utils::fromJson(const QMetaObject* meta, QJsonObject& jsonObject)
{
    QObject* object = meta->newInstance();

    int propertyStart = QObject::staticMetaObject.propertyCount();
    for (int i = propertyStart; i < meta->propertyCount(); ++i) {
        QMetaProperty property = meta->property(i);
        if (!property.isWritable())
            continue;
        if (!jsonObject.contains(property.name()))
            continue;

        auto value = jsonValueToProperty(object, property, jsonObject.value(property.name()));
        property.write(object, value);
    }
    return object;
}

QVariant Utils::jsonValueToProperty(QObject* object, QMetaProperty& property, QJsonValue value)
{
    auto type = property.userType();
    auto typeName = QString(property.typeName());
    if (value.isArray()) {
        //todo array
    } else if (value.isObject()) {
        switch (type) {
        default:
            auto jsonObject = value.toObject();
            return QVariant::fromValue(fromJson(QMetaType::metaObjectForType(type), jsonObject));
            break;
        }
        //todo other meta object types
    } else {
        //primitive types
        return value.toVariant();
    }
}

我将其实现为一个开放库:

定义结构:

L_BEGIN_CLASS(FMoreInfo)
L_RW_PROP(QString, gps, setGps)
L_RW_PROP(bool, valid, setValid)
L_END_CLASS

L_BEGIN_CLASS(FPersonInfo)
L_RW_PROP(QString, name, setName)
L_RW_PROP(int, age, setAge)
L_RW_PROP(QList<int>, identifiers, setIdentifiers)
L_RW_PROP(FMoreInfo*, more, setMore)
L_END_CLASS
L_开始课程(FMoreInfo)
L_RW_道具(QString、gps、setGps)
L_RW_PROP(bool、valid、setValid)
最后一节课
L_BEGIN_类(FPersonInfo)
L_RW_PROP(QString、name、setName)
L_RW_道具(整数、年龄、设置)
L_RW_PROP(QList、标识符、setIdentifiers)
L_RW_道具(FMoreInfo*,更多,设置更多)
最后一节课
完成:

ld序列化器反序列化器(工厂);
QScopedPointer g(反序列化器.反序列化(jsonString));

您还需要像往常一样在元对象系统中注册类型。

为什么不使用Qt framework提供的数据类型?@mvidelgauz我已经生成了用于操作的数据类型。我不知道QJsonObject,但我需要直接处理对象的字段:
Obj->more->gps
,换句话说,QJsonObject是隐式对象,我需要显式对象。因此,您是否可以解析json并添加到对象?如果您需要像
gps
这样的已生成成员,我认为除了生成QObject源之外,没有其他方法code@mvidelgauz在Unreal Engine 4中,我可以使用
TFieldIterator
按结构\类属性进行迭代并更改它们(通过使用类型转换,如果属性可以转换为指定的,那么我可以更改它们).Qt对象没有任何类似的方法?抱歉,我不熟悉虚幻引擎,但对我来说,使用动态属性可以实现您的目标。有一种方法可以避免在属性定义中使用额外的代码吗?如果每个qproperty都存在反射信息,为什么我不能在循环中枚举这些属性?尽管这似乎是不可能的在qt框架中运行时确定内部容器类型(如QMap、QList)还是我错了?你指的是什么“额外代码”?我指的是L_RW_PROP宏。只是代码样式:想看看经典的QObject类定义,带有Q_属性,没有额外的Q_可调用函数(如所讨论的示例)要更改名称吗?重新定义它。在我的示例中,我没有看到任何Q_可调用函数。
L_BEGIN_CLASS(FMoreInfo)
L_RW_PROP(QString, gps, setGps)
L_RW_PROP(bool, valid, setValid)
L_END_CLASS

L_BEGIN_CLASS(FPersonInfo)
L_RW_PROP(QString, name, setName)
L_RW_PROP(int, age, setAge)
L_RW_PROP(QList<int>, identifiers, setIdentifiers)
L_RW_PROP(FMoreInfo*, more, setMore)
L_END_CLASS
LDeserializer<FPersonInfo> deserializer(factory);
QScopedPointer<FPersonInfo> g(deserializer.deserialize(jsonString));