Python PySide2 / PyQt5 : drag and drop from one QListWidget to another - drag custom object derived from QListWidgetItem

Viewed 22

So I've been trying to get the drag and drop working on PyQt5 / PySide2. I am aware this has been covered in other places, however I have read those and they do not answer my questions or match my case. So this is for you, my fellow newbies, who are searching in the future.

What I want to do is drag a custom object (called EquipmentItem), which is derived from QListWidgetItem from one QListWidget to another.

So far I have the basics, and I will show the code in a moment. I can do the drag and drop, but there are two problems. The first, which is the main one, is that when the item is dropped, it stops being an EquipmentItem and becomes a QListWidgetItem. Now the code is fairly basic and quite clearly I need more to make it work. But there seems to be a bit of a lack of information on this, so far as I can find. Most tutorials seem to presume that there is some data stored in the dragMoveEvent's parameter (type: QDropEvent) Mime data. But in my case this contains nothing. HasText = False. HasHTML = False. HasColor = False. HasImage = False. HasURLs = False. The second problem is that I can drag and drop into the original QListWidget.

So let me now paste the code for QListWidgetExtended, which I have derived from QListWidgetExtended.

class QListWidgetExtended(QListWidget):
    def __init__(self, parent):
        super(QListWidgetExtended, self).__init__(parent)

        self.setDragDropMode(QAbstractItemView.DragDrop)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            super(QListWidgetExtended, self).dragEnterEvent(event)

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            super(QListWidgetExtended, self).dragMoveEvent(event)

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            self.emit(SIGNAL("dropped"), links)
        else:
            event.setDropAction(Qt.MoveAction)
            super(QListWidgetExtended, self).dropEvent(event)

Is most of this copied from sources and not useful for me? Yes I think so. For example, if I'm getting no mime data there seems to be no point in checking for URLs. If someone could explain that, by the way, I would be grateful: why does everyone check for URLs in these examples?

Still, really all that's happening is the default actions for the class and I appreciate that's the case. The class derived from QListWidgetItem, EquipmentItem, has nothing in it that I need to show here (no drag drop event stuff or PySide2 stuff, just a couple of extra attributes).

The above does work but, as I said, with the two problems that I haven't been able to solve. If you can help, I would appreciate it.

Edit: here is the code for EquipmentItem:

class EquipmentItem(QListWidgetItem):
    def __init__(self, parent=None, name=''):
        QListWidgetItem.__init__(self, parent)

        self.parent = parent
        self.parentOriginal = None
        self.name = name
        self.ownerID = -1

    def __repr__(self):
        return f'EquipmentItem: {self.name}'

    def SetOwnerID(self, ownerID):
        self.ownerID = ownerID

    def SetTextWithTranslation(self, qCoreAppObj, windowName, text):
        if text == None:
            text = f'{self.name}'
        self.setText(qCoreAppObj.translate(windowName, text, None))
0 Answers
Related