Автосериализация с использованием Qt Meta Property System - PullRequest
0 голосов
/ 12 сентября 2018

Когда у меня есть свой собственный тип со стандартными свойствами типов 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, используя только конструкторы, операторы присваивания и систему свойств Qt (также Q_DECLARE и qRegister)?

Мои попытки можно найти здесь:

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, реализуйте эти операторы и используйте как любые другие объекты для сериализации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...