In the QML Dynamic View Ordering Tutorial 3 example I've replaced visualModel.items.move()
call with my ObjectListModel::move()
method like this:
ObjectListModel : public QAbstractListModel:
void ObjectListModel::move(int from, int to)
{
if(0 <= from && from < count() && 0 <= to && to < count() && from != to) {
if(from == to - 1) // Allow item moving to the bottom
to = from++;
beginMoveRows(QModelIndex(), from, from, QModelIndex(), to);
objectList.move(from, to);
endMoveRows();
}
}
Delegate component:
DropArea {
anchors { fill: parent; }
onEntered: {
let from = drag.source.DelegateModel.itemsIndex
let to = mouseArea.DelegateModel.itemsIndex
objectListModel.move(from, to)
}
}
And above works perfectly for the ListView
and ObjectListModel
itself - I have checked: items (and therefore objects) are moved correctly, indexes are correct, C++ consumers works just fine and take new order into account correctly, etc.
However another consumer like MapItemView
fails to use the model after beginMoveRows
/endMoveRows
calls: moved item disappeared on the map and other manipulations with an item crashes the app.
Map {
...
MapItemView {
model: objectListModel
delegate: SomeItemIndicator {
}
}
}
Reported QTBUG-81076 bug, which is confirmed.
Workaround:
Found workaround for now: created 2nd duplicate model which content will be replaced completely on every change in the 1st model on every add/delete/moving(reordering). Above works since beginResetModel
/endResetModel
works correctly for MapItemView
. So MapItemView
now utilizes only the 2nd model. So on every 1st model change this method is called for the 2nd model:
QObjectList ObjectListModel::swapObjectList(const QObjectList& newlist)
{
QObjectList oldlist(_objectList);
beginResetModel();
_objectList = newlist;
endResetModel();
return oldlist;
}