PDA

View Full Version : ListModel.remove() crashes program



truefusion
3rd February 2012, 02:24
I've managed to reproduce the crash in the following code. The version of Qt i'm using is 4.7.4. Can anyone tell me why this would crash the program? Does it crash for anyone else?


import QtQuick 1.0

Rectangle {
id: main
width: 360
height: 360

Text {
id: addBtn
text: "Add to List"
anchors.top: parent.top
width: parent.width
height: 40
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.bold: true

MouseArea {
anchors.fill: parent
onClicked: {
list_model.append({"display": "Click me to delete me"})
}
}
}

ListView {
anchors.top: parent.top
anchors.topMargin: 40
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
spacing: 5

model: ListModel {
id: list_model
}

delegate: Rectangle
{
border.width: 1
border.color: "#000"
width: main.width - 1
height: delText.height + 8

MouseArea {
anchors.fill: parent
onClicked: {
list_model.remove(index)
}
}

Text {
id: delText
height: 20
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: display
}
}
}
}

Lykurg
3rd February 2012, 06:46
What should index be? Try .remove(currentIndex)!

truefusion
4th February 2012, 00:59
What should index be? Try .remove(currentIndex)!

index is whatever the index of the item is that has been interacted with or interacted with one of its children. For my current project, which isn't entirely reflected in the reproducable code, in order to remove the item from the list you have to interact with a child element of the item. This means currentIndex is not practical for my current project, since interacting with the child element does not necessarily make the item parent the current item. Nevertheless, if you were to replace index with ListView.currentIndex (or whatever gives you the current index) in the reproducable code, the program would still crash.

wysota
4th February 2012, 11:45
Removing the current item inside any routine that handles that item is not safe. Mark the item for deletion and delete it after the control returns to the event loop. You might need to interface with C++ for that.

truefusion
5th February 2012, 00:57
Removing the current item inside any routine that handles that item is not safe. Mark the item for deletion and delete it after the control returns to the event loop. You might need to interface with C++ for that.

Researching what you said, i found this example in the documentation which also calls model_id.remove(index) from the delegate: http://doc.qt.nokia.com/4.7-snapshot/declarative-modelviews-listview-dynamiclist-qml.html Skimming through the example, i don't really see any fundamental difference between my code (or the crash reproducable code) and the example.

wysota
5th February 2012, 15:27
The fundamental difference is in ListView.delayRemove=true and everything around it.