2013-12-08 108 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)