Как уметь перетаскивать элементы между QListWidgets и все еще иметь возможность сортировки с помощью перетаскивания - PullRequest
1 голос
/ 17 апреля 2019

У меня есть два унаследованных класса QListView: SourceListWidget и AcceptListWidget. Я хочу иметь возможность копировать элементы из SourceListWidget в AcceptListWidget и по-прежнему иметь возможность сортировать их в AcceptListWidget с помощью перетаскивания.

В приведенном ниже коде все работает так, как я хочу, но AcceptListWidget невозможно отсортировать с помощью перетаскивания.Также мне интересно, есть ли способ вставить элемент в AcceptListWidget из SourceListWidget вместо того, чтобы просто добавить его в конец.

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_())

Основной аспект, который я пытаюсьfix - это внутренняя сортировка AcceptListWidget, но если предметы можно было бы уронить в определенные места от SourceListWidget до AcceptListWidget, это было бы еще лучше.

1 Ответ

1 голос
/ 17 апреля 2019

По умолчанию 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())
...