「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > PyQt4 ボタンのクリック信号がループ内で常に同じ値を出力するのはなぜですか?

PyQt4 ボタンのクリック信号がループ内で常に同じ値を出力するのはなぜですか?

2024 年 11 月 16 日に公開
ブラウズ:700

Why Does My PyQt4 Button Clicked Signal Always Output the Same Value Within a Loop?

ループ内での PyQt4 のスロットとシグナルの接続

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」の値を変更して、ボタンのクリックに対する適切な応答を有効にします。

最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3