Drag and drop files to QListWidget created with QT-Designer

Question:

i am trying to implement a drag and drop feature to PyQt5 QListWidget

it works if self.acceptDrops(True) is in the code but it works on whole application window and wherever i drag file in the window it will add a file to QListWidget…

My goal is to enable drag and drop only on QListWidget area. Please help me with some solution. Unfortunately i am stuck with this.

The Code is:

class okno_glowne(qtw.QWidget):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.ui = Ui_main_new()
        self.ui.setupUi(self)
    
        #self.setAcceptDrops(True)

     def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
            print("Coś się udaje")
        else:
            event.ignore()

    def dropEvent(self, event):

    
        if event.mimeData().hasFormat('application/x-qabstractitemmodeldatalist'):
            if event.source() == self.ui.lista_excele_drag:
                event.acceptProposedAction()
        for url in event.mimeData().urls():
             file_path = url.toLocalFile()
             self.ui.lista_excele_drag.addItem(file_path)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
             self.drag_start_position = event.pos()

    def mouseMoveEvent(self, event):
        if not (event.buttons() & Qt.LeftButton):
             return

        if (event.pos() - self.drag_start_position).manhattanLength() <QApplication.startDragDistance():
        return

        drag = QDrag(self)
         mime_data = QMimeData()
        mime_data.setText(self.ui.lista_excele_drag.currentItem().text())
        drag.setMimeData(mime_data)
        drag.exec_(Qt.CopyAction)

if __name__ == '__main__':
app =qtw.QApplication([])
Widget = okno_glowne()
Widget = QtWidgets.QStackedWidget()
w = okno_glowne()
w.show()
app.exec_()

Now the modified code with class in another file named mylistwidget.py

Okay , so i have done a research and i found out promoting widgets is easy ,but not as easy as to implement the code to work 😀 now , the dragEnter event works fine ( it is printing ) , but the rest as drop and mouse does not…

from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QMimeData
from PyQt5.QtGui import QDrag

class MyListWidget(QListWidget):

# def __init__(self, *args, **kwargs):
#     QListWidget().__init__(self, *args, **kwargs)
    def __init__(self, parent=None):
        QListWidget().__init__(parent)
        self.setAcceptDrops(True)
    

    def dragEnterEvent(self, event):
        print("dragEnterEvent")
        if event.mimeData().hasUrls():
             event.accept()
        else:
             event.ignore()

    def dropEvent(self, event):
        print("dropEvent")
        if event.mimeData().hasUrls():
            for url in event.mimeData().urls():
                path = url.toLocalFile()
                item = QListWidgetItem(path)
                self.addItem(item)
            event.accept()
        else:
            event.ignore()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drag_start_position = event.pos()

    def mouseMoveEvent(self, event):
        if not (event.buttons() & Qt.LeftButton):
            return

        if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
            return

        drag = QDrag(self)
        mime_data = QMimeData()
        mime_data.setText(self.currentItem().text())
        drag.setMimeData(mime_data)
        drag.exec_(Qt.CopyAction)

Answers:

Okay i got it…

To override drop function and initialize it i had to add new function:

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

Now it works like a charm.

Thanks for your contribution!

Answered By: Sebastian Kasperski