如何阻止 QTreeWidget 在拖放时创建重复项
Posted
技术标签:
【中文标题】如何阻止 QTreeWidget 在拖放时创建重复项【英文标题】:How to stop QTreeWidget from creating the item duplicates on Drag and Drop 【发布时间】:2014-08-09 20:47:36 【问题描述】:下面的代码创建了包含五个项目的QTreeWidget
。
self.setDragDropMode(self.InternalMove)
标志确保当项目被拖到
另一个将不会复制它(因此项目的数量始终保持不变)。
如果我们用self.setDragDropMode(self.DragDrop)
替换这一行,那么每次拖放一个项目时都会创建一个新副本。
由于我不希望在每个 dragAndDrop 事件上创建项目的副本,如果 InternalMove
标志不会阻止 QTreeWidget
接受来自其自身视图之外的拖放,我会很高兴(如果设置了InternalMove
标志QTreeWidget
不允许从另一个QTreeWidget
、QListView 或文件浏览器拖放。
有没有办法设置覆盖,所以QTreeWidget
不会创建拖动项目的副本,但允许从其自己的窗口外部拖放。
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
class Tree(QtGui.QTreeWidget):
def __init__(self, *args, **kwargs):
super(Tree, self).__init__()
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
self.setDragDropMode(self.InternalMove)
items=[QtGui.QTreeWidgetItem([name]) for name in ['Item_1','Item_2','Item_3','Item_4','Item_5']]
self.addTopLevelItems(items)
self.resize(360,240)
self.show()
tree=Tree()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:解决这个问题的关键是你必须在对象移动到下一个QListsWidget
时执行,并检查数据是否重复。通过删除源并将此数据添加到目标QListsWidget
,将数据从源带到目标。
使用dragEnterEvent
和dropEvent
这两种方法来处理它们;
实现dragEnterEvent
检查要移动的对象是否相同QListsWidget
。
已实现dropEvent
检查数据是否重复,并将数据从源到目标。
例子:
import sys
from PyQt4 import QtCore, QtGui
class QCustomTreeWidget (QtGui.QTreeWidget):
def __init__(self, parent = None):
super(QCustomTreeWidget, self).__init__(parent)
self.setDragEnabled(True)
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.resize(360,240)
def dragEnterEvent (self, eventQDragEnterEvent):
sourceQCustomTreeWidget = eventQDragEnterEvent.source()
if isinstance(sourceQCustomTreeWidget, QCustomTreeWidget):
if self != sourceQCustomTreeWidget:
sourceQCustomTreeWidget.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
eventQDragEnterEvent.accept()
else:
sourceQCustomTreeWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
QtGui.QTreeWidget.dragEnterEvent(self, eventQDragEnterEvent)
else:
QtGui.QTreeWidget.dragEnterEvent(self, eventQDragEnterEvent)
def dropEvent (self, eventQDropEvent):
sourceQCustomTreeWidget = eventQDropEvent.source()
if isinstance(sourceQCustomTreeWidget, QCustomTreeWidget):
if self != sourceQCustomTreeWidget:
sourceQCustomTreeWidget.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
sourceQTreeWidgetItem = sourceQCustomTreeWidget.currentItem()
isFound = False
for column in range(0, self.columnCount()):
sourceQString = sourceQTreeWidgetItem.text(column)
listsFoundQTreeWidgetItem = self.findItems(sourceQString, QtCore.Qt.MatchExactly, column)
if listsFoundQTreeWidgetItem:
isFound = True
break
if not isFound:
(sourceQTreeWidgetItem.parent() or sourceQCustomTreeWidget.invisibleRootItem()).removeChild(sourceQTreeWidgetItem)
self.invisibleRootItem().addChild(sourceQTreeWidgetItem)
else:
sourceQCustomTreeWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
QtGui.QTreeWidget.dropEvent(self, eventQDropEvent)
else:
QtGui.QTreeWidget.dropEvent(self, eventQDropEvent)
class QCustomQWidget (QtGui.QWidget):
def __init__ (self, parent = None):
super(QCustomQWidget, self).__init__(parent)
self.my1QCustomTreeWidget = QCustomTreeWidget(self)
self.my2QCustomTreeWidget = QCustomTreeWidget(self)
items = [QtGui.QTreeWidgetItem([name]) for name in ['Item_1', 'Item_2', 'Item_3', 'Item_4', 'Item_5']]
self.my1QCustomTreeWidget.addTopLevelItems(items)
self.allQHBoxLayout = QtGui.QHBoxLayout()
self.allQHBoxLayout.addWidget(self.my1QCustomTreeWidget)
self.allQHBoxLayout.addWidget(self.my2QCustomTreeWidget)
self.setLayout(self.allQHBoxLayout)
app = QtGui.QApplication([])
myQCustomQWidget = QCustomQWidget()
myQCustomQWidget.show()
sys.exit(app.exec_())
Useful reference for event handle
【讨论】:
以上是关于如何阻止 QTreeWidget 在拖放时创建重复项的主要内容,如果未能解决你的问题,请参考以下文章