我是一名新的Python用户。我尝试通过标签创建一系列条目并插入值。回调函数看起来做得很好,但它总是我达到的第三个条目的值。 我是Python / Linux用户,版本2.7.6 这似乎是lambda的声明问题,你能帮帮我吗?
import Tkinter as tk
class c1(tk.Frame):
def __init__(self, master=None):
r = 0
tk.Frame.__init__(self, master)
self.grid()
self.master.title('Test three binds')
self.master.geometry('300x200+400+400')
self.ents = {}
for i in ['aaa', 'bbb', 'ccc'] :
r += 1
self.ents[i] = c2()
self.ents[i].label = tk.Label(text = i)
self.ents[i].label.grid (row = r, column = 0)
self.ents[i].entry = tk.Entry()
self.ents[i].entry.grid (row = r, column = 1)
self.ents[i].val = tk.StringVar()
self.ents[i].val.set(i)
self.ents[i].entry["textvariable"] = self.ents[i].val
self.ents[i].entry.bind('<Key-Return>', lambda X : self.verif(self.ents[i]))
def verif(self, event) :
print event.val.get()
class c2 :
pass
mm = c1()
for ii in mm.ents :
print mm.ents[ii].val.get()
mm.mainloop()
答案 0 :(得分:2)
一个问题是这行代码:
self.ents[i].entry["textvariable"] = self.ents[i].val
textvariable
属性必须设置为StringVar
(或其他tkinter变量之一)的实例,不此类实例的值。您需要删除.val
。
另一个问题是你需要在创建lambda时绑定(如:创建一个闭包)i
的值。你可以这样做:
self.ents[i].entry.bind('<Key-Return>', lambda event, i=i : self.verif(self.ents[i]))
但是,如果self.verif
中所需的全部是条目小部件中的值,则可以通过完全删除textvariable的使用以及{{1}的使用来降低代码的复杂性因为事件包含对小部件本身的引用。 <{1}}和lambda
都不是真正需要的。
textvariables
最后,tkinter lambda
小部件具有内置的验证支持。请查看此答案以获取更多信息:https://stackoverflow.com/a/4140988/7432
答案 1 :(得分:0)
你是对的,它来自lambda声明问题。
循环中的i
实际上并未发生变化,因为lambdas don't closure the parameter。因此,您可以对for
循环中的这一行进行简单调整,以解决此问题:
self.ents[i].entry.bind('<Key-Return>', lambda event, i = i: self.verif(self.ents[i]))
将lambda更改为使用i = i
可以捕获每次迭代的i
的当前值。