Solved endMoveRows in model crashes my app
-
Hi
I need to move items inside custom QAbstractListModel, this works with ListModel.move()
Code is like thisvoid ObjectModel::move(int from, int to) { if(from==to || to==modelVector.count()-1 || from==0) return; beginMoveRows(QModelIndex(),from,from,QModelIndex(),to); modelVector.move(from,to); endMoveRows();
The thing is that it crashes when I move up from 2 to 3.
I have read about no-op moves here:
http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
Does this mean that I can't move items up ? or up by one place ?Best,
Marek -
Ok I got this working by simple hack
void ObjectModel::move(int from, int to) { if(from+1==to) { to++; if(to>modelVector.count()-1) to=modelVector.count()-1; } if(from==to || from+1==to) return; beginMoveRows(QModelIndex(),from,from,QModelIndex(),to); modelVector.move(from,to); endMoveRows();
Best,
Marek -
The arguments to
beginMoveRows
when parents are the same are not trivial at all. See this commit that will be part of Qt 5.13 for an example of how to implement it.beginMoveRows
returns abool
so you should always check it -
@VRonin thanks for the hint with return value.
Somehow I have managed to make app work without crash.
How should I view this link you have provided to see how to implement it ;)Best,
Marek -
@Marek said in endMoveRows in model crashes my app:
How should I view this link you have provided to see how to implement it
More precise link: https://codereview.qt-project.org/#/c/237801/5/src/widgets/itemviews/qlistwidget.cpp
-
@VRonin It seems to me that beginMoveRows would prevent return false for attempting to move row 0 to row 1 in a list of two elements. The call would look like:
beginMoveRows(QModelIndex(), 0, 0, QModelIndex(), 1)
I have read the documentation for beginMoveRows a few times and can't for the life of me understand the rules for these indexes. Even with the visual diagrams provided. I do know that
if(newRow > oldRow) newRow++
makes it work.Can anyone help me understand how to determine the correct indexes to pass?
Thanks!
-
@patrickkidd said in endMoveRows in model crashes my app:
if(newRow > oldRow) newRow++
Seems that the QT holds the place of your element while it's not completely moved down to new place.
So when you are trying to move elem '0' down after '1' and usebeginMoveRows(QModelIndex(), 0, 0, QModelIndex(), 1)
:0 1 2
It will have an intermediate state with one additional cell:
0 (where the original value has been stored) 0 (new place for 0 element matched to the index you mentioned with last param in beginMoveRows) 1 2
Afterwards the original cell '0' will be removed. Still not clear why it should cause app crush.. but this is not going to give you an expected profit anyway.
-
I think it crashes because move up from 2 to 3 equals to do nothing.
According to doc https://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
If you want to move 2 to 3 you have to move 2 to 4, but in this case you will have a problem with pre_last & last element.
So there is a tricky way to do that: move 3 to 2void ObjectModel::move(int from, int to) { ... if (from + 1 == to) std::swap(from, to); beginMoveRows(QModelIndex(),from,from,QModelIndex(),to); ... endMoveRows(); }