0
我試着做一個簡單的控制serealization /反序列化,我想出了下面的代碼(的.cpp)Qt的覆蓋類屬性
#include "serializer.h"
#include "QMetaProperty"
#include "QTextStream"
#include "QDebug"
Serializer::Serializer(QObject *parent) :
QObject(parent)
{
}
bool Serializer::Serialize(QObject *object,QString name) {
QDomDocument doc;
QDomElement root = doc.createElement(object->metaObject()->className());
doc.appendChild(root);
for(int i = 0; i < object->metaObject()->propertyCount(); i++)
{
QMetaProperty prop = object->metaObject()->property(i);
QString propName = prop.name();
if(propName == "objectName")
continue;
QDomElement el = doc.createElement(propName);
QVariant value = object->property(propName.toLatin1().data());
QDomText txt;
if (object->metaObject()->property(i).typeName() != "QByteArray") {
txt = doc.createTextNode(value.toString());
} else {
txt = doc.createTextNode(object->metaObject()->property(i).typeName());
}
el.appendChild(txt);
root.appendChild(el);
}
QFile f(name);
f.open(QIODevice::ReadWrite | QIODevice::Text);
QTextStream stream(&f);
doc.save(stream, 2);
f.close();
return true;
}
bool Serializer::_deserializeObject(QIODevice* input, QObject* object)
{
QDomDocument doc;
if (!doc.setContent(input))
return false;
QDomElement root = doc.documentElement();
qDebug() << object->metaObject()->propertyCount();
for(int i = 0; i < object->metaObject()->propertyCount(); i++)
{
QMetaProperty prop = object->metaObject()->property(i);
QString propName = prop.name();
if(propName == "objectName")
continue;
QDomNodeList nodeList = root.elementsByTagName(propName);
if(nodeList.length() < 1)
continue;
QDomNode node = nodeList.at(0);
QVariant value = object->property(propName.toLatin1().data());
QString v = node.toElement().text();
object->setProperty(propName.toLatin1().data(), QVariant(v));
}
return true;
}
.h文件中:
#ifndef SERIALIZER_H
#define SERIALIZER_H
#include <QObject>
#include <QDomDocument>
#include <QFile>
class Serializer : public QObject
{
Q_OBJECT
public:
explicit Serializer(QObject *parent = 0);
bool Serialize(QObject *object, QString name);
template<class T>
T* deserialize(QIODevice *input)
{
T* object = new T();
if(_deserializeObject(input, object))
return object;
delete object;
return NULL;
}
bool _deserializeObject(QIODevice* input, QObject* object);
signals:
public slots:
};
#endif // SERIALIZER_H
所以以後我連載例如一些按鈕,XML文件我想要反序列化,我做它像這樣:
QFile f(fname);
f.open(QIODevice::ReadOnly);
QPushButton *ds = s.deserialize<QPushButton>(&f);
f.close();
調試輸出使我對轉換
setProperty: Property "modal" invalid, read-only or does not exist
setProperty: Property "frameGeometry" invalid, read-only or does not exist
setProperty: Property "normalGeometry" invalid, read-only or does not exist
setProperty: Property "x" invalid, read-only or does not exist
setProperty: Property "y" invalid, read-only or does not exist
setProperty: Property "frameSize" invalid, read-only or does not exist
setProperty: Property "width" invalid, read-only or does not exist
setProperty: Property "height" invalid, read-only or does not exist
setProperty: Property "rect" invalid, read-only or does not exist
setProperty: Property "childrenRect" invalid, read-only or does not exist
setProperty: Property "childrenRegion" invalid, read-only or does not exist
setProperty: Property "isActiveWindow" invalid, read-only or does not exist
setProperty: Property "focus" invalid, read-only or does not exist
所以我的問題很多屬性的錯誤的,是有辦法以某種方式做正確的轉換,或者我應該繼承QPushButton,讓這些屬性公開?我如何重寫我的子類中的這些屬性?
但是,例如,如果我需要保存座標:x,y和寬度,高度?因爲我需要知道位置等,所以我需要恢復它 – SirLanceloaaat
@SirLanceloaaat我編輯了答案,解釋了爲什麼'存儲'和'可寫'屬性應該足夠。 – alexisdm