QML StackView:项目在pop上销毁

时间:2015-01-15 10:55:25

标签: qml

考虑以下示例:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2

Window {
    visible: true
    width: 320
    height: 320

    StackView {
        id: stackView
        anchors.fill: parent
        Component.onCompleted: {
            stackView.push( { item: comp1, destroyOnPop:false } )
        }
    }

    Component {
        id: comp1
        Rectangle {
            color: "lightgray"

            Text {
                id: mtext
                anchors.centerIn: parent
                text: "First Page"
            }
        }
    }

    Component {
        id: comp2
        Rectangle {
            color: "lightgreen"

            Text {
                id: mtext
                anchors.centerIn: parent
                text: "Second Page"
            }

            MouseArea {
                id: mouseArea
                anchors.fill: parent
                onClicked: mtext.text += " Clicked"
            }
        }
    }

    Row {
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        Button {
            id: next
            text: "Next"
            onClicked: {
                stackView.push( { item: comp2, destroyOnPop:false } )
                enabled = false
                prev.enabled = true
            }
        }

        Button {
            id: prev
            text: "Prev"
            enabled: false
            onClicked: {
                stackView.pop()
                enabled = false
                next.enabled = true
            }
        }
    }
}

在这里,我将2 Component推入每个按钮点击的StackView,即点击“下一步”按钮加载第二页。当我点击它时,它会显示一个更新的文本(“Second Page Clicked”)。然后单击“上一步”按预期加载第一页。

现在,如果我再次单击“下一步”,它应该加载第二页,其中包含更新的文本(“第二页单击”),但事实并非如此。它显示了初始文本(“第二页”)。

所以问题是Item是否在pop上被破坏了?如果没有,则第二页不应显示更新的文本(“第二页单击”)?

我甚至将标记destroyOnPop设置为false。我误解了StackView的概念吗?任何可能的方法来解决这个问题?

我想从StackView中的任意点加载任何页面,Item的状态就像我离开它的位置一样。就像QStackWidget一样,我们使用setCurrentIndex()

1 个答案:

答案 0 :(得分:2)

文档指的是Item对象,而您正在使用Component s。 documentation非常清楚组件 Item这一事实,因为它不是从Item派生的。实际上,Component就像Class一样,是一个特定对象的实例。

每次致电

stackView.push( { item: comp2, destroyOnPop:false } )

生成组件comp2的新“实例”,并使用此类 new 实例代替前一个实例。我强烈建议您阅读this article以更好地理解Component对象与生成的实例之间的相关性。

可以通过createObject函数生成实例。因此,您可以创建一个Item的数组,并使用Item s而不是Component s。最终代码如下所示:

import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2

Window {
    visible: true
    width: 320
    height: 320

    StackView {
        id: stackView
        anchors.fill: parent
        Component.onCompleted: {
            push( { item: items[0], destroyOnPop:false })
        }
        property variant items: [comp1.createObject(), comp2.createObject()]  // objects from the components
    }

    Component {
        id: comp1
        Rectangle {
            color: "lightgray"

            Text {
                id: mtext
                anchors.centerIn: parent
                text: "First Page"
            }
        }
    }

    Component {
        id: comp2
        Rectangle {
            color: "lightgreen"

            Text {
                id: mtext
                anchors.centerIn: parent
                text: "Second Page"
            }

            MouseArea {
                id: mouseArea
                anchors.fill: parent
                onClicked: mtext.text += " Clicked"
            }
        }
    }

    Row {
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        Button {
            id: next
            text: "Next"
            onClicked: {
                stackView.push({ item: stackView.items[1], destroyOnPop:false })
                enabled = false
                prev.enabled = true
            }
        }

        Button {
            id: prev
            text: "Prev"
            enabled: false
            onClicked: {
                stackView.pop()
                enabled = false
                next.enabled = true
            }
        }
    }
}

通过直接定义源中的Rectagle对象,可以实现相同的正确结果。在这种情况下,我们有两个Item,它们被Window重新定位,感谢destroyOnPop设置为false。

Rectangle {
    id: comp1
    color: "lightgray"
    visible: false

    Text {
        id: mtext
        anchors.centerIn: parent
        text: "First Page"
    }
}

Rectangle {
   id: comp2
   color: "lightgreen"
   visible: false

   Text {
        id: mtext2
        anchors.centerIn: parent
        text: "Second Page"
   }

   MouseArea {
       id: mouseArea
       anchors.fill: parent
       onClicked: mtext2.text += " Clicked"
   }
}