'PyQt5: Update Image py emitting pyqtSignal doesn't work

I created a GUI. In the class which is inheriting from QWidget i designed the gui and defined the functions for my buttons. In the class Worker() i am editing values in a while loop and i want to update constantly the Image. But unfortunately I receive the following error:

TypeError: update() missing 1 required positional argument: 'data3'

Here is my code:

from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QGridLayout# (the example applies equally well to PySide2)
from PyQt5.QtGui import QFont
from PyQt5.QtCore import QThread, QObject, pyqtSignal
import pyqtgraph as pg
import numpy as np
import time



class Worker(QObject):

    finished = pyqtSignal()  # give worker class a finished signal
    update_signal = pyqtSignal(np.ndarray)

    def __init__(self, parent=None):
        QObject.__init__(self, parent=parent)
        self.update_signal.connect(Gui.update)
        
    def do_work(self):
        
        self.run=True
        while self.run:
                
            data3 = np.zeros((160, 160)) + 1
            self.update_signal.emit(data3)

            time.sleep(0.1)

        self.finished.emit()  # emit the finished signal when the loop is done

    def stop(self):
        self.run = False  # set the run condition to false on stop    



class Gui(QWidget):

    stop_signal = pyqtSignal()  # make a stop signal to communicate with the worker in another thread

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        btn = QPushButton('Start', self)
        btn.setFont(QFont('Arial', 12))
        btn.resize(120,50)
        btn2 = QPushButton('Stop', self)
        btn2.setFont(QFont('Arial', 12))
        btn2.resize(120,50)
        btn3 = QPushButton('Close')
        btn3.setFont(QFont('Arial', 12))
        btn3.resize(120,50)
        btn3.clicked.connect(self.close)
        plotwin = pg.GraphicsView()
        p = pg.PlotItem() 
        plotwin.setCentralItem(p)

        data = np.empty(shape=(160,160))
        cmap = pg.colormap.getFromMatplotlib('hot')
        self.img = pg.ImageItem(image=data)  
        
        p.addItem(self.img)
        ay = p.getAxis('left')
        ax = p.getAxis('bottom')   
        ticks = [16, 32, 48, 64, 80, 96, 112, 128, 144, 160]
        ticks_label = {16:'1', 32:'2', 48:'3', 64:'4', 80:'5', 96:'6', 112:'7', 128:'8', 144:'9', 160:'10'}
        ay.setTicks([[(v, ticks_label[v]) for v in ticks ]])
        ax.setTicks([[(v, ticks_label[v]) for v in ticks ]])
        p.addColorBar(self.img, colorMap = cmap, values=(0, 255))
        
        ## Create a grid layout to manage the widgets size and position
        layout = QGridLayout(self)
        self.setLayout(layout)
        
        ## Add widgets to the layout in their proper positions
        layout.addWidget(btn, 0, 0)   # button goes in upper-left
        layout.addWidget(btn2, 1, 0)   # text edit goes in middle-left
        layout.addWidget(btn3, 2, 0)  # list widget goes in bottom-left
        layout.addWidget(plotwin, 0, 1, 3, 1)  # plot goes on right side, spanning 3 rows
        self.setGeometry(50,50,700,700)
        self.setWindowTitle('Abstrahlcharakteristik')
        self.show()
        

        # Thread:
        self.thread = QThread()
        self.worker = Worker()
        self.stop_signal.connect(self.worker.stop)  # connect stop signal to worker stop method
        self.worker.moveToThread(self.thread)

        self.worker.finished.connect(self.thread.quit)  # connect the workers finished signal to stop thread
        self.worker.finished.connect(self.worker.deleteLater)  # connect the workers finished signal to clean up worker
        self.thread.finished.connect(self.thread.deleteLater)  # connect threads finished signal to clean up thread

        self.thread.started.connect(self.worker.do_work)
        self.thread.finished.connect(self.worker.stop)

        # Start Button action:
        btn.clicked.connect(self.thread.start)

        # Stop Button action:
        btn2.clicked.connect(self.stop_thread)

        self.show()

    def update(self, data3):
        self.img.setImage(data3)
    
    # When stop_btn is clicked this runs. Terminates the worker and the thread.
    def stop_thread(self):
        self.stop_signal.emit()  # emit the finished signal on stop
        data2 = np.zeros((160,160))
        self.img.setImage(data2)


if __name__ == '__main__':
    #app = QApplication([])
    gui = Gui()
    #app.exec_()

Everything is working fine instead of the update function. I don't know why the data which I have inserted right is missing when the function is called.

Thanks in advance.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source