2013-12-08 4 views
2

현재 PyQt4와 qrcode4.0.4을 사용하고 있습니다.Python (PyQt)에서 QR 코드 만들기

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 docs에서 자신 만의 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)