I've made a QtGui.LineEdit()
widget in a python script using pySide Qt bindings and I'd like to be able to drag a file from the desktop into the QLineEdit to set the text in the QLineEdit to the path of the file. I've done QLineEdit.setDragEnabled(True)
to enable drag and drop operations but I'm a bot lost about how to procede from here. Does anyone know how to achieve this?
Usually, for events you can use the QObject.eventFilter and QObject.installEventFilter to do intercept events and process them. However, it does not seem to work for QDrag/QDrop events (and if I'm wrong on this - someone else please let me know as I've about pulled all my hair out trying to figure the way to get it to work with filtering).
The best way I know how to do it, you have to subclass the QLineEdit and overload the dragEnterEvent, dragMoveEvent and dropEvent methods to check to see if what is being dragged into your class is valid. Something like:
from PySide.QtGui import QLineEdit
class FileEdit(QLineEdit):
def __init__( self, parent ):
super(FileEdit, self).__init__(parent)
self.setDragEnabled(True)
def dragEnterEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
event.acceptProposedAction()
def dragMoveEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
event.acceptProposedAction()
def dropEvent( self, event ):
data = event.mimeData()
urls = data.urls()
if ( urls and urls[0].scheme() == 'file' ):
# for some reason, this doubles up the intro slash
filepath = str(urls[0].path())[1:]
self.setText(filepath)
Using the eventFilter mechanism, mentioned above, does work, when used like this:
from PyQt4.QtCore import QObject, QEvent
class QLineEditDropHandler(QObject):
def eventFilter(self, watched, event):
if event.type() == QEvent.DragEnter:
# we need to accept this event explicitly to be able to receive QDropEvents!
event.accept()
if event.type() == QEvent.Drop:
md = event.mimeData()
if md.hasUrls():
obj.setText(url.toLocalFile())
return True
return super().eventFilter(watched, event)
Now, one can use the drop handler on any line edit without subclassing:
lineEdit.installEventFilter(QLineEditDropHandler(self))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With