简体   繁体   中英

How to stop QTreeWidget from creating the item duplicates on Drag and Drop

The code below creates QTreeWidget with five items. The self.setDragDropMode(self.InternalMove) flag assures that when the item is dragged on top of another there will be no copy of it made (so the number of items always stay the same).

在此处输入图片说明

If we replace this line with self.setDragDropMode(self.DragDrop) then every time an item is dragged/dropped a new copy of will be created.

在此处输入图片说明

Since I don't want a copy of item to be created on every dragAndDrop event I would be happy with InternalMove flag if it wouldn't be blocking QTreeWidget from accepting the drops from outside of its own view (if InternalMove flag is set QTreeWidget does not allow dragging-dropping from another QTreeWidget , QListView or File Browser).
Is there a way to set an override so QTreeWidget doesn't create a duplicate of dragged item and yet allows a dropping from outside of its own window.

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_())

The key to solving this problem is that you have to implement when the object has moved to the next QListsWidget and check whether or not the data is duplicated or not. Take the data from source to destination by removing the source and adding this data to destination QListsWidget .

Use two methods, dragEnterEvent and dropEvent , to handle them all;

  1. Implemented dragEnterEvent Check object to move is same QListsWidget .

  2. Implemented dropEvent Check data is duplicated or not And take data from source to destination.

Example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM