How to change the order of QTableView rows by dragging and store the changes to the model?

112 Views Asked by At

I want to know how to change the order of QTableView rows by dragging, and store the order changes to the model?

I use QTableView as view and QSqlTableModel as model. I am using Qt 5.15.

I set:

ui->table_view->setSelectionMode(QAbstractItemView::SingleSelection);
ui->table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->table_view->setEditTriggers(QAbstractItemView::NoEditTriggers);

Methods I tried:

1.

ui->table_view->setSectionsMovable(true);
ui->table_view->setDragEnabled(true);
ui->table_view->setDragDropMode(QAbstractItemView::InternalMove);
ui->table_view->setAcceptDrops(true);

It doesn't take effect. The row cannot be dragged.

2.

ui->table_view->verticalHeader()->setSectionsMovable(true);
ui->table_view->verticalHeader()->setDragEnabled(true);
ui->table_view->verticalHeader()->setDragDropMode(QAbstractItemView::InternalMove);
ui->table_view->verticalHeader()->setAcceptDrops(true);

The row can be dragged by vertical header. But the order of changes will not affect the model.

1

There are 1 best solutions below

2
On BEST ANSWER

As far as I know the QTableView does not call moveRows method of the model by itself. Instead drag and drop actions call *mimeData methods.

So, one option would be the following:

In your model you need to implement mimeData and dropMimeData functions. When you drag and drop a row the view will ask for mimeData() of the given row. If you are sure that you need only internal moves you can encode the selected row indices to QMimeData. Then in the dropMimeData() you decode the indices that were selected and use them to call your moveRows() implementation. Return false from this function to prevent removing of the moved out rows.

Another option can be to override the QTableView methods such as dropEvent() in a way, that it calls the model moveRows() method directly.