QPixmap和GUI线程

问题描述 投票:0回答:1

我正在尝试获取一个小示例,并使用Thread执行屏幕截图并将其发送到要显示的GUI应用程序。但我得到这个“错误”

QPixmap: It is not safe to use pixmaps outside the GUI thread

我试过阅读,但很难理解为什么它给我这个,因为QImage是在主应用程序和GUI线程中制作的?

我希望我的标签显示线程捕获的图像。

class Main(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.setGeometry(300, 300, 280, 600)
        self.layout = QtGui.QVBoxLayout(self)

        self.testButton = QtGui.QPushButton("Click Me")
        self.connect(self.testButton, QtCore.SIGNAL("clicked()"), self.Capture)

        self.layout.addWidget(self.testButton)

        self.label_ = QLabel(self)
        self.label_.move(280, 120)
        self.label_.resize(640, 480)
        self.layout.addWidget(self.label_)


    @pyqtSlot(QImage) 
    def ChangeFrame(self, image):  
        qimg = QImage(image.data, image.shape[1], image.shape[0], QImage.Format_RGB888)

        self.label_.setPixmap(QPixmap.fromImage(qimg))


    def Capture(self):       
        self.thread_ = CaptureScreen()        
        self.connect(self.thread_, QtCore.SIGNAL("ChangeFrame(PyQt_PyObject)"), self.ChangeFrame, Qt.DirectConnection)
        self.thread_.start()       

class CaptureScreen(QtCore.QThread):
    pixmap = pyqtSignal(QImage)

    def __del__(self):
        self.exiting = True
        self.wait()

    def run(self):    
        img = ImageGrab.grab(bbox=(100,10,400,780))
        img_np = np.array(img)
        frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)        

        self.emit( QtCore.SIGNAL("ChangeFrame(PyQt_PyObject)"), frame)



app = QtGui.QApplication(sys.argv)
test = Main()
test.show()
app.exec_()
python pyqt pyqt4
1个回答
2
投票

来自the docs

Direct Connection在发出信号时立即调用插槽。插槽在发射器的线程中执行,该线程不一定是接收器的线程。

通过在连接信号时指定Qt.DirectConnection,您将导致CaptureScreen线程调用connected方法,这意味着您正在GUI线程之外创建QPixmap。

将连接类型更改为Qt.QueuedConnection是否可以解决问题?

© www.soinside.com 2019 - 2024. All rights reserved.