QML StackView:项目在弹出时被销毁
QML StackView: Item Destroyed on pop
考虑以下示例:
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
,即单击 "Next" 按钮会加载第二页。当我单击它时,它会显示更新的文本 ("Second Page Clicked")。然后单击 "Prev" 按预期加载第一页。
现在,如果我再次单击 "Next",它应该加载带有更新文本 ("Second Page Clicked") 的第二页,但它没有。它显示初始文本 ("Second Page")。
所以问题是 Item
是否在弹出时被销毁?如果不是,那么第二页不应该显示更新后的文本吗 ("Second Page Clicked")?
我什至将标志 destroyOnPop
设置为 false
。我是否误解了 StackView
的概念?有什么办法可以解决这个问题吗?
我想从 StackView
中的任何点加载任何页面,并且 Item
的状态与我离开时的状态相同。就像QStackWidget
,这里我们用setCurrentIndex()
.
文档指的是 Item
对象,而您使用的是 Component
。 documentation 非常清楚一个组件 不是 和 Item
的事实,因为它不是从 Item
派生的。事实上,Component
就像 Class
一样,它被实例化到一个特定的对象。
每次打电话
stackView.push( { item: comp2, destroyOnPop:false } )
生成了组件 comp2
的一个新 "instance" 并且使用了这样的 new 实例而不是前一个实例。我强烈建议阅读 this article 以更好地理解 Component
对象和生成的实例之间的相关性。
可以通过createObject
函数生成实例。因此,您可以创建一个 Item
数组,并使用 Item
代替 Component
。最终代码如下所示:
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"
}
}
考虑以下示例:
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
,即单击 "Next" 按钮会加载第二页。当我单击它时,它会显示更新的文本 ("Second Page Clicked")。然后单击 "Prev" 按预期加载第一页。
现在,如果我再次单击 "Next",它应该加载带有更新文本 ("Second Page Clicked") 的第二页,但它没有。它显示初始文本 ("Second Page")。
所以问题是 Item
是否在弹出时被销毁?如果不是,那么第二页不应该显示更新后的文本吗 ("Second Page Clicked")?
我什至将标志 destroyOnPop
设置为 false
。我是否误解了 StackView
的概念?有什么办法可以解决这个问题吗?
我想从 StackView
中的任何点加载任何页面,并且 Item
的状态与我离开时的状态相同。就像QStackWidget
,这里我们用setCurrentIndex()
.
文档指的是 Item
对象,而您使用的是 Component
。 documentation 非常清楚一个组件 不是 和 Item
的事实,因为它不是从 Item
派生的。事实上,Component
就像 Class
一样,它被实例化到一个特定的对象。
每次打电话
stackView.push( { item: comp2, destroyOnPop:false } )
生成了组件 comp2
的一个新 "instance" 并且使用了这样的 new 实例而不是前一个实例。我强烈建议阅读 this article 以更好地理解 Component
对象和生成的实例之间的相关性。
可以通过createObject
函数生成实例。因此,您可以创建一个 Item
数组,并使用 Item
代替 Component
。最终代码如下所示:
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"
}
}