在PyQt5中的QTreeWidget和QListWidget之间拖动项目?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在PyQt5中的QTreeWidget和QListWidget之间拖动项目?相关的知识,希望对你有一定的参考价值。
我有一个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(Qt.MoveAction)
QtWidgets.QTreeWidget.dropEvent(self, event)
else:
bytearray = event.mimeData().data('application/x-qabstractitemmodeldatalist')
data_items = decode_data(bytearray)
for item in data_items:
print(item)
# What do I do with this?
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(Qt.MoveAction)
QtWidgets.QListWidget.dropEvent(self, event)
else:
bytearray = event.mimeData().data('application/x-qabstractitemmodeldatalist')
data_items = decode_data(bytearray)
for item in data_items:
print(item)
# What do I do with this?
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)
以上是关于在PyQt5中的QTreeWidget和QListWidget之间拖动项目?的主要内容,如果未能解决你的问题,请参考以下文章
PyQt5复杂控件(树控件选项卡控件(滚动条控件多文档控件停靠控件)