PyQt Drag Images into List Widget for Thumbnail List

This simple tutorial shows how you can create a program with Python and Qt to allow for image files from Explorer/Finder/Nautilus to be dropped in a list widget and create list items with thumbnails

droppedthumbnails

First we subclass a QListWidget to handle events

class DragDropListWidget(QListWidget):
	def __init__(self, type, parent=None):
		super(DragDropListWidget, self).__init__(parent)
		self.setAcceptDrops(True)
		self.setIconSize(QSize(72, 72))
 
	def dragEnterEvent(self, event):
		if event.mimeData().hasUrls:
			event.accept()
		else:
			event.ignore()
 
	def dragMoveEvent(self, event):
		if event.mimeData().hasUrls:
			event.setDropAction(Qt.CopyAction)
			event.accept()
		else:
			event.ignore()
 
	def dropEvent(self, event):
		if event.mimeData().hasUrls:
			event.setDropAction(Qt.CopyAction)
			event.accept()
			l = []
			for url in event.mimeData().urls():
				l.append(str(url.toLocalFile()))
			self.emit(SIGNAL("dropped"), l)
		else:
			event.ignore()

The initialiser simply allows drops into the widget. It also makes sure thumbnails are well visible.

Then each event performs a check to make sure the object being dropped is indeed a file. Finally, at the drop, the class sends an event with a list of local files dropped. Of course all handling could be done within the class but I will eventually need to manage dropped files in a parent form so an event is used here.

self.connect(self.pictureListWidget, SIGNAL("dropped"), self.pictureDropped)

In the parent class, I first connect the signal I defined in the custom list widget.

def pictureDropped(self, l):
	for url in l:
		if os.path.exists(url):
			picture = Image.open(url)
			picture.thumbnail((72, 72), Image.ANTIALIAS)
			icon = QIcon(QPixmap.fromImage(ImageQt.ImageQt(picture)))
			item = QListWidgetItem(os.path.basename(url)[:20] + "...", self.pictureListWidget)
			item.setStatusTip(url)
			item.setIcon(icon)

Here the Image and ImageQt modules of PIL are used to process the images. The Image class can help to create a thumbnail of the opened image. ImageQt can then convert the Image class into an ImageQt class which is a subclass of QImage. QIcons can only be constructed from QPixmap so we build one from the ImageQt class and send it to make a QIcon.

There you go, you now have a working list widget which allow image files to be dropped and can list them with thumbnail.

Of course, this snippet doesn’t check for other file types being dropped. More code would take away the focus.

Related posts:

  1. Deploy PyQt Applications on Mac OS X with PyInstaller!
  2. PyQt and Snow Leopard
  3. Python Log Stdout to File
  4. Qt with C++ or Python Tutorial

  • Pingback: Qt with C++ or Python Tutorial | Xster.net

  • Jo

    i would like to thank you for this post. it indeed saved me at least 2 day of search and try.
    although i want to mention that your “if event.mimeData().hasUrls:” is allways true as (i think) that you test for the method of mimeData(). i guess you wanted to test whether the thing you are draging is some kind of file. thus you should test “if event.mimeData().hasUrls():”, which tests the actual presence of an url in the mimeData.

  • http://joe76shields.livejournal.com/577.html Hipolito Shave

    Great, thanks for sharing this blog post.Thanks Again.

  • nubbe

    PIL just kept crashing on me, so here’s a version without PIL:

    Replace in def pictureDropped:
    if os.path.exists(url):
    qIcon = QtGui.QIcon()
    qIcon.addPixmap(QtGui.QPixmap(url), QtGui.QIcon.Normal, QtGui.QIcon.Off)
    item = QtGui.QListWidgetItem(os.path.basename(url)[:20] + “…”, self.ui.listView)
    item.setStatusTip(url)
    item.setIcon(qIcon)