Python:Tkinter菜单项未传递正确值
我现在正在为我的应用程序制作一个图形用户界面(使用Tkinter)。我遇到了一些问题,就是想创建几个下拉菜单来选择日期。我的应用程序可以生成带标签的菜单,但是无论我点击哪个按钮,最后一个菜单的值总是被传递给tkinter的可变IntVar。
下面是我代码的一部分,突出了我的问题。用户点击的年份应该是year,但它总是显示为2011。
from Tkinter import *
import tkFileDialog as dialog
import datetime
import calendar
window = Tk()
text = Text(window)
text.pack()
year = IntVar()
list_of_years = [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011]
def year_seter(value):
year.set(value)
menubar = Menu(window)
yearmenu = Menu(menubar)
for the_year in list_of_years:
yearmenu.add_command(label=str(the_year), command=lambda : year_seter(the_year))
menubar.add_cascade(label = 'Year', menu=yearmenu)
window.config(menu=menubar)
label = Label(window, textvariable=year)
label.pack()
window.mainloop()
有人能告诉我,为什么会这样吗?谢谢你们的时间!
1 个回答
4
把 command
改成:
lambda the_year=the_year: year_seter(the_year)
这个问题和 Python 查找 the_year
的值有关。当你使用
lambda : year_seter(the_year)
the_year
在 lambda 函数的本地范围内找不到,所以 Python 会去更大的范围找,包括全局范围和内置范围。它在全局范围找到了 the_year
。这个 for-loop
使用了 the_year
,而在 for-loop
结束后,the_year
保留了最后的值,也就是 2011。因为 lambda 函数是在 for-loop
结束后执行的,所以 Python 给 the_year
赋的值是 2011。
相反,如果你使用一个带有默认值的参数,那么这个默认值在函数(lambda)被定义的时候就固定下来了。因此,每个 lambda
都会有一个不同的 the_year
值作为默认值。
现在当调用 lambda 时,Python 又去找 the_year
的值,这次它在 lambda 的本地范围找到了。它把默认值绑定到 the_year
上。
附注:
你也可以不定义
year_seter
,直接这样做:lambda the_year=the_year: year.set(the_year)
list_of_years = range(1995,2012)
也可以用。