how to disable a date cell in tkcalendar?

1k Views Asked by At
# Import Required Library
from tkinter import *
from tkcalendar import Calendar
from  datetime import date
# Create Object
root = Tk()

# Set geometry
root.geometry("400x400")

today = date.today() # today
maxdate=date(2023,12,31) # Maximum date in Year, month , day
# Add Calendar
cal = Calendar(root, selectmode = 'day',
            year = 2020, month = 5,
            day = 22,mindate=today,maxdate=maxdate)

cal.pack(pady = 20)

def grad_date():
    date.config(text = "Selected Date is: " + cal.get_date())

# Add Button and Label
Button(root, text = "Get Date",
    command = grad_date).pack(pady = 20)

date = Label(root, text = "")
date.pack(pady = 20)

# Execute Tkinter
root.mainloop()

for example, i wish christmas and first day of a year to be unable to be selected. (hopefully class will not be used)

*code taken from geeksfrogeeks

1

There are 1 best solutions below

0
On

There is no built-in way to disable dates in tkcalendar but it can be added. A clean way to do so is to create a class (I know the OP would rather not use classes but I need to access some internal attributes of the calendar) inheriting from Calendar to add the disable_date() method.

In Calendar, the days are Label widgets and they cannot be selected if they are in disabled state. Therefore, the idea is to store the disabled dates in a list (self._disabled_dates in the code below) and put the labels corresponding to these dates in the disabled state when displaying the calendar (in self._display_calendar() method).

import tkinter as tk
from tkcalendar import Calendar
import datetime

class MyCalendar(Calendar):
    def __init__(self, master=None, **kw):
        self._disabled_dates = []
        Calendar.__init__(self, master, **kw)

    def disable_date(self, date):
        self._disabled_dates.append(date)
        mi, mj = self._get_day_coords(date)
        if mi is not None:  # date is displayed
            self._calendar[mi][mj].state(['disabled'])

    def _display_calendar(self):
        Calendar._display_calendar(self)
        for date in self._disabled_dates:
            mi, mj = self._get_day_coords(date)
            if mi is not None:  # date is displayed
                self._calendar[mi][mj].state(['disabled'])

root = tk.Tk()
cal = MyCalendar(root, selectmode='day',
                 year=2022, month=5, disableddaybackground="red",
                 day=22)
cal.disable_date(datetime.date(2022, 5, 1))
cal.disable_date(datetime.date(2022, 5, 25))
cal.disable_date(datetime.date(2022, 5, 31))
cal.pack(pady=20)

def grad_date():
    date.config(text="Selected Date is: " + cal.get_date())

tk.Button(root, text="Get Date",
          command=grad_date).pack(pady=20)

date = tk.Label(root, text="")
date.pack(pady=20)

root.mainloop()

screenshot