尝试在标签中显示图像时 setPixmap 崩溃

问题描述:

我使用 pyqt 设计器创建了一个最小示例,它在按下按钮时更改标签的文本,并且应该通过标签在窗口中显示屏幕截图.

I have created a minimal example with pyqt designer, that changes the text of a label when a button is pressed and is supposed to present a screenshot in the window, via the label.

不幸的是,该示例在尝试在标签中显示屏幕截图时崩溃了.

Unfortunately, the example just crashes when it tries to show the screenshot in the label.

from PIL.ImageQt import ImageQt
from PyQt5 import QtCore, QtGui, QtWidgets
from pyscreenshot import grab

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(503, 382)
        self.pushButton = QtWidgets.QPushButton(Form)
        self.pushButton.setGeometry(QtCore.QRect(70, 30, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(80, 100, 47, 14))
        self.label.setObjectName("label")

        self.retranslateUi(Form)
        self.pushButton.clicked.connect(lambda: self.take_screenshot())
        QtCore.QMetaObject.connectSlotsByName(Form)

    def take_screenshot(self):
        self.label.setText("1?")
        screenshot = grab()
        self.label.setText("2")
        qim = ImageQt(screenshot)
        pix = QtGui.QPixmap.fromImage(qim)
        self.label.setText("3")
        self.label.setPixmap(pix)



    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.pushButton.setText(_translate("Form", "PushButton"))
        self.label.setText(_translate("Form", "TextLabel"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

"screenshot" 和 "qimg" 共享内存,截图是一个局部变量,当消去相关内存时,QPbelmap 也被消去QLabel 在尝试访问信息时会产生一个Segmentation fault.解决方案是制作一个副本,这样它们就不会共享相同的内存

"screenshot" shares the same memory with "qimg", and as screenshot it is a local variable that when eliminated the associated memory is also eliminated so the QPbelmap of the QLabel when trying to access information will generate a Segmentation fault. The solution is to make a copy so that they do not share the same memory

def take_screenshot(self):
    screenshot = grab()
    qim = ImageQt(screenshot).copy()
    pix = QtGui.QPixmap.fromImage(qim)
    self.label.setPixmap(pix)
    self.label.adjustSize()