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

setPixmap crashing when trying to show image in label

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

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

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" 共享相同的内存,并且如屏幕截图所示,它是一个局部变量,当它被删除时,关联的内存也会被删除,因此 QLabel 的 QPbelmap 在尝试访问信息时将生成 分段错误 。解决办法是做一个副本,这样他们就不会共享同一个内存

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