Reputation: 717
I'm facing the problem with Pathview. I need to change the path property to reorganize the children items, but when I'm doing this, it causes all of the created elements (specified by model) to be destroyed and created again.
Is there any way to do that without reloading content, or maybe 'cover' the blink effect?
Example:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
Window {
visible: true
width: 640
height: 480
title: qsTr("PathView path test")
Path {
id: path1
startX: 100; startY: 100
PathLine{ x: 300; y: 100 }
}
Path {
id: path2
startX: 100; startY: 100
PathLine{ x: 100; y: 300 }
}
ListModel {
id: pvModel
ListElement{ name: "rectangle" }
ListElement{ name: "rectangle" }
ListElement{ name: "rectangle" }
}
Component {
id: pvDelegate
Rectangle {
width: 50
height: 50
color: "red"
border.width: 1
Component.onCompleted: console.log("Rectangle created")
Component.onDestruction: console.log("Rectangle deleted")
}
}
property bool currentPath;
PathView {
anchors.fill: parent
model: pvModel
delegate: pvDelegate
path: (currentPath ? path1 : path2)
}
Button {
width: 100
height: 40
text: "Switch path"
onClicked: currentPath = !currentPath
}
}
Upvotes: 1
Views: 945
Reputation: 13691
The PathView
seems to use this trick, to force a re-layout after the Path
has changed. I found no ideal way to do this sofar, but to stop the PathView
from destroying your delegates can be done by using a intermediate DelegateModel
.
The DelegateModel
instantiates the Item
s for the view
and you can chose, to have the Item
s persistent, by adding them to the persistedItems
-group.
As we might want to use the dynamic instantiation of a model, for this example, I add only those Item
s to this group, that are instantiated, when the Path
will switch, and remove them from the group right after the switch.
As I said: I did not find (but was not looking too much) for a nice way to force a relayout. So for the moment, I resort to moving the view a little bit, as otherwise the x and y-values of the delegates won't be updated.
If all your Item
s are visible anyway, you can just mark all of them as persistent
in the Component.onCompleted
-slot
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
import QtQml.Models 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("PathView path test")
Path {
id: path1
startX: 100; startY: 100
PathLine{ id: line1; x: 300; y: 100 }
}
Path {
id: path2
startX: 100; startY: 100
PathLine{ x: 100; y: 300 }
}
ListModel {
id: pvModel
ListElement{ name: "rectangle" }
ListElement{ name: "rectangle" }
ListElement{ name: "rectangle" }
}
DelegateModel {
id: pvDelegateModel
model: pvModel
delegate: Rectangle {
id: delegate
width: 50
height: 50
color: 'red'
border.width: 1
Component.onCompleted: console.log("Rectangle created")
Component.onDestruction: console.log("Rectangle destroyed")
Connections {
target: button
onStart: delegate.DelegateModel.inPersistedItems = true // Make them persistent befor the switch
onEnd: delegate.DelegateModel.inPersistedItems = false // Make them non-persistent after the switch
}
}
}
PathView {
id: pv
anchors.fill: parent
model: pvDelegateModel
path: path1
clip: true
}
Button {
id: button
width: 100
height: 40
text: "Switch path"
signal start
signal end
onClicked: {
start()
pv.path = (pv.path === path1 ? path2 : path1)
end()
pv.currentIndex +=1 // To force a refresh of the layout
pv.currentIndex -= 1
}
}
}
Upvotes: 2
Reputation: 5836
I don't know if it's just the path in the above test case, or whether this is possible with the path you have in your real app, but one option could be to change the attributes of the path instead of changing the whole path. Looks like you can even animate the path attributes:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
Window {
visible: true
width: 640
height: 480
title: qsTr("PathView path test")
Path {
id: pvPath
startX: 100; startY: 100
PathLine{
x: currentPath ? 300 : 100
y: currentPath ? 100 : 300
Behavior on x { SmoothedAnimation { duration: 125 } }
Behavior on y { SmoothedAnimation { duration: 125 } }
}
}
ListModel {
id: pvModel
ListElement{ name: "rectangle" }
ListElement{ name: "rectangle" }
ListElement{ name: "rectangle" }
}
Component {
id: pvDelegate
Rectangle {
width: 50
height: 50
color: "red"
border.width: 1
Component.onCompleted: console.log("Rectangle created")
Component.onDestruction: console.log("Rectangle deleted")
}
}
property bool currentPath;
PathView {
anchors.fill: parent
model: pvModel
delegate: pvDelegate
path: pvPath
}
Button {
width: 100
height: 40
text: "Switch path"
onClicked: currentPath = !currentPath
}
}
Upvotes: 0