How to get dropped file names in PyQt/PySide

12,690

The QMimeData class has methods for dealing with dropped urls. Below is a minimal working example:

# from PyQt4.QtGui import QApplication, QLabel
# from PySide2.QtWidgets import QApplication, QLabel
from PyQt5.QtWidgets import QApplication, QLabel

class Window(QLabel):
    def __init__(self):
        super().__init__()
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        print('drag-enter')
        if event.mimeData().hasUrls():
            print('has urls')
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        lines = []
        for url in event.mimeData().urls():
            lines.append('dropped: %r' % url.toLocalFile())
        self.setText('\n'.join(lines))
    
app = QApplication(['Drag & Drop'])
window = Window()
window.setGeometry(50, 100, 400, 300)
window.show()
app.exec_()

UPDATE:

Regarding the additions to the question:

Some widgets (unlike the QLabel used above) have a default implementation of dragMoveEvent that explicitly ignores most events. For example, classes based on QAbstractItemView may only handle certain kinds of internal move and ignore everything else. In which case, a reimplementation of dragMoveEvent should be added that explicitly accepts the events that need to be handled differently:

class MyView(QTableView):
    ...
    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            super().dragMoveEvent(event)
Share:
12,690

Related videos on Youtube

TimothyAWiseman
Author by

TimothyAWiseman

Nevada appellate and business law attorney, former SQL Server DBA and former U.S. Army Officer.

Updated on June 04, 2022

Comments

  • TimothyAWiseman
    TimothyAWiseman almost 2 years

    I am trying to set up an application that will accept havin files dropped into it. So, I am looking for a way to extract the path when they are dropped in.

    Right now, I have drag and drop enabled for the right part of the application, and it will accept text dropped in, but I do not know how to handle having a file dropped in.

    I am using:

    def PTE_dragEnterEvent(self, e):
        if e.mimeData().hasFormat('text/plain'):
            e.accept()
        else:
            e.ignore() 
    
    def PTE_dropEvent(self, e):
        newText = self.ui.fileListPTE.toPlainText() + '\n\n' + e.mimeData().text()
        self.ui.fileListPTE.setPlainText(newText)
    

    Which is slightly modifying the code provided in the Zetcode Drag and Drop tutorial.


    I couldn't quite get @ekhumoro answer to work for me, but it gave me more places to look, and I found Drag and drop files into QListWidget which helped.

    In addition to the suggestions made by ekhumoro I needed to implement the drag move event. What I finally used looked like:

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()
            
    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()
    
    def dropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            
            newText = self.ui.fileListPTE.toPlainText()
            for url in event.mimeData().urls():
                newText += '\n' + str(url.toLocalFile())
            self.ui.fileListPTE.setPlainText(newText)
            self.emit(QtCore.SIGNAL("dropped"))
        else:
            event.ignore()