How to implement simple internal drag&drop for reordering items in QListView using a custom model
-
I have a QList of custom structs and i'm using custom model class (subclass of QAbstractListModel) to display those structs in 1-dimensional QListView. I have overriden the methods
rowCount
,flags
anddata
to construct a display string from the struct elements.Now i would like to enable internal drag&drop to be able to reorder the items in the list by dragging them and dropping them between some other items, but this task seems unbeliavably complicated. What exactly do i need to override and what parameters do i need to set? I tried a lot of things, i tried
view->setDragEnabled( true ); view->setAcceptDrops( true ); view->setDragDropMode( QAbstractItemView::InternalMove ); view->setDefaultDropAction( Qt::MoveAction );
I tried
Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; } Qt::ItemFlags flags( const QModelIndex & index ) const override{ return QAbstractItemModel::flags( index ) | Qt::ItemIsDragEnabled; }
I tried implementing
insertRows
andremoveRows
, but it still doesn't work.I haven't found a single example of a code doing exactly that. The official documentation goes very deeply into how view/model pattern works and how to make drag&drops from external apps or from other widgets, but i don't want any of that. I only want simple internal drag&drop for manual reordering of the items in that one list view and nothing more.
Can someone please help me? Or i'll get nuts from this.
-
Hi
When the build in drag & drop is not enough, then for the model you need to override
mimeType()
mimeData()
dropMimeData()example.
https://www.qtcentre.org/threads/51679-How-to-Drag-and-Drop-working-with-tableviewps. Qt Models and Views will drive you slightly nuts but really worth it :)
-
But this
https://doc.qt.io/qt-5/model-view-programming.html#accepting-dropped-data
says QAbstractListModel has default implementations of mimeType, mimeData, dropMimeData, that should do everything i need. -
-
I got quite a good answer here https://stackoverflow.com/questions/56819085/qt-how-to-implement-simple-internal-dragdrop-for-reordering-items-in-qlistview
Additionally i discovered few other important things about how it works, which i included in my own answer.
Not gonna copy&paste here. TL,DR: defaultmimeData
anddropMimeData
work only if your underlying data structure only contains elements serialized insidedata
and deserialized insetData
on EditRole. If there is something more in your structs than those display elements, you need your ownmimeData
anddropMimeData
to move the whole content of your struct. -
Hi,
Just in case, there's a whole chapter dedicated to that in QT's documentation.