Archive

Archive for March, 2010

PyQt, PIL and Windows

March 16th, 2010 18 comments

Edit: Although the following approach works on a small sample application, as the app gets more complex it’s less likely to work. I’ve moved to just using PyQt images in the GUI, and PIL images in the backend. If anyone has any ideas on how to make this work let me know in the comments.


Here’s a fun one. If you’re using PIL and PyQt4, you may want to display a PIL image in your PyQt GUI. This is a multi-step process.

kitten.jpg

kitten.jpg

  1. Create your PIL image (you can use my kitten if you want).

  2. Create an ImageQt image from your PIL image (this is PIL’s version of a QImage).

  3. Create a QPixmap from your ImageQt image.

  4. Create a QLabel and set its QPixmap to be the one just created.

And the above in code:

im = Image.open('kitten.jpg')
myQtImage = ImageQt.ImageQt(PilImage)
pixmap = QtGui.QPixmap.fromImage(myQtImage)
label = QtGui.QLabel('', self)
label.setPixmap(pixmap)

This works fine on Linux, but on Windows it crashes python.exe. I think the problem is with the ImageQt object. According to its documentation. To quote:

Creates an ImageQt object from a PIL image object. This class is a subclass of QtGui.QImage, which means that you can pass the resulting objects directly to PyQt4 API functions and methods.

On Windows it seems that it isn’t quite this easy. There is a simple solution though. Just make a new QImage from the ImageQt object:

myQtImage2 = QtGui.QImage(myQtImage1)

and this seems to turn the fake QImage into a real QImage, which can now be happily turned into a QPixmap.

Here’s a fully working program to illustrate the above in context (this is Python 2.6):

import sys
from PyQt4 import QtCore, QtGui
import Image
import ImageQt


class MyWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 400, 293)
        self.setWindowTitle('My Widget!')


        PilImage = Image.open('kitten.jpg')
        QtImage1 = ImageQt.ImageQt(PilImage)
        QtImage2 = QtGui.QImage(QtImage1)
        pixmap = QtGui.QPixmap.fromImage(QtImage2)
        label = QtGui.QLabel('', self)
        label.setPixmap(pixmap)


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    myWidget = MyWidget()
    myWidget.show()

    sys.exit(app.exec_())
Kitten program screenshot

Look – it works!

Categories: Programming Tags: , ,