Tiago Sousa
Tiago Sousa

Reputation: 23

How to restrict the tkcalendar to only select certain weekdays

I'm making a calendar and I wanted to restrict the user by only enable the selection of, for instance, Mondays. Is it possible? I can't find anything like that in the tkcalendar documentation.

Upvotes: 1

Views: 1137

Answers (1)

j_4321
j_4321

Reputation: 16179

tkcalendar.Calendar has the feature that when a day is "disabled" (each day is a ttk.Label), it cannot be selected and has a grayed out appearance. This is used to implement date ranges but it can be adapted for the purpose of only allowing certain weekdays.

The idea is to create a class inheriting from Calendar and modify the _display_calendar() method to disable the non allowed weekdays:

import tkinter as tk
import tkcalendar as tkc
import calendar


class MyCalendar(tkc.Calendar):
    def __init__(self, master=None, allowed_weekdays=(calendar.MONDAY,), **kw):
        self._select_only = allowed_weekdays
        tkc.Calendar.__init__(self, master, **kw)
        # change initially selected day if not right day
        if self._sel_date and not (self._sel_date.isoweekday() - 1) in allowed_weekdays:
            year, week, wday = self._sel_date.isocalendar()
            # get closest weekday
            next_wday = max(allowed_weekdays, key=lambda d: (d - wday + 1) > 0) + 1
            sel_date = self.date.fromisocalendar(year, week + int(next_wday < wday), next_wday)
            self.selection_set(sel_date)

    def _display_calendar(self):
        # display calendar
        tkc.Calendar._display_calendar(self)
        # disable not allowed days
        for i in range(6):
            for j in range(7):
                if j in self._select_only:
                    continue
                self._calendar[i][j].state(['disabled'])


root = tk.Tk()
cal = MyCalendar(root, allowed_weekdays=(calendar.WEDNESDAY, calendar.SATURDAY),
                 weekendbackground='white', weekendforeground='black',
                 othermonthbackground='gray95', othermonthwebackground='gray95',
                 othermonthforeground='black', othermonthweforeground='black')
cal.pack()
root.mainloop() 

screenshot

Upvotes: 0

Related Questions