在QTreeView中拖放,未调用

在QTreeView中拖放,未调用,qt,drag-and-drop,treeview,Qt,Drag And Drop,Treeview,我在QTreeView中拖放时遇到一些问题: 我将flag设置为Qt::MoveAction,并在我的模型中重新实现removeows()、dropMimeData()等。该模型继承了qabstractemmodel 当我拖放时,mimeData(),dropMimeData()会自动调用, 而且dropMimeData()自动调用insertRows()。但是未调用removows(),因此拖动的项仍然处于活动状态。我在谷歌上搜索过,但他们说他们的removeRows()是自动调用的 为什么

我在
QTreeView
中拖放时遇到一些问题:

我将flag设置为
Qt::MoveAction
,并在我的模型中重新实现
removeows()
dropMimeData()
等。该模型继承了
qabstractemmodel

当我拖放时,
mimeData()
dropMimeData()
会自动调用, 而且
dropMimeData()
自动调用
insertRows()
。但是未调用
removows()
,因此拖动的项仍然处于活动状态。我在谷歌上搜索过,但他们说他们的
removeRows()
是自动调用的

  • 为什么在dropMimeData()之后不调用my
    removeRows()
  • 我应该在
    dropMimeData()
    中手动调用
    removeows()
  • 如果是,我如何知道开始拖动之前的
    QModelIndex
开始拖动时,在
mimeData()
中,我可以将索引保存在private member中,但看起来不太好


如有任何建议,将不胜感激

我认为是的,如果
Qt::DropAction
Qt::MoveAction
,您必须从
dropMimeData()
调用
removows()
,也就是说,您完全将树节点从一个位置移动到另一个位置


请回答第二个问题,您可以在
qabstractemmodel::mimeData()
中创建自定义mime数据,并在其中对拖动的节点初始信息进行编码。因此,在
dropMimeData()
函数中,您可以解码并使用它。

我的自定义模型也有同样的问题。设置视图的dragDropOverwriteMode=false解决了我的问题。

简短回答

如果所有配置都正确,则目标不应删除源项,如果执行了
Qt::MoveAction
,则拖动的发起人应删除源项

视图的配置

(它是
QTreeView
QListView
QTableView
,…)的基类,在以下位置执行操作的启动和完成:

因此,当请求的删除操作(由返回)是
Qt::MoveAction
时,该项将自动删除(或按照
setDragDropOverwriteMode
的指定清除)

视图的重要配置选项包括:

  • :指定视图应接受外部项的拖放项还是仅接受内部项。此函数相应地调用
    setDragEnabled
    setAcceptDrops

    • :启用内置拖动机制
    • :启用内置下降机制
  • :指定是删除源项(在树视图中是典型的)还是清除源项(在表视图中是典型的)

  • :启动
    QDrag
    操作时指定的默认放置操作

模型的配置

除了配置视图外,还应正确配置模型

  • 您应该实现模型的编辑界面,即
    removows
    insertRows
    moveRows
    setData
    。尽管可能不需要根据您的具体情况实现所有这些功能,但对于可编辑模型来说,实现这些功能仍然是一种很好的方法

  • :重新实现此函数以返回支持删除操作(
    Qt::CopyAction
    默认情况下)。请注意,用户可以通过按一些键在不同支持的操作之间切换。(
    shift
    用于
    Qt::MoveAction
    control
    用于
    Qt::CopyAction

    • :如果支持的拖动操作与支持的拖放操作不同,则重新实现此功能
示例


好的例子是Qt本身的源代码。相应的
Q*Widget
类(例如
QTreeWidget
用于
QTreeView
)提供了视图的具体实现和相应的模型。

感谢您的快速回复。我知道对自定义mime数据进行编码/解码,但无法对拖动节点的索引进行编码。。如何将模型索引编码为QDataStream?@user18640,例如,您可以存储行和列编号、树项路径或任何其他可以唯一标识模型索引的信息。我明白了,我将对行、列和模型索引internalid进行编码,以使用dropMimeData()中的QAbstractItemModel::createIndex()。谢谢。如果在两个不同的模型之间拖动一个下拉菜单会怎么样?”实际上应该在源模型上调用removeRows。文档中说,当“dropMimeData”返回true时,将自动调用“removeRows”。这是错误的,当您从
dropMimeData()返回
true
时,Qt将自动为您调用
removeRows
,这是我遇到的另一件事:视图的属性必须设置为
QAbstractItemView::SelectRows
(而不是
QAbstractItemView::SelectItems
)。dragDropOverwriteMode的默认值为false,就像在QListView和QTreeView子类中一样。另一方面,在QTableView子类中,属性已设置为true
if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
    d->clearOrRemove();