[PyQt] How to use a pixmap in a thread ?

Vincent Vande Vyvre vincent.vandevyvre at swing.be
Sat Mar 6 08:04:57 GMT 2010


Hi,

In a image viewer I need to show a list of pictures into a trailer.

Since the source folder contain a large amount of pictures, I want to
create they thumbnails
in a thread, but PyQt return an error.

    QPixmap::scaled: Pixmap is a null pixmap
    QPixmap: It is not safe to use pixmaps outside the GUI thread

Extract of my code:

# -*- coding: utf-8 -*-

import os
import time
import glob
from threading import Thread

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.resize(900, 600)
        MainWindow.setWindowTitle("Icon-trailer")
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
        self.verticalLayout = QtGui.QVBoxLayout()
        self.scene = QtGui.QGraphicsScene()
        self.view = QtGui.QGraphicsView(self.scene)
        self.verticalLayout.addWidget(self.view)
        self.ico_trail = QtGui.QListWidget(self.centralwidget)
        self.ico_trail.setMaximumSize(QtCore.QSize(9999, 100))
       
self.ico_trail.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
       
self.ico_trail.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.ico_trail.setIconSize(QtCore.QSize(100, 100))
        self.ico_trail.setFlow(QtGui.QListView.LeftToRight)
        self.verticalLayout.addWidget(self.ico_trail)
        self.gridLayout.addLayout(self.verticalLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)

        self.images = glob.glob("/home/vincent/Images/Disk2/*")
        self.trl = Trailer(self.images)
        self.trl.start()

class Trailer(Thread):
    def __init__(self, imgs):
        self.imgs = imgs
        Thread.__init__(self)

    def run(self):
        for i in self.imgs:
            img = QtGui.QPixmap(i)
            pix = img.scaled(160, 160, QtCore.Qt.KeepAspectRatio,
                            QtCore.Qt.FastTransformation)
            time.sleep(0.2)
            obj = QtGui.QListWidgetItem(ui.ico_trail)
            obj.setIcon(QtGui.QIcon(pix))
            obj.setFlags(QtCore.Qt.ItemIsSelectable |
                            QtCore.Qt.ItemIsEnabled)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())


Thanks, vincent



More information about the PyQt mailing list