在包含很多项的 QML 文件中 Component.onCompleted 的顺序是什么?

问题描述 投票:0回答:3

例如,考虑下面的代码:

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

或任何其他组合。

qt qml
3个回答
10
投票

顺序未定义:

在对象实例化后发出。这可以用来 完整的 QML 环境完成后,在启动时执行脚本代码 成立。

对应的handler是onCompleted。有可能 在任何对象上声明。运行 onCompleted 处理程序的顺序 未定义。

https://doc.qt.io/qt-6/qml-qtqml-component.html#completed-signal


7
投票

顺序是未定义的,但它是有意义的(并且可以凭经验观察),当为一项调用

OnCompleted
方法时,其所有子项都会被实例化并安全访问(并且属性已初始化),即使这些项目的
OnCompleted
事件孩子们还没有被叫到。


6
投票

顺序由 C++ 类规定,对于简单声明,顺序从 Qt 4.8 到 5.15 保持不变。

该示例描述了一个包含项目的 QML 组件。 C++ 调用按以下顺序发生:

  1. QQmlComponent::beginCreate()
    被调用来创建组件。
  2. 调用
  3. QQmlObjectCreator::createInstance()
    来创建组件中的每个项目。
  4. QQmlObjectCreator::createInstance()
    对于项目中声明的每个子项都会递归调用。
  5. 如果子项没有子项,则会将其添加到 componentAttached 堆栈中以供稍后完成。
  6. 通过各自的
    QQmlObjectCreator::createInstance()
    调用创建所有子级后,父级的
    QQmlObjectCreator::createInstance()
    继续执行,并将父级添加到 componentAttached 堆栈中以供稍后完成。
  7. QQmlComponent::beginCreate()
    呼叫退出。
  8. 调用
  9. QQmlComponent::completeCreate()
    完成组件。
  10. 当每个项目从堆栈中弹出时,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. idRectChild2
    componentAttached 堆栈中弹出,并发出
    onCompleted
    信号。
  3. idRectChild1
    componentAttached 堆栈中弹出,并发出
    onCompleted
    信号。

无论项目的层次结构有多深,都会维持此顺序:按照与声明相反的顺序先是父级,然后是子级。

© www.soinside.com 2019 - 2024. All rights reserved.