如何阻止QTreeWidget在拖放时创建项目重复项

时间:2014-08-09 20:47:37

标签: python pyqt

以下代码会创建包含五个项目的QTreeWidgetself.setDragDropMode(self.InternalMove)标志确保当项目被拖动时 另一个将没有它的副本(所以项目的数量始终保持不变)。

enter image description here

如果我们用self.setDragDropMode(self.DragDrop)替换此行,则每次拖放项目时都会创建一个新副本。

enter image description here

由于我不希望在每个dragAndDrop事件上创建项目的副本,所以如果它不会阻止InternalMove阻止QTreeWidget接受来自外部的丢弃,我会对InternalMove标志感到满意。它自己的视图(如果设置QTreeWidget标志QTreeWidget不允许从另一个QTreeWidget,QListView或文件浏览器中拖放。)
有没有办法设置覆盖,因此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}}

1 个答案:

答案 0 :(得分:1)

解决此问题的关键是您必须在对象移动到下一个QListsWidget时实施,并检查数据是否重复。通过删除源并将此数据添加到目标QListsWidget来获取源到目标的数据。

使用两种方法dragEnterEventdropEvent来处理所有这些方法;

  1. 已实施dragEnterEvent检查要移动的对象是QListsWidget

  2. 已实施dropEvent检查数据是否重复并将数据从源传送到目的地。

  3. 示例:

    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