使用 setDropAction 时,QTreeWidget 丢弃的项目被删除

Posted

技术标签:

【中文标题】使用 setDropAction 时,QTreeWidget 丢弃的项目被删除【英文标题】:QTreeWidget dropped item gets deleted when using setDropAction 【发布时间】:2021-09-15 20:09:17 【问题描述】:

我正在尝试制作一个QTreeWidget,让用户重新排列其元素,如果用户将树项目拖放到另一个小部件,我不希望删除该项目。为了获得这种行为,我尝试在dropEvent 中使用setDropAction

下面的代码成功拒绝其他小部件的拖放,并允许在不删除原始小部件的情况下拖放到其他小部件,但它似乎破坏了树内的拖放 - 它导致项目在拖放时消失。

https://www.screencast.com/t/driIjyg8ekzt

import sys

from PyQt5 import QtWidgets, QtGui
from PyQt5.QtCore import Qt


class MyTree(QtWidgets.QTreeWidget):
    def __init__(self):
        super().__init__()

        self.setDragDropMode(self.DragDrop)
        self.setSelectionMode(self.ExtendedSelection)
        self.setSelectionBehavior(self.SelectRows)
        self.setDefaultDropAction(Qt.CopyAction)
        self.setAcceptDrops(True)

    def dropEvent(self, e: QtGui.QDropEvent):
        if e.source() is self:
            print("move")
            e.setDropAction(Qt.MoveAction)
            e.accept()
        super().dropEvent(e)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    my_list = QtWidgets.QListWidget()
    my_list.addItems(list('1234'))
    my_list.show()
    my_list.setDragEnabled(True)
    my_list.setAcceptDrops(True)

    my_tree = MyTree()
    for item in list('abcd'):
        QtWidgets.QTreeWidgetItem(my_tree, [item])
    my_tree.show()

    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

如果您只是想防止从外部来源丢弃,只需使用:

    self.setDragDropMode(self.InternalMove)

并且不要重新实现dropEvent()

您的代码不能正常工作主要是因为您已将事件设置为已接受,如果已接受,项目视图会忽略放置事件。

在你的情况下,这样做会更好:

    def dzropEvent(self, e: QtGui.QDropEvent):
        if e.source() != self:
            # ignore the drop from other sources
            return
        e.setDropAction(Qt.MoveAction)
        super().dropEvent(e)

但是如果你真的想忽略外部丢弃,你应该忽略来自dragEnterEvent()的事件,这样用户也可以清楚地知道不允许丢弃。

【讨论】:

以上是关于使用 setDropAction 时,QTreeWidget 丢弃的项目被删除的主要内容,如果未能解决你的问题,请参考以下文章

参数标志,不使用时为空,不使用时为默认值

使用 php artisan migrate 时,迁移时更改表名,使用 tinker 保存对象时出错

使用前台服务时允许“使用应用程序时”而不是“始终允许”是不是可以?

为啥在使用自适应查询执行时要使用广播时火花洗牌

使用自定义效果时缺少网格颜色,但使用 BasicEffect 时没有

使用google可视化api时,使用dashboard时如何使用getChartLayoutInterface()