2014-02-07 24 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