ラムダ式を使用してpyqtのスロットを接続する質問する

ラムダ式を使用してpyqtのスロットを接続する質問する

ラムダ関数でスロットを接続しようとしていますが、期待通りに動作しません。以下のコードでは、最初の 2 つのボタンを正しく接続できます。ループで接続する 2 番目の 2 つでは、うまくいきません。私より前に同じ質問をした人がいました (Qt - ラムダを使用して引数でスロットを接続する) ですが、この解決策は私にはうまくいきません。30 分間画面を見つめていますが、コードがどのように異なるのかわかりません。

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)

最初の 2 つのボタンを押すと、「ボタン 1 が押されました」と「ボタン 2 が押されました」という結果が返されますが、他の 2 つのボタンを押すと、3 と 4 を期待していたにもかかわらず、両方とも「ボタン False が押されました」という結果が返されます。

また、ラムダのメカニズムも完全には理解していません。正確には何が接続されるのでしょうか? ラムダによって生成された関数へのポインター (パラメーターが代入される) ですか、それともシグナルが発せられるたびにラムダ関数が評価されるのでしょうか?

ベストアンサー1

シグナルQPushButton.clickedは、ボタンの状態を示す引数を出力します。ラムダ スロットに接続すると、割り当てたオプションの引数idxがボタンの状態によって上書きされます。

代わりに、次のように接続してください

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

この方法では、ボタンの状態は無視され、正しい値がメソッドに渡されます。

おすすめ記事