QAbstractItemModel::endMoveRows: Invalid index



  • Hi,
    To move a row of a QTreeView up or down with a button click, I have adapted the code from here to this code, which I reproduce here for convenience:

    bool StandardItemModel::move(int from, bool isUp)
    {
        //range checking etc.
        const int numRows = rowCount();
    
        if (from<0 || from>=numRows || (from==0 && isUp) || (from==numRows-1 && !isUp))
            return false;
    
        const int to = isUp ? from - 1: from + 1;
    
        //See documentation
        //http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
        //on why this is needed?
        const int toSignal = isUp ? to : to + 1;
    
        if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal))
            return false;
    
        blockSignals(true);
        QList<QStandardItem*> fromRow = takeRow(from); //this also removes it from the model!
        insertRow(to, fromRow); //but the actual insertion must be done using to, not toSignal!
        blockSignals(false);
    
        endMoveRows();
    
        return true;
    }
    Note that there is no removeRow(from) in the adapted code, as takeRow(from) seems to already take care of that.
    In a dialog, I have Move Up and Move Down buttons that call the following dialog method:
    
    void changeOrderDialog::moveCurrentRow(bool isUp)
    {
        const QModelIndex index = ui->treeView->currentIndex();
    
        if (index.isValid())
        {
            StandardItemModel* model = qobject_cast<StandardItemModel*>(ui->treeView->model());
            const int row = index.row();
    
            if (model->move(row, isUp))
            {
                const QModelIndex newIndex = model->index(isUp ? row-1 : row+1, 0);
                ui->treeView->setCurrentIndex(newIndex);
            }
        }
    }
    

    Although the moves up and down + boundary conditions seem to work correctly, I get the following debugger messages (one triplet per up/down move, probably because I have 3 columns per row):

    //Error on the moveUp (to lower row index):
    QAbstractItemModel::endMoveRows:  Invalid index ( -2 , -1 ) in model StandardItemModel(0x779ad90)
    QAbstractItemModel::endMoveRows:  Invalid index ( -2 , -1 ) in model StandardItemModel(0x779ad90)
    QAbstractItemModel::endMoveRows:  Invalid index ( -2 , -1 ) in model StandardItemModel(0x779ad90)
    
    //Error on the moveDown (to higher row index):
    QAbstractItemModel::endMoveRows:  Invalid index ( 0 , -1 ) in model StandardItemModel(0x779ad90)
    QAbstractItemModel::endMoveRows:  Invalid index ( 0 , -1 ) in model StandardItemModel(0x779ad90)
    QAbstractItemModel::endMoveRows:  Invalid index ( 0 , -1 ) in model StandardItemModel(0x779ad90)
    

    What do I need to do to avoid these messages?



  • bool StandardItemModel::move(int from, bool isUp)
    {
    //range checking etc.
    const int numRows = rowCount();

    if (from<0 || from>=numRows || (from==0 && isUp) || (from==numRows-1 && !isUp))
        return false;
    
    const int to = isUp ? from - 1: from + 1;
    
    //See documentation
    //http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
    //on why this is needed?
    const int toSignal = isUp ? to : to + 1;
    
    if (!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal))
        return false;
    
    blockSignals(true);
    QList<QStandardItem*> fromRow = takeRow(from); //this also removes it from the model!
    
    //add this 
    beginInsertRows(QModelIndex(),from,toSignal);
    
    insertRow(to, fromRow); //but the actual insertion must be done using to, not toSignal!
    blockSignals(false);
    
    endMoveRows();
    
    return true;
    

    }

    it`s work for me.



  • @proman said in QAbstractItemModel::endMoveRows: Invalid index:

    //add this
    beginInsertRows(QModelIndex(),from,toSignal);

    @proman, many thanks for your reply, and apologies for this late reaction. I did not recall seeing a notification about your post in my Qt notifications list and just happened to stumble on this old post of mine by accident.

    Your addition works, I no longer have the debugger messages. Thanks again!



  • The problem I mentioned in my post above and in the reference therein to another post of mine was solved graciously by @proman.

    He mentioned that I should add

    beginInsertRows(QModelIndex(),from,toSignal); 
    

    before doing

    insertRow(to, fromRow);  
    

    This avoids the debugger error messages.

    UPDATE:
    then line should actually be:

    beginInsertRows(QModelIndex(),toSignal,toSignal); 
    

    otherwise, you'll get ASSERT error messages when moving up because last<first.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.