QML Repeater父母

时间:2014-02-07 09:02:24

标签: c++ qml qt-quick qtquick2

假设我有两种类型的自定义元素 - 父和子

并且可以在场景中超过一个父

简单的场景看起来像这样:

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的对象?

2 个答案:

答案 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;

}