столкнулся со следующей проблемой: я не могу сериализовать определенный пользователем объект из 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 );
}
};
Решение состоит в том, чтобы расширить шаблон с помощью конструктора.
SettingsItem()
{
qRegisterMetaType<T>();
qRegisterMetaTypeStreamOperators<T>(T::staticMetaObject.className());
}
и зарегистрировать вложенный тип в конструкторе класса
RegistersSettings()
{
qRegisterMetaTypeStreamOperators<QList<RegisterGroupSettings>>("QList<RegisterGroupSettings>");
}
Других решений пока нет …