2014-02-07 46 views
3

比方說,我有2種自定義元素 - 父母與子女QML直放站parentness

,並可以在現場

簡單的場景看起來像這樣有一個以上的家長:

Parent { 
    Child { 
     id: child1 
    } 
    Child { 
     id: child2 
    } 
} 

經過現場裝載我想初始化所有兒童的父類:

void InitializeChildren() { 
    list = findChildren<Child*>(QString(),Qt::FindChildrenRecursively); 
    foreach(Child * child,list) { 
     InitChild(this,child); 
} 

但更復雜的場景失敗:

Parent { 
    Rectangle { 
     Repeater { 
      model: 10 
      delegate: Child { 
      } 
     } 
    }  
} 

just bacause Repeater沒有Childs對象作爲子項。 所以我的問題 - 如果我確切知道它們是嵌套指定父親的孩子,我如何獲得所有孩子的對象?

回答

0

,而不是分析中繼器,你可以設置模型在你的C++代碼:

Parent { 
    Rectangle { 
     Repeater { 
      model: childModel 
      delegate: Child { 
       Text { text: childValue } 
      } 
     } 
    }  
} 

在C++:

QList<QObject*> m_childModel; 
void InitializeChildren() { 
    this->m_childModel.append(new Child("value 1")); 
    this->m_childModel.append(new Child("value 2")); 
    this->m_scene->rootContext()->setContextProperty("childModel", QVariant::fromValue(m_childModel)); 
} 

還需要加載根QML文件之前做setContextProperty

而且Child聲明:

class Child : public QObject 
{ 
    Q_OBJECT 

public: 
    Child(QString value) : m_value(value) {} 
    Q_PROPERTY(QString childValue READ getChildValue WRITE setChildValue NOTIFY childValueUpdated) 
    // Other properties... 

    QString getChildValue() const { return m_value; } 
    void setChildValue(const QString &value) 
    { 
     if (value == m_value) 
      return; 
     m_value = value; 
     emit childValueUpdated(); 
    } 

signals: 
    void childValueUpdated(); 

private: 
    QString m_value; 

} 
+2

謝謝@Kirween的答案。可能我並不清楚,但我的目的是在QML中創建一些靈活的結構,而不是使用C++。對於普通QML樣式的用戶,添加新的子對象必須是透明的,作爲嵌套塊。子項可以位於Rectangle ot Item或其他任何QML節點中。但所有這些元素都是父母的孩子,不一定是父母的直接子女。可能是孩子的孩子...我需要從這個堆子中取回子節點,但是所有子節點 – folibis

+1

此問題的任何更新?我遇到同樣的問題.. –

+0

+1我也有這個問題... – Avio

1

好吧,我想通了: 有在QT5改變這使得使用findChildren()用於直放站兒童不能使用了。查看qquickrepeater.cpp之後,事實證明Repeater將QQuickItem :: setParentItem()調用到創建的子代理。因此,原始父母和子女保持未觸動,但「視覺」父母是直放站的父母。

TLDR: 請勿在Qt5中使用findChildren()瀏覽項目場景圖。相反,使用類似以下內容:

void getAllSearchTypes(QQuickItem *parent, QList<SearchType *> &list) { 

QList<QQuickItem *> children = parent->childItems(); 
    foreach (QQuickItem *item, children) { 
    SearchType *searchObject = dynamic_cast<SearchType *>(item); 
    if (seachObject) list.append(searchObject); 
    // call recursively and browse through the whole scene graph 
    getAllSearchTypes(item,list); 
} 
} 

並調用這樣的功能:

QList<SearchType *> list; 
getAllSearchTypes(rootItem, list); 
// list now contains all obects of type SearchType, recursively searched children of rootItem 

更換檢索類別與您正在尋找的C++類型。

注意:findChildren()的相關更改是您需要調用childItems()而不是child()。理想情況下,QQuickItem中會有一個模板函數,例如在將來的Qt版本中稱爲findChildItems(),它在內部執行上述遞歸搜索。

+0

+1謝謝,這工作完美。我認爲沒有比這更好的方式了。可能這應該是被接受的答案... – Avio