Skip to content

Instantly share code, notes, and snippets.

@benjaminirving
Last active March 10, 2023 19:15
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save benjaminirving/f45de3bbabbcacd3ca29 to your computer and use it in GitHub Desktop.
Save benjaminirving/f45de3bbabbcacd3ca29 to your computer and use it in GitHub Desktop.
Pyside example of dragging and dropping a file onto a GUI. See http://www.birving.com/blog/2015/09/29/drag-and-drop-files-into-gui-using/
"""
A simple example pyside app that demonstrates dragging and dropping
of files onto a GUI.
- This app allows dragging and dropping of an image file
that this then displayed in the GUI
- Alternatively an image can be loaded using the button
- This app includes a workaround for using pyside for dragging and dropping
with OSx
- This app should work on Linux, Windows and OSx
"""
from __future__ import division, unicode_literals, print_function, absolute_import
from PySide import QtGui, QtCore
import sys
import platform
# Use NSURL as a workaround to pyside/Qt4 behaviour for dragging and dropping on OSx
op_sys = platform.system()
if op_sys == 'Darwin':
from Foundation import NSURL
class MainWindowWidget(QtGui.QWidget):
"""
Subclass the widget and add a button to load images.
Alternatively set up dragging and dropping of image files onto the widget
"""
def __init__(self):
super(MainWindowWidget, self).__init__()
# Button that allows loading of images
self.load_button = QtGui.QPushButton("Load image")
self.load_button.clicked.connect(self.load_image_but)
# Image viewing region
self.lbl = QtGui.QLabel(self)
# A horizontal layout to include the button on the left
layout_button = QtGui.QHBoxLayout()
layout_button.addWidget(self.load_button)
layout_button.addStretch()
# A Vertical layout to include the button layout and then the image
layout = QtGui.QVBoxLayout()
layout.addLayout(layout_button)
layout.addWidget(self.lbl)
self.setLayout(layout)
# Enable dragging and dropping onto the GUI
self.setAcceptDrops(True)
self.show()
def load_image_but(self):
"""
Open a File dialog when the button is pressed
:return:
"""
#Get the file location
self.fname, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file')
# Load the image from the location
self.load_image()
def load_image(self):
"""
Set the image to the pixmap
:return:
"""
pixmap = QtGui.QPixmap(self.fname)
pixmap = pixmap.scaled(500, 500, QtCore.Qt.KeepAspectRatio)
self.lbl.setPixmap(pixmap)
# The following three methods set up dragging and dropping for the app
def dragEnterEvent(self, e):
if e.mimeData().hasUrls:
e.accept()
else:
e.ignore()
def dragMoveEvent(self, e):
if e.mimeData().hasUrls:
e.accept()
else:
e.ignore()
def dropEvent(self, e):
"""
Drop files directly onto the widget
File locations are stored in fname
:param e:
:return:
"""
if e.mimeData().hasUrls:
e.setDropAction(QtCore.Qt.CopyAction)
e.accept()
# Workaround for OSx dragging and dropping
for url in e.mimeData().urls():
if op_sys == 'Darwin':
fname = str(NSURL.URLWithString_(str(url.toString())).filePathURL().path())
else:
fname = str(url.toLocalFile())
self.fname = fname
self.load_image()
else:
e.ignore()
# Run if called directly
if __name__ == '__main__':
# Initialise the application
app = QtGui.QApplication(sys.argv)
# Call the widget
ex = MainWindowWidget()
sys.exit(app.exec_())
@KengoSawa2
Copy link

Thank you for a wonderful sample!!
I think, this bug is a thorny issue for pyside and pyqt.
I was in trouble in QTBUG40449, I was able to work around the problem in your favor:)

@benjaminirving
Copy link
Author

@KengoSawa2, glad the example was useful 👍

@Huston94
Copy link

Great example. Easy to follow and understand what's happening. Helped me a ton. Thanks a bunch.

@TyLaneTech
Copy link

Is there an updated version for python 3?

@benjaminirving
Copy link
Author

Is there an updated version for python 3?

Good point @TyLaneTech. This needs an update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment