Виджет календаря Python - возвращает выбранную пользователем дату
Этот класс ttk calendar делает календарь на основе tkinter. Как заставить его вернуть значение выбранной даты? Ниже, что я пытался, он возвратил "объект NoneType не вызывается":
def test():
import sys
root = Tkinter.Tk()
root.title('Ttk Calendar')
ttkcal = Calendar(firstweekday=calendar.SUNDAY)
ttkcal.pack(expand=1, fill='both')
x = ttkcal.selection() #this and the following line are what i inserted
print 'x is: ', x #or perhaps return x
if 'win' not in sys.platform:
style = ttk.Style()
style.theme_use('clam')
root.mainloop()
if __name__ == '__main__':
test()
1 ответ
Выделение - это @property, поэтому вам необходимо выполнить следующее:
x = ttkcal.selection
Кроме того, используя этот календарь, вы можете получить выбранную дату после закрытия виджета callendar (т.е. после mainloop()). Таким образом, ваш код должен быть:
def test2():
import sys
root = Tkinter.Tk()
root.title('Ttk Calendar')
ttkcal = Calendar(firstweekday=calendar.SUNDAY)
ttkcal.pack(expand=1, fill='both')
if 'win' not in sys.platform:
style = ttk.Style()
style.theme_use('clam')
root.mainloop()
x = ttkcal.selection
print 'x is: ', x
Так, на всякий случай. Если вы не хотите закрывать окно календаря, чтобы получить выбранное значение, но хотите, чтобы они были "живыми" при нажатии, например, для отображения их в метке другого окна, вы можете сделать следующее:
Сначала расширьте класс Calendar, чтобы добавить функцию обратного вызова, которая будет вызываться каждый раз при выборе какой-либо даты:
class Calendar2(Calendar):
def __init__(self, master=None, call_on_select=None, **kw):
Calendar.__init__(self, master, **kw)
self.set_selection_callbeck(call_on_select)
def set_selection_callbeck(self, a_fun):
self.call_on_select = a_fun
def _pressed(self, evt):
Calendar._pressed(self, evt)
x = self.selection
#print(x)
if self.call_on_select:
self.call_on_select(x)
С этим вы можете сделать новый пример test2, который имеет два окна. Один для календаря и одно окно с некоторой меткой (например):
class SecondFrame(Tkinter.Frame):
def __init__(self, *args, **kwargs):
Tkinter.Frame.__init__(self, *args, **kwargs)
self.l = Tkinter.Label(self, text="Selected date")
self.l.pack()
self.pack()
def update_lable(self, x):
self.l['text'] = x;
def test2():
import sys
root = Tkinter.Tk()
root.title('Ttk Calendar')
ttkcal = Calendar2(firstweekday=calendar.SUNDAY)
ttkcal.pack(expand=1, fill='both')
if 'win' not in sys.platform:
style = ttk.Style()
style.theme_use('clam')
sf = SecondFrame(Tkinter.Toplevel())
ttkcal.set_selection_callbeck(sf.update_lable)
root.mainloop()
В этом примере метка в SecondFrame будет обновляться каждый раз при выборе какой-либо даты в календаре.