如何在一段时间内向同一槽发送多个复杂信号

0 投票
1 回答
1054 浏览
提问于 2025-06-18 04:05

我正在使用PyQT5.10在Spyder3.8上编写一个图形用户界面(GUI)。用户可以输入几个参数,包括字符串、整数和浮点数,然后按下“开始”按钮,这会启动一个新线程,在这个线程中存储这些参数,并进行计算。这个线程应该能够立即从GUI获取几个参数。此外,GUI还有一些按钮,可以向线程发送新的参数,希望能够实时更新线程中的各个参数。我的问题是:是否可以在不同的时间通过信号和槽将所有这些整数、字符串和浮点数参数发送到同一个线程?有没有什么特别的策略是最好的?我附上了一个简化版的脚本,线程中运行的函数叫做“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()

相关问题:

  • 暂无相关问题
暂无标签

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数组等等(你也可以使用对象,因为对象是通用的)。

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

# ...

撰写回答