具有许多项的QML文件中Component.onCompleted的顺序是什么?

时间:2014-07-04 15:06:26

标签: qt qml

例如,请考虑以下代码:

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

或任何其他组合。

3 个答案:

答案 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 ++调用按以下顺序进行:

  1. QQmlComponent::beginCreate()被调用以创建组件。
  2. QQmlObjectCreator::createInstance()被调用以创建组件中的每个项目。
  3. QQmlObjectCreator::createInstance()对于在项内声明的每个子项都递归调用。
  4. 如果子项没有子项,则将其添加到 componentAttached 堆栈中以供以后完成。
  5. 通过各自的QQmlObjectCreator::createInstance()调用创建所有子级之后,父级的QQmlObjectCreator::createInstance()继续执行,并将父级添加到 componentAttached 堆栈中,以供以后完成。
  6. QQmlComponent::beginCreate()呼叫退出。
  7. 调用
  8. QQmlComponent::completeCreate() complete 组件。
  9. componentAttached 堆栈被清空,并在堆栈中弹出每个项目时发出onCompleted

这将强制执行以下顺序:

  1. idRectParent是在QQmlObjectCreator::createInstance()中构造的,子代在函数退出QQmlObjectCreator::createInstance()之前通过对idRectParent的递归调用来开始构造。
  2. idRectChild1完成QQmlObjectCreator::createInstance()并被压入 componentAttached 堆栈。
  3. idRectChild2完成QQmlObjectCreator::createInstance()并被压入 componentAttached 堆栈。
  4. idRectParent完成QQmlObjectCreator::createInstance()并被压入 componentAttached 堆栈。

QQmlComponent::completeCreate()调用QQmlObjectCreator::finalize(),并为每个项目清空 componentAttached 堆栈并发出onCompleted

  1. idRectParent componentAttached 堆栈中弹出,并发出onCompleted信号。
  2. componentAttached 堆栈中弹出
  3. idRectChild2,并发出onCompleted信号。
  4. componentAttached 堆栈中弹出
  5. idRectChild1,并发出onCompleted信号。

无论项目的层次结构有多深,都将保持此顺序:父级先声明,然后子级声明顺序相反。