使用Qt元属性系统进行自动序列化

时间:2018-09-12 20:29:16

标签: json qt serialization

当我的自定义类型具有标准的Qt类型属性时,可以执行以下操作:

for (int i = metaObject()->propertyOffset(); i < metaObject()->propertyCount(); i++) {
    auto key = metaObject()->property(i).name();
    setProperty(key, other.property(key));
}

我还可以使用接受 QJsonObject QVariant 和其他任何非显式类型的构造函数创建自己的类型。您可以输入QJsonObject json = MyType();]

我已经实现了 QVariant 构造函数,因为other.property(key)返回了 QVariant 。我希望它能起作用。

我也可以创建这种类型的运算符,例如

virtual operator const QVariant() const {...}

virtual operator const QJsonObject() const {...}

但是,如果我将自定义类与Q_PROPERTY(MyType....)一起使用,则不能只使用本文开头的循环。

所以,问题是:如何仅使用构造函数,赋值运算符和Qt属性系统(以及Q_DECLAREqRegister)来实现通用Qt序列化系统?

我的尝试可以在这里找到

https://gitlab.com/luntik2012/goodies/blob/master/rfproperty.h

示例序列化类:

class Test : public QObject
{
    Q_OBJECT

    Q_PROPERTY(QString name READ name NOTIFY nameChanged)

public:
    Test() = default;
    Test(const QJsonObject &json)
        : QObject()
    {
        // just imagine it will work dynamically. I have my own macro performing this
        for(int i = staticMetaObject.propertyOffset(); i < metaObject()->propertyCount(); i++)
        {
            auto key = metaObject()->property(i).name();
            setProperty(key, json[key]);
        }
    }

    // The same thing as in Json constructor, just shotrened the snippet
    Test(const Test &other) : QObject() { Q_UNUSED(other); }

public:
    Test& operator =(const Test &other) {
        for(int i = staticMetaObject.propertyOffset(); i < metaObject()->propertyCount(); i++)
        {
            auto key = metaObject()->property(i).name();
            setProperty(key, json[key]);
        }
        return *this;
    }

    Test& operator =(const QVariant &variant) {
        *this = variant.value<Test>();
        return *this;
    }

signals:
    void nameChanged();

public:
    Q_INVOKABLE QString name() const { return m_name; }

    virtual operator const QJsonObject() const {
        return QJsonObject { { "name", m_name } };
    }

    virtual operator const QVariant() const {
        return QVariant(Test::operator const QJsonObject());
    }

private:
    QString m_name;
};
Q_DECLARE_METATYPE(Test)

现在您可以想象同一个类,比如说Check,但是它具有Test属性而不是QString。我只想写

QJsonObject json;
json = Check(...);

它适用于标准类型,但我不知道该如何处理自己的

完全,我想使用这样的“操作符QJsonObject”来序列化QObject中的任何类型。例如,继承QList,实现这些运算符,并用作序列化的任何其他对象

0 个答案:

没有答案