Create QR-code in Python (PyQt)

pyqt, python, python-imaging-library, qpixmap, qr-code

Solution

From the qrcode docs, it appears you can create your own `image_factory`, which might allow you to streamline the process.

You just need to subclass `qrcode.image.base.BaseImage` and reimplement the `new_image`, `drawrect` and `save` methods. This subclass could wrap a QImage and therefore eliminate the need for the PIL conversion step.

UPDATE:

Here's a demo that eliminates the PIL dependency (which is just as well, because I found PIL crashes with certain inputs):

from PyQt4 import QtGui, QtCore
import qrcode

class Image(qrcode.image.base.BaseImage):
    def __init__(self, border, width, box_size):
        self.border = border
        self.width = width
        self.box_size = box_size
        size = (width + border * 2) * box_size
        self._image = QtGui.QImage(
            size, size, QtGui.QImage.Format_RGB16)
        self._image.fill(QtCore.Qt.white)

    def pixmap(self):
        return QtGui.QPixmap.fromImage(self._image)

    def drawrect(self, row, col):
        painter = QtGui.QPainter(self._image)
        painter.fillRect(
            (col + self.border) * self.box_size,
            (row + self.border) * self.box_size,
            self.box_size, self.box_size,
            QtCore.Qt.black)

    def save(self, stream, kind=None):
        pass

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.label = QtGui.QLabel(self)
        self.edit = QtGui.QLineEdit(self)
        self.edit.returnPressed.connect(self.handleTextEntered)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.label)
        layout.addWidget(self.edit)

    def handleTextEntered(self):
        text = unicode(self.edit.text())
        self.label.setPixmap(
            qrcode.make(text, image_factory=Image).pixmap())

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 200, 200)
    window.show()
    sys.exit(app.exec_())

Problem

I'm currently using PyQt4 and qrcode4.0.4. ``` from PyQt4 import QtGui, QtCore from PIL.ImageQt import ImageQt import qrcode class QRLabel(QtGui.QLabel): def __init__(self, text=""): super(QRLabel, self).__init__() self.setCode(text) def setCode(self, text=""): self.text = text qrImg = qrcode.make(text) imgQt = ImageQt(qrImg.convert("RGB")) # keep a reference! pixm = QtGui.QPixmap.fromImage(imgQt) self.setPixmap(pixm.scaled(self.size(),QtCore.Qt.KeepAspectRatio)) ``` As you can see, there are several hurdles to be passed before you get the image on your screen. The QR code starts as a RGBA PIL Image, it is converted to RGB, then to PIL ImageQt object, then to a QPixmap, which is then placed on a QLabel with a scaling fix. If you don't explicitly store the imgQt reference, you get rubbish when you load the widget. My question: is there anything I could do to improve this, as it seems there are so many conversions involved.

Original source