Search code examples
python-3.xtkintercalendarnameerrornested-function

How do i call variable c from def cal_fun()


I am trying to call the variable c in the below code. It says the cal is not defined

def pay_cal():

    def cal_fun():
        t = Toplevel()
        global cal
        cal = Calendar(t, year=2019, month=6, day=1, foreground='Blue', background='White', selectmode='day')
        cal.pack()

    c = cal.get_date

    sub_win =Tk()
    sub_win.geometry('400x500+600+100')
    sub_win.title('Payout Calculator')

    l1 = Button(sub_win, text= 'Check-In Date:', command= cal_fun)
    chck_in_date = Label(sub_win, textvariable= c )
    l1.grid(row=1)
    chck_in_date.grid(row=1, column=2)


Solution

  • There are couple things wrong with your code. For starters, you define c as cal.get_date when cal hasn't even been created yet.

    Next you pass c as a textvariable for a label widget. It will not raise any error, but it will not get updated either - what you need is a StringVar object.

    You also lack the mechanism to update the textvariable upon calendar selection. Even your original code is fixed, the date will only update once upon execution.

    Here's how you can make everything work:

    from tkinter import *
    from tkcalendar import Calendar #I assume you are using tkcalendar
    
    def pay_cal():
    
        def cal_fun():
            t = Toplevel()
            global cal
            cal = Calendar(t, year=2019, month=6, day=1, foreground='Blue', background='White', selectmode='day')
            cal.pack()
            cal.bind("<<CalendarSelected>>",lambda e: c.set(cal.get_date())) #make use of the virtual event to dynamically update the text variable c
    
        sub_win = Tk()
        sub_win.geometry('400x500+600+100')
        sub_win.title('Payout Calculator')
        c = StringVar() #create a stringvar here - note that you can only create it after the creation of a TK instance
    
        l1 = Button(sub_win, text= 'Check-In Date:', command= cal_fun)
        chck_in_date = Label(sub_win, textvariable=c)
        l1.grid(row=1)
        chck_in_date.grid(row=1, column=2)
        sub_win.mainloop()
    
    pay_cal()
    

    Lastly I noticed you use sub_win as a variable name for this function - which means you might have a main_win something else. It is generally not advised to use multiple instance of Tk - if you need additional windows, just use Toplevel.