【发布时间】:2022-01-12 00:34:50
【问题描述】:
我有一个启用拖放功能的 MVC QAbstractItemModel,如下所示:
class Model(QtCore.QAbstractItemModel):
# ... other code ...
def flags(self, index):
flags = super(Model, self).flags(index)
flags |= QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled
return flags
这会启用拖放,但拖放行为过于宽松。在这样的树中:
- root
- A
- B
- C
- D
- E
如果删除的索引保留其原始父级,我只想允许拖放。
在其他作品中,我可以在root 下重新排列 A、B 或 C,我可以在 C 下重新排列 D 或 E,但我无法将 A 移至 C,或将 D/E 移至 @987654327 @等
这是一个“有效的”拖放:
- root
- B
- C
- D
- E
- A
因为 A 已移至最后一行,但 A 仍具有相同的父级,root。
但这不是有效的拖放
- root
- B
- A
- C
- D
- E
A 的父级从 root 更改为 B,这不是我想要的。
第一次尝试
我试图通过子类化QTreeView 并向其添加dragMoveEvent 来实现这种“始终保持同一个父级”逻辑,就像这样
class MyTreeSubClass(QtWidgets.QTreeView):
# ... more code ...
def dragMoveEvent(self, event):
super(MyTreeSubClass, self).dragMoveEvent(event)
widget = event.source()
if widget != self:
# Forbid dropping any external data to this widget
event.ignore()
return
index = widget.indexAt(event.pos())
for selected in widget.selectedIndexes():
if index.parent() != selected.parent():
event.ignore()
return
event.accept()
但我认为这不起作用,因为index = widget.indexAt(event.pos()) 返回相同的索引,无论您是直接悬停在树中的索引上还是两个索引之间。
有没有更可靠的方法来判断一个位置是否直接高于索引(如果是,请致电event.reject())?如果是这样,我也许可以用它来接受/拒绝事件。
如果有更简单的方法来实现我正在寻找的东西,我将不胜感激。
【问题讨论】:
标签: python qt model-view-controller