ListView, delegate; strange behaviour after repaint
-
Hi,
Qt 4.8/QML
I have a ListView with a delegate and model.
In the delegate defintion:
color : "#FF0000"
onclick turns the color to green (color = "#00FF00"). Next click back to red.
All works fine, until I scroll the list. Then all the green items - that have been hidden (scrolled out of the listview area) - are set back to red again.
I guess this is caused by repainting the items when they scroll back in/out of the (list)view area.
Is this a bug or does qtquick completely reload components with start-off values when repainting is needed.
BTW: the QtGUI equivalent works fine. -
Hi,
The listview dynamically constructs and destroys delegates as they enter the viewable area. If you have a cache buffer specified, delegates will be created slightly earlier and destroyed slightly later (which in most cases will improve the appearance of scrolling, as delegates are created before they're viewable, but in some cases can cause performance degradation due to increased memory pressure). So, any state in a delegate which is destroyed is of course lost. If you need persistent state, you should store it in a dictionary/map in the parent object (or some other object with a lifetime longer than that of the delegate). Each delegate knows its index.
Cheers,
Chris. -
Thanks for the reply.
I don't understand what you mean by storing a delegate. In an array or sth. ?
I tried to use setproperty on the listmodel to store/change values, but the delegates keeps repeating the initial values of the listmodel.
So, even with scrolling (destroyed and re-created) it does not re-read the listmodel values. I am quite lost here. -
Sorry, I wasn't clear. The delegates cannot be stored (they're managed by the listview). But state-information associated with a delegate could be stored.
pseudocode below:
@
Item {
id: root
property var stateInformation: []ListView { model: someModel delegate: deleg } Component { id: deleg Rectangle { property bool isRed: root.stateInformation[index] === true ? true : false color: isRed ? "red" : "blue" onColorChanged: { var si = root.stateInformation si[index] = isRed root.stateInformation = si } MouseArea { anchors.fill: parent onClicked: { if (parent.isRed) { parent.isRed = false } else { parent.isRed = true } } } } }
}
@