Сериализует вложенный пользовательский класс из Q_PROPERTY в QT

Столкнулся со следующей проблемой: я не могу сериализовать определенный пользователем объект из Q_PROPERTY, я пытаюсь сериализовать класс RegistersSettings в QDataStream. Идея состоит в том, чтобы иметь возможность сериализовать его в текстовый файл (с помощью оператора <<), а затем прочитать его (с помощью оператора >>). Следует проверить, что поля, которые были прочитаны из файла, все еще действительны. Поэтому я проверяю собственность для этого. Проблема в том, что Q_PROPERTY(группы MLBER групп QList) не работает должным образом. Похоже, что возможно создать такую ​​функциональность, но, похоже, это не так просто. Может ли кто-нибудь помочь с распространенным способом, как сериализовать пользовательский класс из Q_PROPERTY?

Код упрощен, чтобы быть более читабельным, но основная идея на месте.

class RegisterGroupSettings:SettingsItem<RegisterGroupSettings>
{
private:
    Q_GADGET
    Q_PROPERTY(QString name MEMBER name)
    Q_PROPERTY(int interval MEMBER interval)

public:
    QString name;
    int     interval;
};
Q_DECLARE_METATYPE(RegisterGroupSettings)

class RegistersSettings:SettingsItem<RegistersSettings>
{
private:
    Q_GADGET
    Q_PROPERTY(QList<RegisterGroupSettings> groups MEMBER groups)
    Q_PROPERTY(int code MEMBER code)

public:
    QList<RegisterGroupSettings> groups;
    int code;
};
Q_DECLARE_METATYPE(RegistersSettings)

SettingsItem - помощник для объединения

template <typename T> class SettingsItem
{
public:
    friend QDataStream & operator << (QDataStream &arch, const T & object)
    {
        const QMetaObject &mo = object.staticMetaObject;
        int cnt = mo.propertyCount();
        QString prop_name;
        QVariant prop_value;
        arch << cnt;
        while (cnt>0)
        {
            prop_name = mo.property(cnt-1).name();
            prop_value = mo.property(cnt-1).readOnGadget(&object);
            arch << prop_name;
            arch << prop_value;
            cnt--;
        }
        return arch;
    }

    friend QDataStream & operator >> (QDataStream &arch, T & object)
    {
        const QMetaObject &mo = object.staticMetaObject;
        int cnt=0;
        QString prop_name;
        QVariant prop_value;
        int prop_index;
        arch >> cnt;
        while (cnt>0)
        {
            arch >> prop_name;
            arch >> prop_value;
            prop_index = mo.indexOfProperty(prop_name.toStdString().c_str());
            if (prop_index > -1)
            {
                mo.property(prop_index).writeOnGadget(&object, prop_value);
            }
            cnt--;
        }
        return arch;
    }

    friend bool operator == (const T &first, const T &second)
    {
        const QMetaObject &mo = first.staticMetaObject;
        int cnt = mo.propertyCount();
        QString prop_name;
        QVariant oProp_value;
        QVariant dProp_value;
        while (cnt>0)
        {
            prop_name = mo.property(cnt-1).name();
            oProp_value = mo.property(cnt-1).readOnGadget(&first);
            dProp_value = mo.property(cnt-1).readOnGadget(&second);
            if (oProp_value == dProp_value)
            {
                cnt--;
                continue;
            }
            return false;
        }

        return true;
    }

    friend bool operator != (const T &first, const T &second)
    {
        return !( first == second );
    }
};

1 ответ

Решение

Решение состоит в том, чтобы расширить шаблон с помощью конструктора.

SettingsItem()
{
    qRegisterMetaType<T>();
    qRegisterMetaTypeStreamOperators<T>(T::staticMetaObject.className());
}

и зарегистрировать вложенный тип в конструкторе класса

RegistersSettings()
{
    qRegisterMetaTypeStreamOperators<QList<RegisterGroupSettings>>("QList<RegisterGroupSettings>");
}
Другие вопросы по тегам