Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python calendar widget - return the user-selected date

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()
like image 479
Inner Peace Avatar asked Feb 11 '23 05:02

Inner Peace


1 Answers

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

x = ttkcal.selection

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:

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)

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

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

enter image description here

like image 144
Marcin Avatar answered Feb 14 '23 17:02

Marcin