Python: элементы меню Tkinter не передают правильное значение - PullRequest
3 голосов
/ 25 сентября 2011

В настоящее время я работаю над графическим интерфейсом (Tkinter) для моего приложения.У меня проблемы с созданием пары выпадающих меню, которые должны быть использованы для выбора даты.Написанное мною приложение создает нужные меню с метками, однако, нажав любую из кнопок, только значение последней записи меню передается в изменяемый tkinter IntVar.

Это часть кодаэто подчеркивает мою проблему.год должен быть годом, на который пользователь нажимает, однако это всегда 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 голосов
/ 25 сентября 2011

Измените command на:

lambda the_year=the_year: year_seter(the_year)

Проблема связана с тем, как Python ищет значение the_year.Когда вы используете

lambda : year_seter(the_year)

the_year, он не входит в локальную область действия лямбда-функции, поэтому Python ищет его в расширенных глобальных , а затем во встроенных областях .Он находит это в глобальном масштабе.for-loop использует the_year, и после окончания цикла for the_year сохраняет свое последнее значение, 2011. Поскольку лямбда-функция выполняется после завершения цикла for, значение, которое Python назначает the_year, равно2011.

В отличие от этого, если вы используете параметр со значением по умолчанию, значение по умолчанию фиксируется в тот момент, когда функция (лямбда) имеет значение определено .Таким образом, каждый lambda получает различное значение для the_year, фиксированное в качестве значения по умолчанию.

Теперь, когда вызывается лямбда, снова Python ищет значение the_year, но на этот раз находит егов локальной области лямбды.Он связывает значение по умолчанию с the_year.


PS.

  1. Вы также можете отказаться от определения year_seter и просто сделать:

    lambda the_year=the_year: year.set(the_year)
    
  2. list_of_years = range(1995,2012) также работает.
...