pyqt中使用lambda表达式连接槽

新手上路,请多包涵

我正在尝试将插槽与 lambda 函数连接起来,但它没有按我预期的方式工作。在下面的代码中,我成功地正确连接了前两个按钮。对于我在循环中连接的后两个,这是错误的。在我之前有人有同样的问题( Qt - Connect slot with argument using lambda ),但这个解决方案对我不起作用。我已经盯着屏幕看了半个小时,但我无法弄清楚我的代码有何不同。

 class MainWindow(QtGui.QWidget):
    def __init__(self):
        super(QtGui.QWidget, self).__init__()

        main_layout = QtGui.QVBoxLayout(self)

        # Works:
        self.button_1 = QtGui.QPushButton('Button 1 manual', self)
        self.button_2 = QtGui.QPushButton('Button 2 manual', self)
        main_layout.addWidget(self.button_1)
        main_layout.addWidget(self.button_2)

        self.button_1.clicked.connect(lambda x:self.button_pushed(1))
        self.button_2.clicked.connect(lambda x:self.button_pushed(2))

        # Doesn't work:
        self.buttons = []
        for idx in [3, 4]:
            button = QtGui.QPushButton('Button {} auto'.format(idx), self)
            button.clicked.connect(lambda x=idx: self.button_pushed(x))
            self.buttons.append(button)
            main_layout.addWidget(button)

    def button_pushed(self, num):
        print 'Pushed button {}'.format(num)

按下前两个按钮会产生“Pushed button 1”和“Pushed button 2”,另外两个按钮都会产生“Pushed button False”,尽管我预计会出现 3 和 4。

我也没有完全理解 lambda 机制。究竟是什么连接起来了?指向由 lambda 生成的函数的指针(参数被替换),或者在信号触发时评估 lambda 函数?

原文由 zeus300 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 751
2 个回答

QPushButton.clicked 信号发出一个指示按钮状态的参数。当您连接到您的 lambda 槽时,您分配的可选参数 idx 被按钮的状态覆盖。

相反,将您的连接设置为

button.clicked.connect(lambda state, x=idx: self.button_pushed(x))

这样,按钮状态将被忽略,并将正确的值传递给您的方法。

原文由 three_pineapples 发布,翻译遵循 CC BY-SA 3.0 许可协议

谨防!只要您将信号连接到带有对自身的引用的 lambda 插槽,您的小部件就不会被垃圾收集!那是因为 lambda 创建了一个闭包,其中包含另一个无法收集的小部件引用。

因此, self.someUIwidget.someSignal.connect(lambda p: self.someMethod(p)) 是非常邪恶的:)

原文由 Grigory Makeev 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题