QPixmap и GUI-потоки - PullRequest
       9

QPixmap и GUI-потоки

0 голосов
/ 14 сентября 2018

Я пытаюсь запустить небольшой пример с тем, чтобы поток делал снимок экрана и отправлял его в приложение с графическим интерфейсом для отображения.Но я получаю эту «ошибку»

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_()

1 Ответ

0 голосов
/ 14 сентября 2018

С документы :

Прямое подключение Слот вызывается сразу же, когда излучается сигнал.Слот выполняется в потоке эмиттера, который не обязательно является потоком получателя.

Указывая Qt.DirectConnection при подключении вашего сигнала, вы вызываете вызываемый метод с помощью CaptureScreenthread, то есть вы создаете QPixmap вне вашего потока GUI.

Исправляет ли изменение типа соединения значение Qt.QueuedConnection?

...