Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt: How do I handle QPixmaps from a QThread?

This has to be the biggest nuisance I've encountered with PyQT: I've hacked together a thumbnailing thread for my application (I have to thumbnail tons of big images), and it looks like it would work (and it almost does). My main problem is this error message whenever I send a SIGNAL from my thread:

QPixmap: It is not safe to use pixmaps outside the GUI thread

I can't figure out how to get around this. I've tried passing a QIcon through my SIGNAL, but that still generates the same error. If it helps, here's the code blocks which deal with this stuff:

The Thumbnailer class:

class Thumbnailer(QtCore.QThread):
  def __init__(self, ListWidget, parent = None):
    super(Thumbnailer, self).__init__(parent)
    self.stopped = False
    self.completed = False
    self.widget = ListWidget

  def initialize(self, queue):
    self.stopped = False
    self.completed = False
    self.queue = queue

  def stop(self):
    self.stopped = True

  def run(self):
    self.process()
    self.stop()

  def process(self):
    for i in range(self.widget.count()):
      item = self.widget.item(i)

      icon = QtGui.QIcon(str(item.text()))
      pixmap = icon.pixmap(72, 72)
      icon = QtGui.QIcon(pixmap)
      item.setIcon(icon)

The part which calls the thread (it occurs when a set of images is dropped onto the list box):

  self.thread.images.append(f)

  item = QtGui.QListWidgetItem(f, self.ui.pageList)
  item.setStatusTip(f)

  self.thread.start()

I'm not sure how to handle this kind of stuff, as I'm just a GUI newbie ;)

Thanks to all.

like image 397
Blender Avatar asked Dec 22 '22 19:12

Blender


1 Answers

After many attempts, I finally got it. I can't use a QIcon or QPixmap from within a non-GUI thread, so I had to use a QImage instead, as that transmits fine.

Here's the magic code:

Excerpt from the thumbnailer.py QThread class:

  icon = QtGui.QImage(image_file)
  self.emit(QtCore.SIGNAL('makeIcon(int, QImage)'), i, icon)

makeIcon() function:

  def makeIcon(self, index, image):
    item = self.ui.pageList.item(index)
    pixmap = QtGui.QPixmap(72, 72)
    pixmap.convertFromImage(image) #   <-- This is the magic function!
    icon = QtGui.QIcon(pixmap)
    item.setIcon(icon)

Hope this helps anyone else trying to make an image thumbnailing thread ;)

like image 73
Blender Avatar answered Dec 24 '22 07:12

Blender