ホームページ > バックエンド開発 > Python チュートリアル > PyQt4 ボタンのクリック信号がループ内で常に同じ値を出力するのはなぜですか?

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

DDD
リリース: 2024-11-13 04:08:09
オリジナル
703 人が閲覧しました

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

以上がPyQt4 ボタンのクリック信号がループ内で常に同じ値を出力するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート