在 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'。
要解決此問題,一種方法是在 lambda 函數中將“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