Reputation: 79
I am trying to use tkcalendar to display some events in my python tkinter application. I have a database of events and i put them in the calendar as in the following example (I have created a dictionary of events to show the case). In this example I loop over all events and put them all in the calendar
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import *
import tkcalendar
from tkcalendar import Calendar, DateEntry
import datetime
root = tk.Tk()
events={'2018-09-28':('London','meeting'),\
'2018-08-15':('Paris','meeting'),\
'2018-07-30':('New York','meeting')}
cal = Calendar(root, selectmode='day', year=2018, month=8)
for k in events.keys():
date=datetime.datetime.strptime(k,"%Y-%m-%d").date()
cal.calevent_create(date, events[k][0], events[k][1])
cal.tag_config('meeting', background='red', foreground='yellow')
cal.pack(fill="both", expand=True)
root.mainloop()
Up to now everything fine. The problem is that the database of events is quite large and expands several years. Ideally I would want to create only the events of the month being displayed. I need to detect when the user clicks on "Next month" and "Previous Month" (the standard buttons that come with the tkcalendar):
and create the events for the month being displayed. Is that even possible?
thank you very much in advance
Upvotes: 0
Views: 5409
Reputation: 16169
You can create a class inheriting from Calendar
and redefine the callbacks of the "Next month" and "Previous Month" buttons so that they generate a virtual event '<<CalendarMonthChanged>>'
. Then bind this event to a function that displays the current month events.
Here is the code:
from tkcalendar import Calendar
from tkinter import Tk
class MyCalendar(Calendar):
def _next_month(self):
Calendar._next_month(self)
self.event_generate('<<CalendarMonthChanged>>')
def _prev_month(self):
Calendar._prev_month(self)
self.event_generate('<<CalendarMonthChanged>>')
def _next_year(self):
Calendar._next_year(self)
self.event_generate('<<CalendarMonthChanged>>')
def _prev_year(self):
Calendar._prev_year(self)
self.event_generate('<<CalendarMonthChanged>>')
def get_displayed_month_year(self):
return self._date.month, self._date.year
def on_change_month(event):
# remove previously displayed events
cal.calevent_remove('all')
year, month = cal.get_displayed_month_year()
# display the current month events
# ...
print(year, month)
root = Tk()
cal = MyCalendar(root)
cal.pack()
cal.bind('<<CalendarMonthChanged>>', on_change_month)
root.mainloop()
Upvotes: 3