如何将多个复杂的信号随时间发送至同一槽位?

问题描述 投票:0回答:1

我在Spyder3.8上使用PyQT5.10编写一个GUI。 用户输入几个参数,包括字符串、整数和浮点数,然后按 "Go "按钮,启动一个新的线程,在这个线程中存储参数,并由一个函数进行计算。 线程应该是马上从GUI中获取几个参数,另外GUI有按钮,可以向线程发送新的参数,希望能在线程中飞速更新各个参数。 我的问题是:是否可以在不同的时间使用signalsslots将所有这些intstrfloat参数发送到同一个线程? 有什么特别的策略是最好的吗? 我已经附上了一个缩小版的脚本,在线程中运行的函数叫做 "runner"。 当前错误。

TypeError: runner() missing 26 required positional arguments.

(只有发送的第一个参数被线程接收到)

我见过其他例子,其中有多个相同类型的参数被发送到一个槽中,但没有像这样复杂的例子。

import stuff

class ClassProcessingThread(QObject):
    signalStatus = pyqtSignal(str)
    sendreset = pyqtSignal()
    sendquit = pyqtSignal()

    def __init__(self):
        super().__init__()
        # Make GUI
        # Start thread

class ThreadClass(QObject):
    def __init__(self):
        super().__init__()

    @pyqtSlot(int)
    @pyqtSlot(float)
    @pyqtSlot(str)
    def runner(self, param1, param2, param3, param4): 
        self.p1=param1    
        self.p2=param2   
        self.p3=param3
        self.p4=param4  
        #Do stuff with the params

class WidgetGallery(QDialog):
    signalStatus = pyqtSignal(str)
    sendparameter1 = pyqtSignal(float)
    sendparameter2 = pyqtSignal(float)
    sendparameter3 = pyqtSignal(int)
    sendparameter4 = pyqtSignal(str)

    def __init__(self):
        super(WidgetGallery, self).__init__()

        self.originalPalette = QApplication.palette()
        styleComboBox = QComboBox()
        styleComboBox.addItems(QStyleFactory.keys())
        self.createTopLeftGroupBox()
        self.createTopRightGroupBox()
        topLayout = QHBoxLayout()

    def createTopLeftGroupBox(self):
        self.topLeftGroupBox = QGroupBox("Entries")
        l1= QLabel("param1:")
        self.DoubleSpinBox1 = QDoubleSpinBox()
        l2=QLabel("param2:")
        self.DoubleSpinBox2 = QDoubleSpinBox()
        l3=QLabel("param3:")
        self.spinBox1 = QSpinBox()       
        l4=QLabel("param4:")
        self.textEdit1 = QLineEdit('')    

        layout = QGridLayout()
        self.topLeftGroupBox.setLayout(layout)   

    def createTopRightGroupBox(self):
        self.topRightGroupBox = QGroupBox("Buttons")

        self.defaultPushButton1 = QPushButton("function 1", self)  
        self.defaultPushButton1.setDefault(False)
        self.defaultPushButton1.pressed.connect(self.func1)

        self.defaultPushButton2 = QPushButton("function 2")
        self.defaultPushButton2.setDefault(False)     
        self.defaultPushButton2.pressed.connect(self.func2)

        self.defaultPushButton3 = QPushButton("func 3")
        self.defaultPushButton3.setDefault(False)
        self.defaultPushButton3.pressed.connect(self.func3)

        self.defaultPushButton4 = QPushButton("function 4")
        self.defaultPushButton4.setDefault(False)
        self.defaultPushButton4.pressed.connect(self.func4)
        self.label_status = QLabel('Status:', self)

        layout = QVBoxLayout()
        layout.addWidget(self.defaultPushButton1)
        layout.addWidget(self.defaultPushButton2)
        layout.addWidget(self.defaultPushButton3)
        layout.addWidget(self.defaultPushButton4)
        layout.addWidget(self.label_status)
        layout.addStretch(1)
        self.topRightGroupBox.setLayout(layout)

    def func1(self):
        param1=float(self.DoubleSpinBox1.value())
        param2=float(self.DoubleSpinBox2.value())
        param3=int(self.spinBox1.value())
        param4=str(self.textEdit1.text())      

        self.sendparameter1.emit(param1)
        self.sendparameter2.emit(param2)
        self.sendparameter3.emit(param3)
        self.sendparameter4.emit(param4)

    @pyqtSlot()        
    def func2(self):
        #some function

    @pyqtSlot() 
    def func3(self):
        #some function

    @pyqtSlot() 
    def func4(self):
        #some function

def main():
    app = QApplication(sys.argv)
    processor = ClassProcessingThread()
    receiving_class = ThreadClass()
    processor.WG.sendparameter1.connect(receiving_class.runner)
    processor.WG.sendparameter2.connect(receiving_class.runner)
    processor.WG.sendparameter3.connect(receiving_class.runner)
    processor.WG.sendparameter4.connect(receiving_class.runner)
    sys.exit(app.exec_())

if __name__ == '__main__':
    print('0')
    main()
python python-3.x multithreading pyqt5 qt-signals
1个回答
0
投票

如果你想通过一个信号得到各种信息,那么你必须在签名中设置。

# ...
class ThreadClass(QObject):
    @pyqtSlot(float, float, int, str)
    def runner(self, param1, param2, param3, param4):
        self.p1 = param1
        self.p2 = param2
        self.p3 = param3
        self.p4 = param4
        # Do stuff with the params


class WidgetGallery(QDialog):
    signalStatus = pyqtSignal(str)

    sendparameters = pyqtSignal(float, float, int, str)

    # ...

    def func1(self):
        param1 = float(self.DoubleSpinBox1.value())
        param2 = float(self.DoubleSpinBox2.value())
        param3 = int(self.spinBox1.value())
        param4 = str(self.textEdit1.text())

        self.sendparameter1.emit(param1, param2, param3, param4)

    # ...


def main():
    # ...
    processor.WG.sendparameter1.connect(receiving_class.runner)
    sys.exit(app.exec_())

# ...

但如果你想简化上面的内容,那么你可以将其设置为发送一个容器,如列表,元组,numpy数组等(Object也可以使用,因为它是一个通用对象)。

# ...
class ThreadClass(QObject):
    @pyqtSlot(list)
    def runner(self, params):
        self.p1, self.p2, self.p3, self.p4 = params


class WidgetGallery(QDialog):
    signalStatus = pyqtSignal(str)

    sendparameters = pyqtSignal(list)

    # ...

    def func1(self):
        param1 = float(self.DoubleSpinBox1.value())
        param2 = float(self.DoubleSpinBox2.value())
        param3 = int(self.spinBox1.value())
        param4 = str(self.textEdit1.text())

        self.sendparameter1.emit([param1, param2, param3, param4])

    # ...


def main():
    # ...
    processor.WG.sendparameter1.connect(receiving_class.runner)
    sys.exit(app.exec_())

# ...
© www.soinside.com 2019 - 2024. All rights reserved.