簡體   English   中英

在 PyQt5 中的 QTreeWidget 和 QListWidget 之間拖動項目?

[英]Drag items between QTreeWidget and QListWidget in PyQt5?

我有一個 QListWidget 和一個 QTreeWidget,我希望能夠在每個列表項內以及它們之間拖動一個或多個列表項。 我有內部拖放工作,但我不確定如何在它們之間拖動。

在此處輸入圖片說明

當我在下面的代碼中打印event.mimeData().formats() ,它顯示['application/x-qabstractitemmodeldatalist'] 我被困在如何提取該項目的文本和索引(它應該是 QListWidgetItem 或 QTreeWidgetItem,對嗎?)所以我可以從源小部件中刪除原始項目並將新項目添加到目標小部件,我該怎么做那?

我嘗試使用這里的代碼:
https://wiki.python.org/moin/PyQt/Handling%20Qt%27s%20internal%20item%20MIME%20type

因此,目前當我在小部件之間拖動項目時,我的代碼會獲得一個 QVariant 項目,但我仍然不知道如何處理這些項目以獲取項目文本和索引。

from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QTreeWidgetItem
import sys

class Tree(QtWidgets.QTreeWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setDragDropMode(self.DragDrop)
        self.setSelectionMode(self.ExtendedSelection)
        self.setAcceptDrops(True)

        for text in ['tree1','tree2','tree3']:
            treeItem = QtWidgets.QTreeWidgetItem(self, [text])
            treeItem.setFlags(treeItem.flags() & ~QtCore.Qt.ItemIsDropEnabled)
            self.addTopLevelItem(treeItem)

    def dropEvent(self, event):
        if event.source() == self:
            event.setDropAction(QtCore.Qt.MoveAction)
            super().dropEvent(event)
        elif isinstance(event.source(), QtWidgets.QListWidget):
            item = self.itemAt(event.pos())
            ix = self.indexAt(event.pos())
            col = 0 if item is None else ix.column()
            item = self.invisibleRootItem() if item is None else item
            ba = event.mimeData().data('application/x-qabstractitemmodeldatalist')
            data_items = decode_data(ba)
            for data_item in data_items:
                it = QtWidgets.QTreeWidgetItem()
                item.addChild(it)
                for data in data_items:
                    for r, v in data.items():
                        it.setData(col, r, v)


class List(QtWidgets.QListWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setDragDropMode(self.DragDrop)
        self.setSelectionMode(self.ExtendedSelection)
        self.setAcceptDrops(True)

        for text in ['list1','list2','list3']:
            self.addItem(text)

    def dropEvent(self, event):
        if event.source() == self:
            event.setDropAction(QtCore.Qt.MoveAction)
            QtWidgets.QListWidget.dropEvent(self, event)
        elif isinstance(event.source(), QtWidgets.QTreeWidget):
            item = self.itemAt(event.pos())
            row = self.row(item) if item else self.count()
            ba = event.mimeData().data('application/x-qabstractitemmodeldatalist')
            data_items = decode_data(ba)
            for i, data_item in enumerate(data_items):
                it = QtWidgets.QListWidgetItem()
                self.insertItem(row+i, it)
                for r, v in data_item.items():
                    it.setData(r,v)


def decode_data(bytearray):

    data = []
    item = {}

    ds = QtCore.QDataStream(bytearray)
    while not ds.atEnd():

        row = ds.readInt32()
        column = ds.readInt32()

        map_items = ds.readInt32()
        for i in range(map_items):
            key = ds.readInt32()

            value = QtCore.QVariant()
            ds >> value
            item[Qt.ItemDataRole(key)] = value

        data.append(item)
    return data

if __name__=='__main__':

    app = QtWidgets.QApplication(sys.argv)

    layout = QtWidgets.QHBoxLayout()
    layout.addWidget(Tree())
    layout.addWidget(List())

    container = QtWidgets.QWidget()
    container.setLayout(layout)
    container.show()

    app.exec_()

您必須使用 decode_data 返回的信息創建項目,這些信息是每個拖動項目的角色和值:

class Tree(QtWidgets.QTreeWidget):
    # ...

    def dropEvent(self, event):
        if event.source() == self:
            event.setDropAction(QtCore.Qt.MoveAction)
            super().dropEvent(event)
        elif isinstance(event.source(), QtWidgets.QListWidget):
            item = self.itemAt(event.pos())
            ix = self.indexAt(event.pos())
            col = 0 if item is None else ix.column()
            item = self.invisibleRootItem() if item is None else item            
            ba = event.mimeData().data('application/x-qabstractitemmodeldatalist')
            data_items = decode_data(ba)
            for data_item in data_items:
                it = QtWidgets.QTreeWidgetItem()
                item.addChild(it)
                for data in data_items:
                    for r, v in data.items():
                        it.setData(col, r, v)

class List(QtWidgets.QListWidget):
    # ... 

    def dropEvent(self, event):
        if event.source() == self:
            event.setDropAction(QtCore.Qt.MoveAction)
            QtWidgets.QListWidget.dropEvent(self, event)
        elif isinstance(event.source(), QtWidgets.QTreeWidget):
            item = self.itemAt(event.pos())
            row = self.row(item) if item else self.count()
            ba = event.mimeData().data('application/x-qabstractitemmodeldatalist')
            data_items = decode_data(ba)
            for i, data_item in enumerate(data_items):
                it = QtWidgets.QListWidgetItem()
                self.insertItem(row+i, it)
                for r, v in data_item.items():
                    it.setData(r,v)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM