使用 setDropAction 时 QTreeWidget 丢弃的项目被删除
QTreeWidget dropped item gets deleted when using setDropAction
我正在尝试制作一个 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_())
如果你只是想防止从外部源掉落,只需使用:
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()
忽略事件,这样也让用户清楚不允许掉落。
我正在尝试制作一个 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_())
如果你只是想防止从外部源掉落,只需使用:
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()
忽略事件,这样也让用户清楚不允许掉落。