I am trying to create a tool in Python that allows the user to select a date or a range of dates through a calendar within a form using npyscreen.
The calendar should allow the user to select the month and year within a range of dates from November 1, 2012 to December 31, 2022.
I have tried using the Grid widget of npyscreen to display the calendar, but I cannot get all the dates to display within the form. Specifically, the Grid widget seems to have limited dimensions, which do not allow me to display all the dates of the calendar.
Below is the code I am using to create the calendar. Can you please help me resolve the issue?
import curses
import npyscreen
from datetime import datetime, timedelta
npyscreen.disableColor()
def terminal_dimensions():
return curses.initscr().getmaxyx()
class App(npyscreen.NPSApp):
def main(self):
form = npyscreen.FormBaseNew(name = "Tool to extract data")
column_height = terminal_dimensions()[0] - 30
widget_calendar = form.add(CalendarWidget, name = "CALENDAR", relx=2, rely=2, max_width=95, max_height=column_height)
self.selected_dates_widget = form.add(SelectedDatesWidget, name = "SELECTED DATES", relx=100, rely=2, max_height=column_height)
widget_fileman = form.add(npyscreen.BoxTitle, name = "FILE MANAGER", relx=2, rely=column_height + 2, max_height=column_height)
widget_messages = form.add(npyscreen.BoxTitle, name = "MESSAGES", rely=column_height + 24, max_height=4)
form.edit()
class CalendarWidget(npyscreen.GridColTitles):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.col_titles = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
self.col_width = 3
self.row_height = 2
self.start_date = datetime(2012, 11, 1)
self.end_date = datetime(2022, 12, 31)
self.current_date = datetime.now()
self.display_month = self.current_date.month
self.display_year = self.current_date.year
self.selected_dates = []
self.update_values()
def update_values(self):
days_in_month = (self.start_date.replace(year=self.display_year, month=self.display_month, day=1) - timedelta(days=1)).day
first_day_of_month = datetime(self.display_year, self.display_month, 1).weekday()
self.values = [[''] * 7 for _ in range(6)]
current_day = 1
for row in range(6):
for col in range(7):
if row == 0 and col < first_day_of_month:
continue
if current_day > days_in_month:
break
self.values[row][col] = current_day
current_day += 1
def when_cursor_moved(self):
self.parent.selected_dates_widget.reset_selection()
self.parent.display()
def get_selected_objects(self):
return self.selected_dates
def when_value_edited(self):
self._old_value = self.value
super().when_value_edited()
if not self.get_selected_objects():
return
selected_date = datetime(self.display_year, self.display_month, int(self.get_selected_objects()[0]))
self.parent.selected_dates_widget.update_selection(selected_date)
self.parent.display()
class SelectedDatesWidget(npyscreen.BoxTitle):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.values = []
def reset_selection(self):
self.values = []
self.display()
def update_selection(self, selected_date):
self.values.append(selected_date.strftime('%Y-%m-%d'))
self.display()
if __name__ == "__main__":
app = App()
try:
app.run()
except:
curses.endwin()
Thank you in advance for your help.