pyqt中使用lambda表达式连接槽并发送多个值

Using lambda expression to connect slots and send multiple values in pyqt

我遇到了与 类似的问题。就我而言,我想发送两条不同的信息。单击哪个按钮(端口号)以及与该端口号关联的传感器(存储在 QComboBox 中)。

这就是我想要实现的并且效果很好:

self.portNumbers[0].clicked.connect(lambda: self.plot(1, self.sensorNames[0].currentText()))
self.portNumbers[1].clicked.connect(lambda: self.plot(2, self.sensorNames[1].currentText()))
self.portNumbers[2].clicked.connect(lambda: self.plot(3, self.sensorNames[2].currentText()))
...

但是当我把它放在一个循环中时:

for i, (portNumber, sensorName) in enumerate(zip(self.portNumbers, self.sensorNames)):
    portNumber.clicked.connect(lambda _, x=i + 1, y=sensorName.currentText(): self.plot(x, y))

我得到了正确的端口号,但组合框中的更改没有反映出来。

最小可重现代码:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QComboBox

portNumbers = [None] * 8
sensorNames = [None] * 8
SENSORS = ["Temperature", "Pressure", "Height"]


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()

        self.init_ui()
        self.connectButtonsToGraph()

    def init_ui(self):
        vbox = QVBoxLayout()
        h1box = QHBoxLayout()
        h2box = QHBoxLayout()
        for i, (portNumber, sensorName) in enumerate(zip(portNumbers, sensorNames)):
            # Set portNumber as pushButton and list sensorNames in ComboBox
            portNumber = QPushButton()
            sensorName = QComboBox()
            h1box.addWidget(portNumber)
            h2box.addWidget(sensorName)

            # Give identifier, text info to individual ports and modify the list
            portNumberName = "port_" + str(i + 1)
            portNumber.setObjectName(portNumberName)
            portNumberText = "Port " + str(i + 1)
            portNumber.setText(portNumberText)
            portNumbers[i] = portNumber

            # Add the textual information in PushButton and add modify the list
            sensorNameStringName = "portSensorName_" + str(i + 1)
            sensorName.setObjectName(sensorNameStringName)
            for counter, s in enumerate(SENSORS):
                sensorName.addItem("")
                sensorName.setItemText(counter, s)
            sensorNames[i] = sensorName

        vbox.addLayout(h1box)
        vbox.addLayout(h2box)
        self.setLayout(vbox)

        self.show()

    def connectButtonsToGraph(self):
        for i, (portNumber, sensorName) in enumerate(zip(portNumbers, sensorNames)):
            portNumber.clicked.connect(lambda _, x=i + 1, y=sensorName.currentText(): self.plot(x, y))

    def plot(self, portNumber, sensorName):
        print(portNumber, sensorName)


def run():
    app = QApplication([])
    mw = MyWidget()
    app.exec_()


if __name__ == '__main__':
    run()

谢谢@musicamante 的解释。如果有人遇到类似问题,我只是将其添加到答案中以将其标记为已解决。

正如他们提到的,lambda 的关键字参数的值是在创建时计算的。因此,创建对 sensorName.currentText() 的引用使用了当时当前文本的值。但是创建对 ComboBox 本身的引用允许获取 run-time.

中文本的值