Hi, I’m trying to get my GridView to animate transitions on operations performed on my C++ model (exposed as a QQmlListProperty). But they don’t work.
The following snippet works:
GridView {
id: gridview
anchors.fill: parent
cellWidth: width / 3
cellHeight: height / 3
model: ListModel {
id: model2
ListElement {
name: "red"
}
ListElement {
name: "blue"
}
ListElement {
name: "green"
}
ListElement {
name: "tomato"
}
}
delegate: Item {
id: gridDelegate
width: gridview.cellWidth
height: gridview.cellHeight
Rectangle {
id: image
anchors.fill: parent
color: name
Behavior on color {
PropertyAnimation { duration: 1000 }
}
}
Image {
width: parent.width / 10
height: width
anchors {
right: image.right
rightMargin: 10
bottom: image.bottom
bottomMargin: 10
}
source: "delete-icon.png"
antialiasing: true
opacity: mouseArea.containsMouse ? 1 : 0
Behavior on opacity {
NumberAnimation { duration: 200 }
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: model2.remove(index);
}
}
}
// Transitions
remove: Transition {
ParallelAnimation {
NumberAnimation { property: "opacity"; to: 0; duration: 500 }
NumberAnimation { properties: "width, height"; to: 0; duration: 500 }
}
}
removeDisplaced: Transition {
NumberAnimation { properties: "x, y"; duration: 500 }
}
}
The following does not:
GridView {
id: gridview
anchors.fill: parent
cellWidth: width / 3
cellHeight: height / 3
* model: imageLoader.allImages*
delegate: Item {
id: gridDelegate
width: gridview.cellWidth
height: gridview.cellHeight
* Image {
id: image
width: parent.width - anchors.margins / 2
height: status == Image.Ready ? parent.height - anchors.margins / 2 : 0
anchors {
centerIn: parent
margins: 10
}
Behavior on height {
NumberAnimation { duration: 500; easing.type: Easing.InOutQuad }
}
fillMode: Image.PreserveAspectFit
asynchronous: true
source: "file:///" + path
}
*
Image {
width: parent.width / 10
height: width
anchors {
right: image.right
rightMargin: 10
bottom: image.bottom
bottomMargin: 10
}
source: "delete-icon.png"
antialiasing: true
opacity: mouseArea.containsMouse ? 1 : 0
Behavior on opacity {
NumberAnimation { duration: 200 }
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
* onClicked: imageLoader.remove_all_image(index);*
}
}
}
// Transitions
remove: Transition {
ParallelAnimation {
NumberAnimation { property: "opacity"; to: 0; duration: 500 }
NumberAnimation { properties: "width, height"; to: 0; duration: 500 }
}
}
removeDisplaced: Transition {
NumberAnimation { properties: "x, y"; duration: 500 }
}
}
I’ve highlighted the differences: in the first case, the model is a dedicated ListModel QML element.
In the second case, it’s a QQmlListProperty I expose from C++.
I think the problem is with the slot I call from C++ when clicking the delete-icon:
* onClicked: imageLoader.remove_all_image(index);*
which is as follows in the code behind:
void ImageLoader::remove_all_image(int i)
{
m_allImages.removeAt(i);
emit allImagesChanged();
}
I have the feeling that GridView’s transitions remove and removeDisplaced are only triggered by a call to the remove function in the ListModel, which fires the proper signals, whereas my function just emits the NOTIFY signal for the QQmlListProperty change and this forces a refresh of the whole Grid. I also noticed that removing an element from the ListModel maintains the currentIndex, whereas calling my function resets the currentIndex to 0 (and if I remove and element from the bottom of the GridView, the grid scroll back to top…).
So, how can I work this problem around? If I got it right, QQmlListProperty wraps QList<MyCustomQObject*> and offers the append function, the count, the access and the clear function, but no removeAt function (which is why I implemented it manually), how can I get this functionality?? The documentation is quite lacking…
↧