我无法从tkinter获得Entry的值,最后一个会损坏其他人

时间:2016-06-03 10:41:55

标签: python lambda tkinter bind

我是一名新的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()

2 个答案:

答案 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的当前值。