Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

endMoveRows in model crashes my app



  • Hi
    I need to move items inside custom QAbstractListModel, this works with ListModel.move()
    Code is like this

    void 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 a bool 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 use beginMoveRows(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.


Log in to reply