2013-08-17 192 views
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,让这些属性公开?我如何重写我的子类中的这些属性?

回答

1

尝试保存所有属性没有意义。

QMetaProperty有很多标志可以帮助您过滤应该保存的属性(应避免非“存储”和非“可写”属性)。请参阅Qt's Property System

例如,属性xywidthheight是非writable,但分别是possize性能,这是writable的部分,但非stored,因为它们本身较大的属性的部分geometry这是您真正需要保存和恢复的唯一一个,您可以检查此属性是否为storedwritable

+0

但是,例如,如果我需要保存坐标:x,y和宽度,高度?因为我需要知道位置等,所以我需要恢复它 – SirLanceloaaat

+0

@SirLanceloaaat我编辑了答案,解释了为什么'存储'和'可写'属性应该足够。 – alexisdm