问题描述
考虑以下示例:
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 Component
s 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 Component
s. 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 Item
s and use such Item
s instead of the Component
s. 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 Item
s 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:项目在弹出时被销毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!