python - 如何能够在 QListWidgets 之间拖放项目并且仍然能够使用拖放进行排序
问题描述
我有两个 QListView 继承类,一个SourceListWidget
我AcceptListWidget
希望能够将项目从复制SourceListWidget
到,AcceptListWidget
并且仍然能够AcceptListWidget
使用拖放对它们进行排序。
在下面的代码中,一切都按照我想要的方式工作,除了AcceptListWidget
无法使用拖放进行排序。另外我想知道是否有一种方法可以将项目插入AcceptListWidget
from theSourceListWidget
而不是仅将其附加到末尾。
import sys
from PyQt5.QtWidgets import QApplication, QWidget, \
QVBoxLayout, QListWidget, QAbstractItemView
from PyQt5.QtGui import QDragMoveEvent, QDropEvent
from PyQt5.QtCore import Qt, QMimeData
import typing
class AcceptListWidget(QListWidget):
def __init__(self):
super().__init__()
self.setDefaultDropAction(Qt.MoveAction)
self.setDragDropMode(QAbstractItemView.InternalMove)
self.setAcceptDrops(True)
def dragEnterEvent(self, e: QDragMoveEvent) -> None:
e.accept()
def dragMoveEvent(self, e: QDragMoveEvent) -> None:
e.accept()
def mimeTypes(self) -> typing.List[str]:
return ['text/json']
def mimeData(self, indexes) -> QMimeData:
drag_data = indexes[0].text()
mime_data = QMimeData()
mime_data.setText(drag_data)
return mime_data
def dropEvent(self, event: QDropEvent) -> None:
event.setDropAction(Qt.CopyAction) if event.source() != self else event.setDropAction(Qt.MoveAction)
if event.source() != self:
self.addItem(event.mimeData().text())
class SourceListWidget(QListWidget):
def __init__(self):
super().__init__()
self.setDragDropMode(QAbstractItemView.DragDrop)
def dragMoveEvent(self, e: QDragMoveEvent) -> None:
e.accept() if e.source() != self else e.ignore()
def mimeTypes(self) -> typing.List[str]:
return ['text/json']
def mimeData(self, indexes) -> QMimeData:
drag_data = indexes[0].text()
mime_data = QMimeData()
mime_data.setText(drag_data)
return mime_data
def dropMimeData(self, index: int, data: QMimeData, action: Qt.DropAction) -> bool:
print('dropMimeData')
drop_data = data.data('text')
for item in drop_data:
if item in self.stringList():
self.removeRow(self.stringList().index(item))
return True
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, event: QDropEvent) -> None:
event.setDropAction(Qt.MoveAction)
event.accept()
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.widget_layout = QVBoxLayout()
self.accept_widget = AcceptListWidget()
self.accept_widget.setFlow(QListWidget.LeftToRight)
# Create ListWidget and add 10 items to move around.
self.list_widget = SourceListWidget()
self.list_widget.setFlow(QListWidget.LeftToRight)
for x in range(1, 11):
self.list_widget.addItem('Item {:02d}'.format(x))
for x in range(1, 2):
self.accept_widget.addItem('Item {:02d}'.format(x))
self.widget_layout.addWidget(self.accept_widget)
self.widget_layout.addWidget(self.list_widget)
self.setLayout(self.widget_layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = Widget()
widget.show()
sys.exit(app.exec_())
我要解决的主要方面是内部排序,AcceptListWidget
但如果可以将项目放入某些地方SourceListWidget
,AcceptListWidget
那就更好了。
解决方案
默认情况下,QListWidget 接受项目的重新排序,因此您只需在源为外部时调用父级的方法:
def dropEvent(self, event: QDropEvent) -> None:
if event.source() is self:
super().dropEvent(event)
else:
event.setDropAction(Qt.CopyAction)
self.addItem(event.mimeData().text())
推荐阅读
- node.js - 匹配路由时节点代理源重写
- java - 这里究竟做了什么?尝试将代码从 Java 传输到 NodeJS
- python - 在消息 [discord.py] 上创建 DM
- php - Laravel 模型批量更新 - Builder::cleanBindings() 必须是数组类型,给定 null
- reactjs - 如何在 Socket.io 中触发真正的错误?
- flutter - 从外部更新 RepaintBoundary 内部
- generics - 通用数学运算符重载而不复制
- docker - 有没有办法将 USER 保留在 docker 基础映像上?
- c++ - 将一对映射到结构
- r - 如何在 r 中使用 VIF?