例如,请考虑以下代码:
Rectangle {
id: idRectParent
Rectangle {
id: idRectChild1
component.onCompleted: {
console.log("Iam Child 1")
}
}
Rectangle {
id: idRectChild2
component.onCompleted: {
console.log("Iam Child 2")
}
}
component.onCompleted : {
console.log("Iam parent Rect")
}
}
如果我在qmlscene
中运行它,我会得到以下输出(我已经尝试了近50次)。
Iam parent Rect
Iam Child 2
Iam Child 1
为什么输出按以上顺序排列,而不是:
Iam parent Rect
Iam Child 1
Iam Child 2
或
Iam Child 1
Iam Child 2
Iam parent Rect
或任何其他组合。
答案 0 :(得分:5)
订单未定义:
组件“启动”完成后发出。这可以用来 一旦完整的QML环境,在启动时执行脚本代码 建立的。
相应的处理程序是onCompleted。有可能 在任何对象上声明。运行onCompleted处理程序的顺序 未定义。
http://qt-project.org/doc/qt-5/qml-qtqml-component.html#completed-signal
答案 1 :(得分:1)
顺序是未定义的,但它是有意义的(并且可以凭经验观察),当为一个项调用OnCompleted
方法时,它的所有子项都被实例化并且可以安全地访问(并且属性已初始化),即使{{ 1}}这些孩子的事件尚未被召唤。
答案 2 :(得分:1)
顺序由C ++类决定,对于简单的声明,顺序从Qt 4.8到5.15保持不变。
该示例描述了包含项目的QML组件。 C ++调用按以下顺序进行:
QQmlComponent::beginCreate()
被调用以创建组件。QQmlObjectCreator::createInstance()
被调用以创建组件中的每个项目。QQmlObjectCreator::createInstance()
对于在项内声明的每个子项都递归调用。QQmlObjectCreator::createInstance()
调用创建所有子级之后,父级的QQmlObjectCreator::createInstance()
继续执行,并将父级添加到 componentAttached 堆栈中,以供以后完成。QQmlComponent::beginCreate()
呼叫退出。QQmlComponent::completeCreate()
来 complete 组件。onCompleted
。这将强制执行以下顺序:
idRectParent
是在QQmlObjectCreator::createInstance()
中构造的,子代在函数退出QQmlObjectCreator::createInstance()
之前通过对idRectParent
的递归调用来开始构造。idRectChild1
完成QQmlObjectCreator::createInstance()
并被压入 componentAttached 堆栈。idRectChild2
完成QQmlObjectCreator::createInstance()
并被压入 componentAttached 堆栈。idRectParent
完成QQmlObjectCreator::createInstance()
并被压入 componentAttached 堆栈。 QQmlComponent::completeCreate()
调用QQmlObjectCreator::finalize()
,并为每个项目清空 componentAttached 堆栈并发出onCompleted
:
idRectParent
从 componentAttached 堆栈中弹出,并发出onCompleted
信号。idRectChild2
,并发出onCompleted
信号。idRectChild1
,并发出onCompleted
信号。无论项目的层次结构有多深,都将保持此顺序:父级先声明,然后子级声明顺序相反。