在PyQt5中的QTreeWidget和QListWidget之间拖动项目? [英] Drag items between QTreeWidget and QListWidget in PyQt5?

查看:166
本文介绍了在PyQt5中的QTreeWidget和QListWidget之间拖动项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个QListWidget和QTreeWidget,并且我希望能够在每个项目中以及它们之间以及它们之间拖动一个或多个列表项.我有内部拖放功能,但不确定如何在它们之间拖动.

I have a QListWidget and a QTreeWidget and I want to be able to drag one or multiple list items around within each one as well as between them. I have the internal drag and drop working, but I'm not sure how to drag between them.

当我在下面的代码中打印 event.mimeData().formats()时,其显示为 ['application/x-qabstractitemmodeldatalist'] .我被困在如何提取该项目的文本和索引(它应该是QListWidgetItem或QTreeWidgetItem,对吗?)上,所以我可以从源窗口小部件中删除原始项目并将新项目添加到目标窗口小部件中,我该怎么办那?

When I print event.mimeData().formats() in my code below it says ['application/x-qabstractitemmodeldatalist']. I am stuck on how to extract the text and index of that item (it should be a QListWidgetItem or QTreeWidgetItem, right?) so I can delete the original from the source widget and add a new item to the destination widget, how do I do that?

我尝试从此处使用代码:
https://wiki.python.org/moin/PyQt/Handling%20Qt%27s%20internal%20item%20MIME%20type

I tried using code from here:
https://wiki.python.org/moin/PyQt/Handling%20Qt%27s%20internal%20item%20MIME%20type

因此,当我在小部件之间拖动项目时,我的代码获得了QVariant项目,但是我仍然不知道该如何处理以获取项目文本和索引.

So currently my code gets a QVariant items when I drag items between the widgets, but I still don't know what to do with those to get the item text and index.

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返回的信息来创建项目,这些信息是所拖动的每个项目的作用和值:

You have to create the items using the information returned by decode_data which are the roles and values of each item dragged:

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)

这篇关于在PyQt5中的QTreeWidget和QListWidget之间拖动项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆