简体   繁体   English

使用 Signal 将 QImage 从工作线程传递到主 UI 线程以在 pyqt5 GUI 中显示(Python)

[英]Use Signal to pass QImage from a Worker Thread to Main UI Thread to Display in pyqt5 GUI (Python)

I'm trying to define my own signal to display QImage (converted from raw data) upon a button press.我正在尝试定义自己的信号以在按下按钮时显示 QImage (从原始数据转换而来)。 The GUI has a button called as connect, and a QLabel that's named as DisplayRect. GUI 有一个名为 connect 的按钮和一个名为 DisplayRect 的 QLabel。 I'd like to draw this QImage on DisplayRect.我想在 DisplayRect 上绘制这个 QImage。 The code below prints 'signal received' upon pressing the connect button.下面的代码在按下连接按钮时打印“收到信号”。 I'd like to make it pass QImage so that I can self.DisplayRect.setPixmap(the passed QImage ) Please have a look:我想让它通过 QImage 以便我可以self.DisplayRect.setPixmap( 传递的 QImage )请看一下:

class DPSignal(QObject):
    dpsig = pyqtSignal()
    
    def run(self):
        self.dpsig.emit()
        
        
        
class DisplayThread(QThread):
    def __init__(self, parent):
        super().__init__(parent)
        self.parent = parent
        
        
    def run(self):
        dps = DPSignal()
        dps.dpsig.connect(self.parent.dpupdate)
        dps.run
        
class WindowClass(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUI(self)
        
       self.connectButton.clicked.connect(self.connectFunction)
       
       
       
       
       
    @pyqtSlot()
    def connectFunction(self):
        dpThread = DisplayThread(self)
        dpThread.start()
        
    def dpupdate(self):
        print("signal received")
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = WindowClass()
    myWindow.show()
    app.exec_()

This piece of code below reads binary data from a file and I'd like to add this code to somewhere in DisplayThread so that it passes the processed QImage to the main UI thread.下面的这段代码从文件中读取二进制数据,我想将此代码添加到 DisplayThread 中的某个位置,以便它将处理后的 QImage 传递给主 UI 线程。 Then main UI thread can (I suppose) self.DisplayRect.setPixmap to display.然后主 UI 线程可以(我想)self.DisplayRect.setPixmap 来显示。 Thanks for reading谢谢阅读

raw = rawpy.imread(...path...)
src = raw.postprocess()
buf = src.data.tobytes()
h, w, ch = src.shape
bytesperline = ch * whileimage = QImage(buf, 1024, 768, bytesperline, QImage.Format_RGB888)

self.DisplayRect.setPixmap(QPixmap.fromImage(image))
self.DisplayRect.show()

You can try moving the object to the QThread using the QObject.moveToThread and then doing the prepocessing in the run method.您可以尝试使用QObject.moveToThread将 object 移动到QThread ,然后在run方法中进行预处理。 Then transfer the raw bytes through the signal to the Main Window and create and show the image from the Main Window.然后通过信号将原始字节传输到 Main Window 并创建并显示来自 Main Window 的图像。


class DPSignal(QObject):
    dpsig = pyqtSignal([bytes, int])
    finished = pyqtSignal()

    def __init__(self, parent):
        super().__init__()
        self.parent = parent

    def run(self):
        raw = rawpy.imread("./file.nef")
        src = raw.postprocess()
        buf = src.data.tobytes()
        h, w, ch = raw.shape
        bpl = w * ch
        self.dpsig.emit(buf, bpl)
        self.finished.emit()


class WindowClass(QMainWindow):
    def __init__(self):
        super().__init__()
        self.connectButton.clicked.connect(self.connectFunction)

    @pyqtSlot()
    def connectFunction(self):
        self.worker = DPSignal(self)
        self.dpThread = QThread()
        self.worker.moveToThread(self.dpThread)
        self.dpThread.started.connect(self.worker.run)
        self.worker.dpsig.connect(self.dpupdate)
        self.worker.finished.connect(self.dpThread.exit)
        self.worker.finished.connect(self.dpThread.deleteLater)
        self.dpThread.start()

    def dpupdate(self, buf, bpl):
        print("signal received")
        image = QImage(buf, 1024, 768, bpl, QImage.Format.Format_RGB888)
        self.DisplayRect.setPixmap(QPixmap.fromImage(image))
        self.DisplayRect.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWindow = WindowClass()
    myWindow.show()
    app.exec_()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM