在 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 中,變數的作用域由最近的封閉函數決定。在此範例中,lambda 函數和「_number」函數均在「__init__」函數中定義。由於每次迭代循環都會將相同的值 ('9') 分配給 'i',因此 lambda 函數始終捕獲在 '__init__' 函數中分配給 'i' 的最後一個值,即 '9'。
要解決此問題,一種方法是將「i」作為關鍵字參數傳遞,並在lambda 函數中使用預設值,確保為每個「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中文網其他相關文章!