我在QTreeView
中拖放有一些问题:
我将标记设置为Qt::MoveAction
并在我的模型中重新实现removeRows()
,dropMimeData()
等。模型继承QAbstractItemModel
。
当我拖放时,会自动调用mimeData()
,dropMimeData()
,
以及dropMimeData()
自动调用insertRows()
。但是没有调用removeRows()
,因此拖动的项目仍然存在。我用谷歌搜索,但是他们说他们removeRows()
被自动调用了。
removeRows()
之后我的dropMimeData()
为什么不被调用? removeRows()
?dropMimeData()
QModelIndex
的阻力开始?开始拖动时,在mimeData()
中,我可以将索引保存在私有成员中,但看起来不太好。
任何建议都将不胜感激。
答案 0 :(得分:3)
简短回答
如果所有内容都已正确配置,则目标不应删除源项目,如果执行Qt::MoveAction
,则拖动的发起者应删除源项目。
视图配置
QAbstractItemView
(QTreeView
的基类,QListView
,QTableView
,...)实现了QDrag
操作的启动和完成在startDrag
中:
if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction) d->clearOrRemove();
因此,当请求的放弃操作(由QDrag::exec
返回)为Qt::MoveAction
时,该项目将自动删除(或按setDragDropOverwriteMode
的指定清除)。
视图的重要配置选项是:
setDragDropMode
:指定视图是否应接受来自外部项目或仅内部项目的拖放项目。此函数会相应地调用setDragEnabled
和setAcceptDrops
。
setDragEnabled
:启用内置拖动机制setAcceptDrops
:启用内置放置机制 setDragDropOverwriteMode
:指定是否应删除源项(在树视图中典型)或清除(在表视图中典型)
setDefaultDropAction
:启动QDrag
操作时指定的默认放弃操作。
模型配置
除了视图的配置外,您还应该正确配置模型。
您应该实施模型的编辑界面,即removeRows
,insertRows
,moveRows
和setData
。虽然可能没有必要根据您的具体情况实施所有这些,但无论如何,对于可编辑的模型来说,这是一种很好的方法。
supportedDropActions
:重新实现此函数以返回支持放置操作(默认情况下为Qt::CopyAction
)。请注意,用户可以通过按某些键在不同的支持操作之间切换。 (shift
为Qt::MoveAction
,control
为Qt::CopyAction
supportedDragActions
:如果受支持的拖动操作与支持的放置操作不同,则重新实现此功能。<强>实施例强>
很好的例子是Qt本身的源代码。相应的Q*Widget
类(例如QTreeWidget
的{{1}})提供了视图和相应模型的具体实现。
答案 1 :(得分:1)
我的自定义模型遇到了同样的问题。为视图设置dragDropOverwriteMode=false
解决了我的问题。
答案 2 :(得分:-3)
我想是的,如果removeRows()
是dropMimeData()
,您必须从Qt::DropAction
致电Qt::MoveAction
,即您将树节点从一个地方完全移动到另一个地方。
WRT您的第二个问题,您可以在QAbstractItemModel::mimeData()
中创建自定义mime数据,并在此处对拖动的节点初始信息进行编码。因此,在dropMimeData()
函数中,您可以解码并使用它。