Calendar Class In Flet And Python

A simple Calendar class for flet. I needed a calendar so I made one. I hope someone finds it useful.

import flet as ft
import datetime
import calendar
from calendar import HTMLCalendar
from dateutil import relativedelta

'''
FletCalendar in Python.

Flet does not have one so I needed to make my own
and I thought I would share.

Author: C. Nichols <mohawke@gmail.com>
License: WTFPL
    
WTFPL — Do What the Fuck You Want to Public License
Requirements: You need to install the following. pip install flet I suggest you use a Python virtual environment. That will keep your system Python clean and make it easier to manage you Flet project. https://docs.python.org/3/library/venv.html ''' class FletCalendar(ft.UserControl): def __init__(self, page): super().__init__() self.page = page self.get_current_date() self.set_theme() # Init the container control. self.calendar_container = ft.Container(width=355, height=300, padding=ft.padding.all(2), border=ft.border.all(2, self.border_color), border_radius=ft.border_radius.all(10), alignment=ft.alignment.bottom_center) self.build() # Build the calendar. self.output = ft.Text() # Add output control. def get_current_date(self): '''Get the initial current date''' today = datetime.datetime.today() self.current_month = today.month self.current_day = today.day self.current_year = today.year def selected_date(self, e): '''User selected date''' self.output.value = e.control.data self.output.update() #return e.control.data def set_current_date(self): '''Set the calendar to the current date.''' today = datetime.datetime.today() self.current_month = today.month self.current_day = today.day self.current_year = today.year self.build() self.calendar_container.update() def get_next(self, e): '''Move to the next month.''' current = datetime.date(self.current_year, self.current_month, self.current_day) add_month = relativedelta.relativedelta(months=1) next_month = current + add_month self.current_year = next_month.year self.current_month = next_month.month self.current_day = next_month.day self.build() self.calendar_container.update() def get_prev(self, e): '''Move to the previous month.''' current = datetime.date(self.current_year, self.current_month, self.current_day) add_month = relativedelta.relativedelta(months=1) next_month = current - add_month self.current_year = next_month.year self.current_month = next_month.month self.current_day = next_month.day self.build() self.calendar_container.update() def get_calendar(self): '''Get the calendar from the calendar module.''' cal = HTMLCalendar() return cal.monthdayscalendar(self.current_year, self.current_month) def set_theme(self, border_color=ft.colors.PINK_700, text_color=ft.colors.PINK_50, current_day_color=ft.colors.PINK_700): self.border_color = border_color self.text_color = text_color self.current_day_color = current_day_color def build(self): '''Build the calendar for flet.''' current_calendar = self.get_calendar() str_date = '{0} {1}, {2}'.format(calendar.month_name[self.current_month], self.current_day, self.current_year) date_display = ft.Text(str_date, text_align='center', size=20, color=self.text_color) next_button = ft.Container( ft.Text('>', text_align='right', size=20, color=self.text_color), on_click=self.get_next ) div = ft.Divider(height=1, thickness=2.0, color=self.border_color) prev_button = ft.Container( ft.Text('<', text_align='left', size=20, color=self.text_color), on_click=self.get_prev ) calendar_column = ft.Column([ft.Row([prev_button, date_display, next_button], alignment=ft.MainAxisAlignment.SPACE_EVENLY, vertical_alignment=ft.CrossAxisAlignment.CENTER, height=40, expand=False), div], spacing=2, width=355, height=330, alignment=ft.MainAxisAlignment.START, expand=False) # Loop weeks and add row. for week in current_calendar: week_row = ft.Row(alignment=ft.MainAxisAlignment.CENTER) # Loop days and add days to row. for day in week: if day > 0: is_current_day_font = ft.FontWeight.W_300 is_current_day_bg = ft.colors.TRANSPARENT display_day = str(day) if len(str(display_day)) == 1: display_day = '0%s' % display_day if day == self.current_day: is_current_day_font = ft.FontWeight.BOLD is_current_day_bg = self.current_day_color day_button = ft.Container(content=ft.Text(str(display_day), weight=is_current_day_font, color=self.text_color), on_click=self.selected_date, data=(self.current_month, day, self.current_year), width=40, height=40, ink=True, alignment=ft.alignment.center, border_radius=ft.border_radius.all(10), bgcolor=is_current_day_bg) else: day_button = ft.Container(width=40, height=40, border_radius=ft.border_radius.all(10)) week_row.controls.append(day_button) # Add the weeks to the main column. calendar_column.controls.append(week_row) # Add column to our page container. self.calendar_container.content = calendar_column return self.calendar_container def main(page: ft.Page): page.theme = ft.theme.Theme(color_scheme_seed=ft.colors.PINK) page.dark_theme = ft.theme.Theme(color_scheme_seed=ft.colors.PINK) # Instantiate the FletCalendar class. mycal = FletCalendar(page) # Add to our application. page.add(mycal, mycal.output) page.update() ft.app(target=main)