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