2013-08-21 66 views
0

我試圖製作讀取xml文件並從這個xml反序列化各種qt控件的代碼,並且我使用QDomDocument來做這件事,並且我想從我的deserealization方法中獲取QLlist。而且有一點麻煩的IM,這裏是模板類的一些代碼文件(.h):Qt QMetaObjects和從QWidget轉換爲QObject

QList<T*> deserialize(QIODevice *input) 
{ 

     QList<T*> objects = QList<T*>(); 


     if(_deserializeObject(input, objects)) 
      return objects; 

    } 
    bool _deserializeObjects(QIODevice* input, QList<QObject*>& list); 

,並與反序列化方法我.cpp文件,這裏我可是從文件中讀取控制標籤:

bool Serializer::_deserializeObjects(QIODevice* input, QList<QObject *> &objects) 
{ 
    QDomDocument doc; 
    if (!doc.setContent(input)) 
     return false; 
    QDomElement root= doc.documentElement(); 

    for(int j = 0; j < root.childNodes().length();j++) 
    { 


     QObject* object; 
     qDebug() << root.tagName(); 
     if(root.tagName().contains("QGroupBox")) // <------- Here i need to determine which control i need to process. 
     { 
      ???? 
     } 

     qDebug() << object->metaObject()->className(); 
     qDebug() << object->metaObject()->propertyCount(); 

    for(int i = 0; i < object->metaObject()->propertyCount(); i++) 
    { 

     object->metaObject()->cast() 

     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(); 

       if(propName == "x") 
       { 
        x = v.toInt(); 
       } 
       else if(propName == "y") 
       { 
        y = v.toInt(); 
       } 
       else if(propName == "width") 
       { 
        width = v.toInt(); 
       } 
       else if(propName == "height") 
       { 
        height = v.toInt(); 
       } 
       if(propName == "geometry") 
       { 
        continue; 

       } 
       object->setProperty(propName.toLatin1().data(), QVariant(v)); 


    } 
    object->setProperty("geometry",QVariant(QRect(x,y,width,height))); 
    objects.push_back(object); 

    } 
    return true; 
} 

在這部分

if(root.tagName().contains("QGroupBox")) // <------- Here i need to determine which control i need to process. 
      { 
       ???? 
      } 

      qDebug() << object->metaObject()->className(); 
      qDebug() << object->metaObject()->propertyCount(); 

     for(int i = 0; i < object->metaObject()->propertyCount(); i++) 
     { 
      ... 
     } 

我想實際某種方式得到通過名稱控件的類型,所以問題是,我可以投QGroupBox到QObject的保存QGroupBox屬性,這樣的QObject元對象CLA SS名稱將是QGroupBox,所以我可以傳遞所有這些屬性?因爲我不想爲每種控件類型製作循環。此外,我當我得到的結果如下所示:

 QList<QObject *> ds = s.deserialize<Object>((QIODevice*)&f); 

我可以那麼就通過所有的QObject在一個循環中,並使用QMetaObject類的名稱,並使用qobject_cast每個對象轉換爲QPushButton,QLabel等?

回答

1

QGroupBox是QObject的子類;因此每個QGroupBox也是一個QObject,所以你可以把它當作你喜歡的一個。明確的轉換不是必需的。如果您對它們調用的方法是虛擬方法(它們大概會是這樣 - 特別是QObject :: QObject ::),那麼循環遍歷循環中的所有不同對象派生自QObject將會做你想做的事情。 metaObject()是一個虛擬方法,因此即使通過QObject指針調用方法,您的循環也會得到相應的QMetaObject。) (另外,進程的惱人的部分可能是你從XML讀取對象類型名稱的部分,現在需要實例化該類型的對象。AFAIK沒有好的自動在C++中做這件事的方法是,所以你可以做的最好的工廠函數是一個包含巨大開關語句的工廠函數,每個類型可能都需要實例化一個單獨的案例)。

+0

Soo它應該是這樣的? if(nodeName.contains(「QPushButton」)) QPushButton * btn = new QPushButton(); object = btn; }' – SirLanceloaaat

+0

也許更喜歡:QObject * obj = NULL; if(nodeName ==「QPushButton」)obj = new QPushButton; else if(nodeName ==「QGroupBox」)obj = new QGroupBox; else [ –

+0

]我還有一個問題,我可以以某種方式在另一個線程中創建反序列化的對象嗎? ui線程中的反序列化會因爲循環等原因而凍結我的UI。是否有可能以某種方式在另一個線程中創建QPushButton/QLabel,然後將它們分配給我的gui? – SirLanceloaaat

0

或者,使用正確的工具進行正確的工作。機會是,你是真的這裏建立的是一些XML的東西,用於定義小部件佈局等Qt已經有一個工具,Qt Designer它使用UI定義的XML format和C++ code generator實際上生產C++代碼編譯時間。

+0

訣竅是,當我的程序工作時,我想從服務器動態加載我的xml到程序中。 – SirLanceloaaat