Передача нескольких параметров обратно из потока PyQt - PullRequest
0 голосов
/ 01 февраля 2020

Есть ли способ передать несколько параметров из потока обратно в основной поток одновременно?

Я запустил поток, используя PyQt5, в котором вычисляются две переменные реального времени. Я хочу передать оба параметра обратно в основной поток, который будет объединен и рассчитан с параметрами из другого потока.

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

Спасибо!

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

1 Ответ

1 голос
/ 01 февраля 2020

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

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