Pyside 从一个 ListView 拖放到另一个
Posted
技术标签:
【中文标题】Pyside 从一个 ListView 拖放到另一个【英文标题】:Pyside Drag and Drop from one ListView to another 【发布时间】:2020-03-29 09:23:57 【问题描述】:我正在尝试深入研究 QlistView 和模型,因此明确使用了 QListWidgets 以上的内容。但是我确实有问题使从一个拖放到另一个成为可能。更准确地说,到目前为止,我还没有捕捉到任何事件。
我必须简单的列表。其中之一按预期显示项目。但是一旦我将项目拖到另一个列表中,应用程序就会关闭。 目前我只有简单的数据,但是一旦我弄清楚了接口,这些数据可能会变得更加复杂。
一个简化和精简的版本:
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import QStringListModel
class ListView(QtWidgets.QListView):
def __init__(self, items=[], parent=None):
super(ListView, self).__init__(parent)
self.setDragEnabled(True)
self.setAcceptDrops(True)
self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
self.setDropIndicatorShown(True)
self.setMaximumWidth(250)
model = ListModel(items)
self.setModel(model)
def dragEnterEvent(self, event):
super(ListView, self).dragEnterEvent(event)
print event
def dragLeaveEvent(self, event):
super(ListView, self).dragLeaveEvent(event)
print event
def dragMoveEvent(self, event):
super(ListView, self).dragMoveEvent(event)
print event
def dropEvent(self, event):
super(ListView, self).dropEvent(event)
print event
class ListModel(QStringListModel):
def __init__(self, items, *args, **kwargs):
super(ListModel, self).__init__(*args, **kwargs)
self.items = items or []
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return self.items[index.row()]
def rowCount(self, index):
return len(self.items)
class View(QtWidgets.QWidget):
def __init__(self):
super(View, self).__init__()
self.list_one = ListView(["Peter", "Bjoern", "John"], parent=self)
self.list_two = ListView(parent=self)
main_layout = QtWidgets.QHBoxLayout()
main_layout.addWidget(self.list_one)
main_layout.addWidget(self.list_two)
self.setLayout(main_layout)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
view = View()
view.show()
app.exec_()
【问题讨论】:
【参考方案1】:至少你需要设置 QMimeData 文本以便它被传递,然后在dropEvent
设置新的列表模型。
def dragEnterEvent(self, event):
if not event.mimeData().hasText():
event.mimeData().setText(self.currentIndex().data())
event.accept()
def dragMoveEvent(self, event):
if event.mimeData().hasText():
event.accept()
else:
event.ignore()
def dropEvent(self, event):
if event.mimeData().hasText():
items = self.model().items + [event.mimeData().text()]
self.setModel(ListModel(items))
event.accept()
else:
event.ignore()
结果:
【讨论】:
每次丢弃物品时都必须创建模型似乎效率低下。我不认为这是正确的。 当然没必要,我只是展示了如何让拖放工作。 有人还有完整的代码吗?我试过这个,它在 PySide2 和 PySide6 上都有段错误以上是关于Pyside 从一个 ListView 拖放到另一个的主要内容,如果未能解决你的问题,请参考以下文章