Home > Mobile >  Tkinter StringVar not updating
Tkinter StringVar not updating

Time:11-18

I'm trying to make a program that displays the date automatically. I see a lot of people using a trace to do it, so I tried to follow them. My code is running well but the variable of date won't change according to the existing entries.

It should be :

2022-11-17

2022-11-18

2022-11-19

and not

2022-11-19

2022-11-19

2022-11-19 

This is my code:

import tkinter  as tk 
from tkcalendar import DateEntry
from datetime import datetime, date, timedelta

my_w = tk.Tk()
my_w.geometry("400x300")  
e1=tk.StringVar()
e2=tk.StringVar()
#d1,d2='',''

lab_from=tk.Label(my_w,text='From')
lab_from.grid(row=0,column=0)
lab_to=tk.Label(my_w,text='To')
lab_to.grid(row=0,column=1)
c1=DateEntry(my_w,selectmode='day',textvariable=e1,date_pattern='dd-MM-yyyy')
c1.grid(row=1,column=0,padx=15)
c2=DateEntry(my_w,selectmode='day',textvariable=e2,date_pattern='dd-MM-yyyy')
c2.grid(row=1,column=1,padx=15)
b=tk.Button(my_w,text='Reset'
    ,command=lambda:reset())
b.grid(row=1,column=2)
b1=tk.Button(my_w,text='test'
    ,command=lambda:co())
b1.grid(row=1,column=3)

def count_date(*args):
    global d1,d2,final_diff,dates
    dates=[]
    if(len(e1.get())&len(e2.get())):
        d1 = c1.get_date()
        d2 = c2.get_date()
        diff = d2 - d1
        final_diff = diff.days
        tday.set(final_diff)
        for i in range(final_diff 1):
            day = d1   timedelta(days=i)
            dates.append(day)
            datev.set(str(dates[i]))
            print(datev.get())            



tday=tk.IntVar()
datev=tk.StringVar()

row_list=[]
row_list1=[]
def b2(*args):
    global en,en1,en2,a,a1,a2, datev
    ac=tday.get()
    rows=len(row_list)
    rows1=len(row_list1)
    diff=ac-rows
    diff1=ac-rows1


    if diff == 0:
        return 
    elif diff > 0:      # Add rows of entrys and remember them
        a=[]
        for i in range(rows 1, rows diff 1):
            en=tk.Entry(my_w,textvariable=datev)
            en.grid(row=i 1,column=0,columnspan=3,pady=10)
            a.append(en)
        row_list.append(a)

    elif diff < 0:      # Remove rows of entrys and froget them
        for i in range(rows-1, rows-1 diff, -1):
            for widget in row_list[i]:
                widget.grid_forget()
                widget.destroy()
            del row_list[-1]

    if diff1 == 0:
        return 
    elif diff1 > 0:      # Add rows of entrys and remember them
        a1=[]
        for i in range(rows1 1, rows1 diff1 1):
            en=tk.Entry(my_w,)
            en.grid(row=i 1,column=1,columnspan=3,pady=10)
            a1.append(en)
        row_list1.append(a1)
    elif diff1 < 0:      # Remove rows of entrys and froget them
        for i in range(rows1-1, rows1-1 diff1, -1):
            for widget in row_list1[i]:
                widget.grid_forget()
                widget.destroy()
            del row_list1[-1]
    

def co():
    print(len(a))
    print(len(a1))
    print(len(a2))

def reset():
    d1,d2='',''
    dt_now=date.today().strftime('%d-%m-%Y')
    c1.set_date(dt_now) # todays date 
    c2.set_date(dt_now) # todays date ) 
    c1.config(maxdate=None)
    c2.config(mindate=None)
      

tday.trace('w',b2)
e1.trace('w',count_date) # on change of string variable 
e2.trace('w',count_date) # on change of string variable 
my_w.mainloop()

Can you help me to solve this?

Thank you for your help!

CodePudding user response:

You need to use a unique StringVar() for each entry that holds the date string. I made a few other minor modifications as well. You can ignore them if you would like.

For example:

import tkinter  as tk
from tkcalendar import DateEntry
from datetime import datetime, date, timedelta

my_w = tk.Tk()
my_w.geometry("400x300")
e1 = tk.StringVar()
e2 = tk.StringVar()
lab_from = tk.Label(my_w, text='From')
lab_from.grid(row=0, column=0)
lab_to = tk.Label(my_w, text='To')
lab_to.grid(row=0, column=1)
c1 = DateEntry(my_w, selectmode='day', textvariable=e1, date_pattern='dd-MM-yyyy')
c1.grid(row=1, column=0, padx=15)
c2 = DateEntry(my_w, selectmode='day', textvariable=e2, date_pattern='dd-MM-yyyy')
c2.grid(row=1, column=1, padx=15)
b = tk.Button(my_w, text='Reset', command=lambda:reset())
b.grid(row=1, column=2)
b1 = tk.Button(my_w, text='test', command=lambda:print())
b1.grid(row=1, column=3)
row_list = []

def count_date(*args):
    if len(e1.get()) and len(e2.get()):
        d1 = c1.get_date()
        d2 = c2.get_date()
        diff = (d2 - d1)
        final_diff = diff.days
        row_count = len(row_list) - 1
        while row_count >= 0:
            for widget in row_list[row_count]:
                widget.grid_forget()
                widget.destroy()
            del row_list[row_count]
            row_count -= 1
        for i in range(final_diff   1):
            datev = tk.StringVar()                # create a unique stringVar() for each entry that holds the date string
            day = d1   timedelta(days=i)
            en1 = tk.Entry(my_w, textvariable=datev)
            en1.grid(row=i   3, column=0, columnspan=3, pady=10)
            en2=tk.Entry(my_w,)
            en2.grid(row=i   3, column=1, columnspan=3, pady=10)
            datev.set(str(day))
            row_list.append((en1,en2))

def reset():
    dt_now=date.today().strftime('%d-%m-%Y')
    c1.set_date(dt_now) # todays date
    c2.set_date(dt_now) # todays date )
    c1.config(maxdate=None)
    c2.config(mindate=None)

e1.trace('w',count_date) # on change of string variable
e2.trace('w',count_date) # on change of string variable
my_w.mainloop()


  • Related