QML 在堆栈视图中的不同页面中共享组件的一个实例

QML share one instance of a component in different pages in a stackview

在 QML 中,我有一个组件 (id: sharedComponent) 的实例,我想在 StackView 中管理的两个 QML Page 中使用它。但是,sharedComponent 仅在 StackView 中激活 page1 时才可见,即,一旦 page2 被推到 StackView 上,蓝色矩形就会消失。

如何在 QML 中 share/use/see 多个页面中的组件实例?

MyPage.qml

Page {
    default property alias mainContent: mainContent.data

    Item {
        id: mainContent
        anchors.fill: parent
    }
}

main.qml

ApplicationWindow {
    id: window
    width: 640
    height: 480
    visible: true

    Rectangle {
        id: sharedComponent
        anchors.fill: parent
        color: "blue"
        // in my actual software, this shared component would contain a Scene3D here
    }

    MyPage {
        id: page1
        mainContent: sharedComponent
    }
    MyPage {
        id: page2
        mainContent: sharedComponent
    }

    StackView {
        id: stackView
        initialItem: page1
        anchors.fill: parent
    }

    Button {
        text: "Switch Page"
        anchors.centerIn: parent
        onClicked: {
            if(stackView.depth>1) {
                stackView.pop()
            } else {
                stackView.push(page2)
            }
        }
    }
}

为了共享对象,需要重新设置共享对象的父级。当一个不同的 MyPage 实例变得可见时,它需要成为 sharedObject 的父级。因此,启动可见设置为 false 的页面。

MyPage.qml:

Page {
    property Item mainContent

    Item {
        id: container
        anchors.fill: parent
    }

    onVisibleChanged: {
        if (visible) {
            // Take ownership of the shared object
            mainContent.parent = container
        }
    }
}

main.qml:

ApplicationWindow {
    ...

    Rectangle {
        id: sharedComponent
        anchors.fill: parent
        color: "blue"
    }

    MyPage {
        id: page1
        mainContent: sharedComponent

        // When visible becomes true, page1 becomes the parent
        visible: false
    }
    MyPage {
        id: page2
        mainContent: sharedComponent

        // When visible becomes true, page2 becomes the parent
        visible: false
    }
}