QAbstractItemModel::endMoveRows: Invalid index
-
Hi,
To move a row of aQTreeView
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
.