我正在尝试获取一个小示例,并使用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_()
来自the docs:
Direct Connection在发出信号时立即调用插槽。插槽在发射器的线程中执行,该线程不一定是接收器的线程。
通过在连接信号时指定Qt.DirectConnection
,您将导致CaptureScreen
线程调用connected方法,这意味着您正在GUI线程之外创建QPixmap。
将连接类型更改为Qt.QueuedConnection
是否可以解决问题?