在拖放操作中交换QTreeView项目

Swap QTreeView items on drag and drop operation

本文关键字:QTreeView 项目 交换 拖放 操作      更新时间:2023-10-16

假设我们有以下层次结构:

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

假设用户将C拖到B上。有可能因为拖放操作而交换两个节点(包括子节点)吗?

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

我尝试了多种方法:从子类化项目模型(dropMimeDatainsertRows等)到用setDragDropOverwriteModeDragDropMode::InternalMove调整模式,再到子类化dropEvent(QDropEvent * e),到目前为止都没有成功。

我遇到了以下技术限制:

  • QStandardItemModel::dropMimeDataQTreeview::dropEvent不会让您知道源索引,它们转发mime数据,并且无法获得源的QModelIndex来执行交换。

  • DragDropMode::InternalMovesetDragDropOverwriteMode方法没有按预期工作,源节点以某种方式被附加到丢弃目标节点,并且源节点被移除。如果设置DragDropMode::Copy,则会保留源节点,但也不会覆盖目标节点。

如果能朝着正确的方向推动,我们将不胜感激。

我检查了Qt的源代码,结果发现要获取源索引,应该使用当前选择。因此,重写QTreeview::dropEvent并通过调用selectedIndexes()获取当前选择。


交换不是问题。你只需要移动两次
有一种空间方法:QAbstractItemModel::moveRow(三行中只有一列,所以可以移动行)。这里有另一个解决方案的答案(针对标准物品模型)。

如果你有自己的自定义模型,你必须直接在你的数据上进行,并且只发出关于移动项目的适当信号。