2013-12-08 69 views
2

我目前使用PyQt4和qrcode4.0.4在Python中创建QR码(PyQt)

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)) 

正如您所看到的,在屏幕上显示图像之前需要传递几个障碍。 QR码从RGBA PIL图像开始,转换为RGB,然后转换为PIL ImageQt对象,然后转换为QPixmap,然后将其放在具有缩放修正的QLabel上。

如果您没有明确存储imgQt引用,那么当您加载小部件时,您会收到垃圾信息。

我的问题:有什么我可以做,以改善这一点,因为它似乎有这么多的转换涉及。

回答

3

从qrcode文档看来,您可以创建自己的image_factory,这可能允许您简化流程。

您只需要子类qrcode.image.base.BaseImage并重新实​​现new_image,drawrectsave方法。这个子类可以包装一个QImage,因此不需要PIL转换步骤。

UPDATE

下面是消除PIL依赖演示(这是一样好,因为我发现PIL与特定输入崩溃):

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_()) 
2

您还可以使用PNG作为一个中间格式并使用StringIO将其存储在内存中。

import qrcode 
import StringIO 

def set_qr_label(label, text): 
    """ 
    set qrcode image on QLabel 

    @param label: QLabel 
    @param text: text for the QR code 
    """ 
    buf = StringIO.StringIO() 
    img = qrcode.make(text) 
    img.save(buf, "PNG") 
    label.setText("") 
    qt_pixmap = QtGui.QPixmap() 
    qt_pixmap.loadFromData(buf.getvalue(), "PNG") 
    label.setPixmap(qt_pixmap)