我目前正在使用PyQt4和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))
正如您所看到的,在您获得屏幕上的图像之前,有几个障碍需要通过。 QR码以RGBA PIL图像开始,然后转换为RGB,然后转换为PIL ImageQt对象,然后转换为QPixmap,然后将QPixmap放置在带有缩放修复的QLabel上。
如果您没有显式存储imgQt引用,则在加载窗口小部件时会出现垃圾。
我的问题:我能做些什么来改善这一点,因为它似乎涉及很多转换。
答案 0 :(得分:4)
从qrcode文档中,您可以创建自己的image_factory
,这可能会让您简化流程。
您只需要继承qrcode.image.base.BaseImage
并重新实现new_image
,drawrect
和save
方法。该子类可以包装QImage,因此无需PIL转换步骤。
<强>更新强>:
这是一个消除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_())
答案 1 :(得分:3)
您还可以使用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)
答案 2 :(得分:1)
mgmax很好的答案,但仅限Python2。对于Python3,使用:
import qrcode
from io import BytesIO
def set_qr_label(label, text):
"""
set qrcode image on QLabel
@param label: QLabel
@param text: text for the QR code
"""
buf = BytesIO()
img = qrcode.make(text)
img.save(buf, "PNG")
label.setText("")
qt_pixmap = QtGui.QPixmap()
qt_pixmap.loadFromData(buf.getvalue(), "PNG")
label.setPixmap(qt_pixmap)
答案 3 :(得分:-1)
这是ekhumoro答案在python3中的pyqt5中工作 希望它能帮助某人。
from PyQt5 import QtWidgets, QtCore, QtGui
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(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.label = QtWidgets.QLabel(self)
self.edit = QtWidgets.QLineEdit(self)
self.edit.returnPressed.connect(self.handleTextEntered)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.label)
layout.addWidget(self.edit)
def handleTextEntered(self):
text = self.edit.text()#text = unicode(self.edit.text())
self.label.setPixmap(
qrcode.make(text, image_factory=Image).pixmap())
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 300, 200, 200)
window.show()
sys.exit(app.exec_())