2013-08-17 252 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