PyQt4 では、スロットとシグナル間の接続を確立することがイベント処理の基本的な側面です。ただし、ループ内のボタンから送信される複数の信号を接続しようとすると、予期しない動作が発生する可能性があります。
この問題を説明するには、次のコードを考えてみましょう。
def __init__(self): for i in range(0, 10): self._numberButtons += [QPushButton(str(i), self)] self.connect(self._numberButtons[i], SIGNAL('clicked()'), lambda: self._number(i)) def _number(self, x): print(x)
いずれかのボタンをクリックすると、ボタンを押すと、どのボタンが押されたかに関係なく、出力には常に「9」が表示されます。この動作の背後にある理由を理解するには、Python のスコープ ルールの複雑さを調べる必要があります。
Python では、変数のスコープは最も近い囲み関数によって決定されます。この例では、ラムダ関数と '_number' 関数の両方が '__init__' 関数内で定義されています。ループは反復ごとに同じ値 (「9」) を「i」に割り当てるため、ラムダ関数は常に「__init__」関数内で「i」に割り当てられた最後の値 (「9」) をキャプチャします。
この問題を解決するための 1 つのアプローチは、ラムダ関数内でデフォルト値を持つキーワード引数として「i」を渡し、インスタンスごとに「i」の個別のバインディングが作成されるようにすることです。
self._numberButtons[i].clicked.connect(lambda checked, i=i: self._number(i))
また、functools.partial を使用して、「i」を各ボタンに関連付けられた特定の値にバインドする特殊な関数を作成することもできます。
self._numberButtons[i].clicked.connect(partial(self._number, i))
これらの変更により、各コールバック関数が正しい値を取得することが保証されます。 「i」: ボタンのクリックに対する適切な応答を有効にします。
以上がPyQt4 ボタンのクリック信号がループ内で常に同じ値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。