python 日历小部件 - 返回用户选择的日期

2022-01-11 00:00:00 python tkinter ttk calendar

问题描述

这个 ttk 日历类基于 tkinter 的日历.如何让它返回所选日期的值?以下是我尝试过的,它返回'NoneType object is not callable':

This ttk calendar class makes a calendar based on tkinter. How do make it return the value of the selected date? Below is what I tried, it returned 'NoneType object is not callable':

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()


解决方案

Selection 是一个@property,因此您需要执行以下操作:

Selection is a @property, so you need to the following to have your code exectued:

x = ttkcal.selection

此外,使用此日历,您可以在关闭 callendar 小部件后(即在 mainloop() 之后)获取所选日期.因此你的代码应该是:

Also, using this calendar, you can get the selected date, after you close the callendar widget (i.e. after mainloop()). Thus your code should be:

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  

以防万一.如果您不想关闭日历窗口以获取所选值,但您希望在单击它们时让它们活动",例如将它们显示在其他窗口的标签中,您可以执行以下操作:

Just in case. If you dont want to close the calendar window to get the selected value, but you want to get them "live" as they are clicked, to e.g. display them in other window's label, you can do the following:

首先扩展 Calendar 类,添加每次选择某个日期时将调用的回调函数:

First extend the Calendar class to add the callback function that will be called each time you select some date:

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 示例,它有两个窗口.一个用于日历,一个带有一些标签的窗口(例如):

With this, you can make the new test2 example, which has two windows. One for Calendar, and one window with some label (for instance):

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 中的标签将在您每次选择日历中的某个日期时更新.

In this example, the label in SecondFrame, will be updated each time you select some date in the calendar.

相关文章