Tkinter: How to use Radiobutton and grid() to create clickable calendar.
This simple example shows how to use Radiobutton and grid (and datetime) to create calendar for one month.
It also shows how to use command= in Radiobutton to execute function which changes text in few Labels
Because command= expects callback - it means function's name without () and arguments - so I use lambda
to assing function with argument (datetime object with current date) which I can use in function
command=lambda x=current_day:on_click(x)
Full example
import tkinter as tk
import datetime
# --- functions ---
def on_click(date):
#print(date)
label_date['text'] = date.strftime('%a, %b %d, %Y')
label_day['text'] = date.strftime('Day: %d')
label_weekday['text'] = date.strftime('Weekday: %a')
label_yearday['text'] = date.strftime('Day of the year: %-j')
# --- main ---
root = tk.Tk()
radiobutton_var = tk.StringVar()
year = 2020
month = 4
row = 0
for day in range(1, 32):
try:
current_day = datetime.datetime(year, month, day)
date_str = current_day.strftime('%a, %m %d, %Y')
weekday = current_day.weekday()
radiobutton_day = tk.Radiobutton(root,
text=str(day),
indicatoron=0,
variable=radiobutton_var,
value=date_str,
#value=day,
command=lambda x=current_day:on_click(x))
radiobutton_day.grid(row=row, column=weekday, sticky='we')
if weekday == 6:
row += 1
radiobutton_day['bg'] = '#faa'
except ValueError as ex:
print(ex)
break
label_date = tk.Label(root, text='?')
label_date.grid(row=10, columnspan=10)
label_day = tk.Label(root, text='Day: ?')
label_day.grid(row=11, columnspan=10)
label_weekday = tk.Label(root, text='Weekday: ?')
label_weekday.grid(row=12, columnspan=10)
label_yearday = tk.Label(root, text='Day of the year: ?')
label_yearday.grid(row=13, columnspan=10)
root.mainloop()
And code in class inherited from Frame so it can be used as widget to put many times
import tkinter as tk
import datetime
# --- classes ---
class Month(tk.Frame):
def __init__(self, master, year, month, *args, **kwargs):
super().__init__(master, *args, **kwargs)
self.year = year
self.month = month
self.var = tk.StringVar()
self.create()
def on_click(self, date):
#print(date)
self.label_date['text'] = date.strftime('%a, %b %d, %Y')
self.label_day['text'] = date.strftime('Day: %d')
self.label_weekday['text'] = date.strftime('Weekday: %a')
self.label_yearday['text'] = date.strftime('Day of the year: %-j')
def create(self):
year = self.year
month = self.month
row = 0
for day in range(1, 32):
try:
current_day = datetime.datetime(year, month, day)
date_str = current_day.strftime('%a, %m %d, %Y')
weekday = current_day.weekday()
radiobutton_day = tk.Radiobutton(self,
text=str(day),
indicatoron=0,
variable=self.var,
value=date_str,
#value=day,
command=lambda x=current_day:self.on_click(x))
radiobutton_day.grid(row=row, column=weekday, sticky='we')
if weekday == 6:
row += 1
radiobutton_day['bg'] = '#faa'
except ValueError as ex:
print(ex)
break
# add empty label to create empty row when it use less rows
row += 1
while row < 6:
l = tk.Label(self, text=" ")
l.grid(row=row, column=0, sticky='we')
row += 1
self.label_date = tk.Label(self, text='?')
self.label_date.grid(row=10, columnspan=10)
self.label_day = tk.Label(self, text='Day: ?')
self.label_day.grid(row=11, columnspan=10)
self.label_weekday = tk.Label(self, text='Weekday: ?')
self.label_weekday.grid(row=12, columnspan=10)
self.label_yearday = tk.Label(self, text='Day of the year: ?')
self.label_yearday.grid(row=13, columnspan=10)
# --- main ---
root = tk.Tk()
for x in range(1, 3):
m = Month(root, 2020, x)
m.pack(side='left')
root.mainloop()
If you like it
Buy a Coffee
furas.pl