问题
Consider the following example:
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
}
}
}
}
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").
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")?
I have even set the flag destroyOnPop
to false
. Have I misunderstood the concept of StackView
? Any possible way to solve this?
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()
.
回答1:
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.
Each time you call
stackView.push( { item: comp2, destroyOnPop:false } )
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.
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
}
}
}
}
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"
}
}
来源:https://stackoverflow.com/questions/27961827/qml-stackview-item-destroyed-on-pop