user12586796
user12586796

Reputation:

Passing multiple parameters back from PyQt thread

Is there a way to pass multiple parameters from a thread back to the main thread at the same time?

I have started a thread using PyQt5 in which two real time variables are calculated. I want to pass both parameters back to the main thread to be combined and calculated with parameters from another thread.

As attached in the code below, I am able to return each parameter individually and print to the screen. How do I return all parameters into one function so I can proceed with calculations from another thread?

Thank you!

import sys
import time

from PyQt5.QtWidgets import QMainWindow, QPushButton, QVBoxLayout, QFrame, QApplication
from PyQt5.QtCore import pyqtSignal, QObject, QThread

class Counter(QObject):
    '''
    Class intended to be used in a separate thread to generate numbers and send
    them to another thread.
    '''
    param1 = pyqtSignal(str)
    param2 = pyqtSignal(str)
    stopped = pyqtSignal()


    def __init__(self):
        QObject.__init__(self)

    def start(self):
        '''
        Count from 0 to 99 and emit each value to the GUI thread to display.
        '''
        for x in range(4):
            self.param1.emit(str(x))
            self.param2.emit(str(x)+'2')
            time.sleep(0.7)
        self.stopped.emit()

class Application(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)

        # Configuring widgets        
        self.button = QPushButton()
        self.button.setText('99')
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.button)
        self.frame = QFrame()
        self.frame.setLayout(self.layout)
        self.setCentralWidget(self.frame)

        # Configuring separate thread
        self.counterThread = QThread()
        self.counter = Counter()
        self.counter.moveToThread(self.counterThread)

        # Connecting signals
        self.button.clicked.connect(self.startCounting)        
        self.counter.param1.connect(self.button.setText)
        self.counter.param1.connect(self.someFunction1)    
        self.counter.param2.connect(self.someFunction2)       
        self.counter.stopped.connect(self.counterThread.quit)
        self.counterThread.started.connect(self.counter.start)

    # print data from parameter 1
    def someFunction1(self, data):
        print(data + ' in main')

    # print data from parameter 2
    def someFunction2(self, data):
        print(data + ' in main') 

    def startCounting(self):
        if not self.counterThread.isRunning():
            self.counterThread.start()  

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Application()
    window.show()
    sys.exit(app.exec_())

Upvotes: 0

Views: 3667

Answers (1)

eyllanesc
eyllanesc

Reputation: 243955

The signals also support the transmission of lists so you can use it to transport several variables:

class Counter(QObject):
    """
    Class intended to be used in a separate thread to generate numbers and send
    them to another thread.
    """

    params = pyqtSignal(list)
    stopped = pyqtSignal()

    def start(self):
        """
        Count from 0 to 99 and emit each value to the GUI thread to display.
        """
        for x in range(4):
            values = [str(x), str(x) + "2"]
            self.params.emit(values)
            time.sleep(0.7)
        self.stopped.emit()


class Application(QMainWindow):
    def __init__(self):
        super(Application, self).__init__()
        # Configuring widgets
        self.frame = QFrame()

        self.button = QPushButton("99")
        lay = QVBoxLayout(self.frame)
        lay.addWidget(self.button)
        self.setCentralWidget(self.frame)

        # Configuring separate thread
        self.counterThread = QThread()
        self.counter = Counter()
        self.counter.moveToThread(self.counterThread)

        # Connecting signals
        self.button.clicked.connect(self.startCounting)
        self.counter.params.connect(self.someFunction)
        self.counter.stopped.connect(self.counterThread.quit)
        self.counterThread.started.connect(self.counter.start)

    @pyqtSlot(list)
    def someFunction(self, params):
        print(params)
        if params:
            self.button.setText(params[0])

    def startCounting(self):
        if not self.counterThread.isRunning():
            self.counterThread.start()

Upvotes: 1

Related Questions