在 QTreeWidget 之间拖放

问题描述 投票:0回答:1

是否可以在两个 QTreeWidget 之间拖放两个项目?我有一个树小部件tree1和第二个树小部件tree2。 Tree1 在某种程度上是包含所有元素的主元素(仅顶级元素,子元素被禁用)。只能进行排序(不能编辑、移动、复制等)。 Tree2 应包含通过从 tree1 拖放添加的项目。这个想法是,如果一个项目从tree1移动到tree2,它就会从tree1中删除。在tree2中,项目可以移动(仅此而已)。我已经检查过互联网但无法真正找到解决方案。我尝试重写 QTreeWidget 类的拖放方法,但目前我不了解拖放机制。 如果将项目从 tree1 拖到 tree2,我看不到任何事件。

from PyQt5 import QtCore, QtGui, QtWidgets




class TreeWidget(QtWidgets.QTreeWidget):


    def dropEvent(self, event):
        if event.source()==self:
            super().dropEvent(event)

        elif isinstance(event.source(), TreeWidget):
            print(True)


def create_treeWidget_1():
    treeWidget=TreeWidget()
    treeWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
    treeWidget.setAlternatingRowColors(True)
    treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
    treeWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
    treeWidget.setHeaderHidden(False)
    treeWidget.setDragEnabled(True)

    treeWidget.headerItem().setText(0, "Header 0")
    treeWidget.headerItem().setText(1, "Header 1")
    treeWidget.headerItem().setText(2, "Header 2")

    item_0=QtWidgets.QTreeWidgetItem(treeWidget)
    item_0=QtWidgets.QTreeWidgetItem(treeWidget)
    treeWidget.topLevelItem(0).setText(0, "y1")
    treeWidget.topLevelItem(0).setText(1, "y2")
    treeWidget.topLevelItem(0).setText(2, "y3")
    treeWidget.topLevelItem(1).setText(0, "z1")
    treeWidget.topLevelItem(1).setText(1, "z2")
    treeWidget.topLevelItem(1).setText(2, "z3")
    
    return treeWidget


def create_treeWidget_2():
    treeWidget=TreeWidget()
    treeWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
    treeWidget.setAlternatingRowColors(True)
    treeWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
    treeWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
    treeWidget.setHeaderHidden(False)
    treeWidget.setDragEnabled(True)
    treeWidget.viewport().setAcceptDrops(True)
    treeWidget.setDropIndicatorShown(True)
    treeWidget.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)

    treeWidget.headerItem().setText(0, "Header 0")
    treeWidget.headerItem().setText(1, "Header 1")
    treeWidget.headerItem().setText(2, "Header 2")

    item_0=QtWidgets.QTreeWidgetItem(treeWidget)
    item_0.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsEnabled)
    item_0=QtWidgets.QTreeWidgetItem(treeWidget)
    item_0.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsEnabled)
    treeWidget.topLevelItem(0).setText(0, "a")
    treeWidget.topLevelItem(0).setText(1, "b")
    treeWidget.topLevelItem(0).setText(2, "c")
    treeWidget.topLevelItem(1).setText(0, "1")
    treeWidget.topLevelItem(1).setText(1, "2")
    treeWidget.topLevelItem(1).setText(2, "3")
    
    return treeWidget




if __name__ == "__main__":
    import sys

    app=QtWidgets.QApplication(sys.argv)
    app.setStyle("fusion")
    tree1=create_treeWidget_1()
    tree2=create_treeWidget_2()
    tree1.show()
    tree2.show()
    sys.exit(app.exec_())

希望有人能帮忙。谢谢。

python pyqt5 drag-and-drop qtreewidget
1个回答
0
投票

您需要重写 QTreeWidget 子类中的

dragMoveEvent
dragEnterEvent
方法以及
dropEvent
,并接受这些方法中的事件以便接收
dropEvent
。否则
dropEvent
将永远不会被触发。

由于您的目标本质上是将项目从一棵树移动到另一棵树,因此在放置事件中,您可以将事件的

dropAction
设置为
Qt.DropAction.MoveAction
,因为默认情况下只是复制它。然后,您需要从事件对象中获取 mimedata 并将其添加到 TreeWidget 的模型中。最后接受 DropEvent,以便成功从源树中删除该行。

例如:

from PyQt5.QtCore import Qt, QModelIndex

class TreeWidget(QtWidgets.QTreeWidget):

    def dropEvent(self, event):
        action = Qt.DropAction.MoveAction
        mime = event.mimeData()
        row = self.topLevelItemCount()
        col = 0
        event.setDropAction(action)
        self.model().dropMimeData(mime, action, row, col, QModelIndex())
        event.accept()

    def dragMoveEvent(self, event):
        if event.mimeData().hasFormat('application/x-qabstractitemmodeldatalist'):
            event.accept()
        return super().dragMoveEvent(event)

    def dragEnterEvent(self, event):
        if event.mimeData().hasFormat('application/x-qabstractitemmodeldatalist'):
            event.accept()
        return super().dragEnterEvent(event)
© www.soinside.com 2019 - 2024. All rights reserved.