2016-02-26 68 views
1

我正在嘗試使用Tkinter爲Python應用程序(2.7)中的PLC應用程序構建一個簡單的GUI模擬器。我創建了一個帶有許多標籤的窗口,每個標籤都代表應用程序中的一個布爾位,並且我試圖將切換功能綁定到每個標籤對象,模擬PLC I/O狀態的變化。要做到這一點,我已經建立了一個名爲bits的列表,每個項目的字典看起來像{'bit':'input1', 'value':True, 'type':'input'}屬性僅分配給列表中的最後一個對象

問題是我試圖將標籤上的點擊事件綁定到每一位的切換功能,但是我的點擊僅綁定到標籤列表中的最後一個標籤。

class Bitwin(tk.Frame): 
def __init__(self, root): 

    tk.Frame.__init__(self, root) 
    self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff") 
    self.frame = tk.Frame(self.canvas, background="#ffffff") 
    self.canvas.pack(side="left", fill="both", expand=True) 
    self.canvas.create_window((4,4), window=self.frame, anchor="nw", 
           tags="self.frame") 

    self.frame.bind("<Configure>", self.onFrameConfigure) 

    self.labels=[] 
    self.populate() 

    for h,i in enumerate(self.labels): 
     i.bind('<Button-1>', lambda event: toggle(i.cget('text'))) 
     i.grid(row=h%200, column=int(floor(h/200))+1) 

def populate(self): 
    for h,i in enumerate(bits): 
     lab=tk.Label(self.frame, text=i['bit'], bg='grey',fg='white', width=20) 
     self.labels.append(lab) 

我認爲綁定切換功能在一個單獨的循環會做的伎倆,但沒有。無論我點擊哪個標籤,只有最後一個'位'被切換。

+0

這是因爲在'lambda'功能,'i'不被引用直到''事件發生。那時候,'i'已經被分配給每個標籤,因此停在最後一個。 – zondo

+0

你正在試圖做這樣的事情:https://pypi.python.org/pypi/SimPyLC?您可以免費使用我的(如果這更有趣,請自行打開) –

回答

0

因爲在for循環內的lambda中的綁定被懶惰地綁定。當lambda被定義時,但是當它被調用時,i未被綁定。

可以解決辦法使用默認參數:

for h,i in enumerate(self.labels): 
    i.bind('<Button-1>', lambda event, i=i: toggle(i.cget('text'))) # <-- 
    i.grid(row=h%200, column=int(floor(h/200))+1) 
+0

謝謝!你已經發現了我對lambda和函數回調的誤解。 – BenJ

相關問題