Json结构是类C ++结构(结构或sturcts数组,数组和基本类型)。 我需要将JSON对象转换为具有指定属性的指定QObject(通过QObject字段)。
例如,json:
{
"name": "Andrew",
"age" 33,
"identifiers": [32, 45, 67, 78],
"more": {
"gps": "44.9064', W073° 59.0735'",
"valid": true
}
}
的QObject:
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 );
}
JSON是一个字符串,我需要通过一个模板函数将其转换为FPersonInfo。 有没有已知的算法?
答案 0 :(得分:5)
我自己一直在研究这个问题,到目前为止我有一个非常粗略的实现,遗憾的是根本不支持列表,没有通用的方法来确定列表的类型然后添加内容,如果适合您,您可以硬编码支持您需要的特定列表类型。
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();
}
}
要记住的一点是,您要转换的每个QObject类型都必须有一个标有Q_INVOKABLE
的默认构造函数,在您的情况下使用它可能看起来像这样(假设您将这些方法放入名为Utils
的课程
QString json = QString(); //load json from somewhere
FPersonInfo* person = (FPersonInfo*) Utils::fromJson(FPersonInfo::staticMetaObject, json);
答案 1 :(得分:0)
我将此实现为开放式图书馆:https://github.com/carlonluca/lqobjectserializer。
定义结构:
explicit
完成:
std::vector<int, stateful_allocator<int>> x(stateful_allocator<int>{0});
您还需要像往常一样在元对象系统中注册类型。