假设我有两种类型的自定义元素 - 父和子
并且可以在场景中超过一个父
简单的场景看起来像这样:
Parent {
Child {
id: child1
}
Child {
id: child2
}
}
加载场景后,我想初始化Parent类中的所有Children:
void InitializeChildren() {
list = findChildren<Child*>(QString(),Qt::FindChildrenRecursively);
foreach(Child * child,list) {
InitChild(this,child);
}
但它失败了更复杂的场景:
Parent {
Rectangle {
Repeater {
model: 10
delegate: Child {
}
}
}
}
只是因为Repeater没有Childs对象作为孩子。 所以我的问题 - 如果我确切地知道它们是指定父级的嵌套childen,我怎样才能得到所有Child的对象?
答案 0 :(得分:2)
好吧我明白了:
Qt5发生了变化,这使得使用findChildren()
Repeater
个孩子不再可用。看了qquickrepeater.cpp
后,发现Repeater
调用了QQuickItem::setParentItem()
来创建了子代理。因此,原始的父母和孩子保持不受影响,但&#34;视觉&#34; parent是Repeater的父级。
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 objects of type SearchType, recursively searched children of rootItem
将SearchType
替换为您要查找的C ++类型。
注意:相对于findChildren()
的更改,您需要致电childItems()
而不是children()
。理想情况下,QQuickItem
中会有一个模板函数,例如在将来的Qt版本中称为findChildItems()
,它会在内部进行上述递归搜索。
答案 1 :(得分: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;
}