I have two QListView inherited classes, a SourceListWidget
and AcceptListWidget
I want to be able to copy items from SourceListWidget
to AcceptListWidget
and still be able to sort them in the AcceptListWidget
using dragging and dropping.
In the code below everything works the way I want it to other than the AcceptListWidget
is unable to be sorted using drag and drop. Also I'm wondering if there's a way to insert an item into the AcceptListWidget
from the SourceListWidget
instead of just appending it to the end.
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_())
The major aspect that I'm trying to fix is the internal sorting of the AcceptListWidget
but if items can be dropped into certain places from SourceListWidget
to AcceptListWidget
that would be even better.
答案 0 :(得分:1)
默认情况下,QListWidget接受项目的重新排序,因此您仅需在源为外部时调用父方法:
forEach