QML StackView:项目在弹出时被销毁 [英] QML StackView: Item Destroyed on pop

查看:13
本文介绍了QML StackView:项目在弹出时被销毁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下示例:

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,即单击下一步"按钮加载第二页.当我点击它时,它会显示一个更新的文本(第二页点击").然后点击上一个"按预期加载第一页.

Here I'm pushing 2 Components into the StackView on the each button clicks, i.e. clicking the "Next" button loads the second page. When I click on it, it displays an updated text("Second Page Clicked"). Then clicking "Prev" loads the first page as expected.

现在,如果我再次单击下一步",它应该加载带有更新文本的第二页(第二页单击"),但它没有.它显示初始文本(第二页").

Now if I click "Next" again, it should load the second page with that updated text ("Second Page Clicked"), but it doesn't. It shows the initial text ("Second Page").

所以问题是 Item 是否在 pop 时被销毁?如果不是,那么第二页不应该显示更新后的文本(第二页点击")吗?

So the question is whether the Item is destroyed on pop? If not then shouldn't the second page display the updated text ("Second Page Clicked")?

我什至将标志 destroyOnPop 设置为 false.我是否误解了 StackView 的概念?有什么办法可以解决吗?

I have even set the flag destroyOnPop to false. Have I misunderstood the concept of StackView? Any possible way to solve this?

我想从 StackView 中的任何点加载任何页面,并且 Item 的状态与我离开时一样.就像 QStackWidget 一样,我们使用 setCurrentIndex().

I want to load any page from any point in StackView and that the state of Item be as it is where I left it. Just like QStackWidget, where we use setCurrentIndex().

推荐答案

文档是指 Item 对象,而您使用的是 Component.documentation 非常清楚一个组件不是一个 Item,因为它不是从 Item 派生的.实际上,Component 的行为类似于被实例化到特定对象的 Class.

Documentation is referring to Item object whereas you are using Components. The documentation is pretty clear about the fact that a component is not an Item since it is not derived from Item. Indeed a Component act like a Class which is instanced to a specific object.

每次调用

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

组件 comp2 的新实例"被生成,并且使用这样的 new 实例代替之前的实例.我强烈建议阅读这篇文章以更好地理解Component 对象和生成的实例.

a new "instance" of the component comp2 is generated and such new instance is used instead of the previous one. I strongly suggest to read this article to better understand the correlation between Component objects and generated instances.

实例可以通过createObject 函数生成.因此,您可以创建一个 Item 数组并使用这样的 Item 代替 Component.最终代码如下所示:

Instances can be generated via createObject function. Hence, you can create an array of Items and use such Items instead of the Components. Final code looks like this:

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 对象可以得到同样正确的结果.在这种情况下,由于 destroyOnPop 设置为 false,我们有两个 Item 被重新设置为 Window.

The same correct result could be achieved by defining directly the Rectagle objects in the source. In this case we have two Items which are reparented to the Window thanks the destroyOnPop set to 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"
   }
}

这篇关于QML StackView:项目在弹出时被销毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆