Вопрос

Let's say we have the following hierarchy:

+ A
|-- B
  |-- D
|-- C

And let's say the user drags C onto B. Is it possible to have both nodes (including children) swapped as the result of that drag and drop operation?

+ A
|-- C
|-- B
  |-- D

I've tried multiple approaches: from subclassing the item model (dropMimeData, insertRows, etc) to adjusting modes with setDragDropOverwriteMode and DragDropMode::InternalMove, to subclassing dropEvent(QDropEvent * e) and nothing worked so far.

I've encountered the following techincal limitations:

  • QStandardItemModel::dropMimeData and QTreeview::dropEvent won't let you know the source index, they forward mime data, and there's no way to obtain the source's QModelIndex to perform the swapping.

  • The DragDropMode::InternalMove and setDragDropOverwriteMode approach doesn't work as expected, the source node gets appended to the drop target node somehow, and the source node is removed. If you set DragDropMode::Copy, the source node is preserved, but the target node isn't overwritten either.

A nudge in the right direction would be appreciated.

Это было полезно?

Решение

I've inspect source code of Qt and it turns out that to fetch source index you should use current selection. So override QTreeview::dropEvent and fetch current selection by calling selectedIndexes().


Swap is not a problem. You have to just do move twice.
There is spatial method for that: QAbstractItemModel::moveRow (in threes you have only one column so moving row is ok). Here you have a answer with another solutions (for standard item model).

If you have own custom model you have to do it directly on your data and just emit proper signals about moving items.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top