Move qtreeview rows
-
Hello,
I have a qtreeview with a qstandarditemmodel..
I would move a row with all subentries to a new position.
I tried:
@ moveRow( customerItem->parent()->index(), customerItem->row(),
_customerGroupsToItems[groupId]->index(), 0);@And now, i readed in the documentation auf moveRows:
@The base class implementation does nothing and returns false.@How can i solve my issue?
-
Hi,
This is because QStandardItemModel doesn't know anything about your underlying data so it can't move things around for you.
You have to implement moveRows for your model if you want to use moveRow.
Hope it helps
-
Hi,
I had the same problem moving a row within a flat QStandardItemModel. It took some figuring out to get the move operation working properly with eg. QML ListView. I ended up doing:@void MyModel::move(int from, int to, int)
{
... //range checking etc.int toSignal = to; if(from < to){ toSignal += 1; } if(!beginMoveRows(QModelIndex(), from, from, QModelIndex(), toSignal)){ return; } blockSignals(true); QStandardItem* fromItem = takeItem(from); removeRow(from); insertRow(to, fromItem); blockSignals(false); endMoveRows();
}@
-
@David-Stiel
Thanks!
I adapted your example to work with aQTreeView
with more than 1 column, as follows (only 1 step up/down per invocation)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, astakeRow(from)
seems to already take care of that.
In a dialog, I haveMove Up
andMove 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); } } }
-
@Diracsbracket
Although this seems to work correctly in the QTreeView, I get the error messages in the Debugger as explained in this post.
https://forum.qt.io/topic/86021/qabstractitemmodel-endmoverows-invalid-indexUpdate: The problem I mentioned in that post was solved by @proman. I should have taken the time to read Qt's online Model/View Programming documentation, as it is clearly mentioned there...