# experiment with wxPython's wx.lib.calendar
# show weekends and holidays in different colour
# tested with Python25 and wxPython28 vegaseat 31jul2007
##########################################################################
# Modification Log
#-------------------------------------------------------------------------
# Date Changes
#-------------------------------------------------------------------------
# 08/01/2020 Modified by Robin Randall
# 08/15/2020 Fixed Year bug by changing range to (1980, 2100
# 08/16/2020 Removed "PySimple.py" bug
# 08/20/2020 Failed to get MDI working with popup calendar
# 08/20/2020 Failed to change Current Day highlighting to Black & Yellow (from Black & 'Blue)
# 08/22/2020 Added code to allow Month spinner to also control Year spinner. Year spinner does not affect Month
##########################################################################
import wx
import wx.lib.calendar
import wx.calendar
class Calendar_Panel(wx.Panel):
#class Calendar_Frame(wx.Frame):
""" create a panel with a calendar on it"""
def __init__(self, parent, id):
# create a panel
wx.Panel.__init__(self, parent, id)
#wx.Frame.__init__(self, *args, **kargs)
# create a label on the panel
self.label1 = wx.StaticText(self, id, "", wx.Point(25, 220))
# create the calendar
self.cal = wx.lib.calendar.Calendar(self, id, pos=(25, 35), size=(200, 180))
#self.cal = wx.calendar.CalendarCtrl(self, -1, wx.DateTime_Now(), pos=(25, 35), size=(200, 180))
# get the current month & year
start_month = self.cal.GetMonth()
start_year = self.cal.GetYear()
start_day = self.cal.GetDay()
self.cal.SetCurrentDay()
# mouse click on a day
self.Bind(wx.lib.calendar.EVT_CALENDAR, self.OnCalSelected)
text = "Current Date = %02d/%02d/%d" % (start_month, start_day, start_year)
self.label1.SetLabel(text)
# set some of the colours
self.SetBackgroundColour("yellow")
self.cal.SetWeekColor('white', 'blue')
self.cal.SetColor(wx.lib.calendar.COLOR_WEEKEND_FONT, 'black')
self.cal.SetColor(wx.lib.calendar.COLOR_WEEKEND_BACKGROUND, 'green')
self.cal.ShowWeekEnd()
# colour holidays of current month
self.set_days = holidays[start_month]
self.cal.AddSelect(self.set_days, 'red', 'white')
self.cal.Refresh()
# mouse click on a day
self.Bind(wx.lib.calendar.EVT_CALENDAR, self.OnCalSelected)
# create year spin
self.texty = wx.TextCtrl(self, -1, str(start_year), pos=(25, 10), size=(50, -1))
h = self.texty.GetSize().height
self.spiny = wx.SpinButton(self, -1, pos=(70, 10), size=(h*2, h))
#Allowed for wider Year Range
self.spiny.SetRange(1900, 2100)
self.spiny.SetValue(start_year)
self.Bind(wx.EVT_SPIN, self.OnSpiny, self.spiny)
# create month spin
self.textm = wx.TextCtrl(self, -1, str(start_month), pos=(130, 10), size=(50, -1))
h = self.textm.GetSize().height
self.spinm = wx.SpinButton(self, -1, pos=(170, 10), size=(h*2, h))
#New Range allows Month spinner to also set Year
self.spinm.SetRange(0, 13)
self.spinm.SetValue(start_month)
self.Bind(wx.EVT_SPIN, self.OnSpinm, self.spinm)
self.timer = wx.Timer(self)
self.timer.Start(1000)
self.Bind(wx.EVT_TIMER, self.update_date)
def update_date(self, evt):
date = wx.DateTime_Now()
self.cal.SetDate(date)
def OnCalToday(self, evt):
self.cal.SetHighlightColours(wx.lib.calendar.start_day, 'black', 'yellow')
def OnCalSelected(self, evt):
text = "Date selected = %02d/%02d/%d" % (evt.month, evt.day, evt.year)
self.label1.SetLabel(text)
def OnSpiny(self, event):
year = event.GetPosition()
self.texty.SetValue(str(year))
self.cal.SetYear(year)
self.ResetDisplay()
def OnSpinm(self, event):
month = event.GetPosition()
# Below code added so month spinner sets the year
year = self.cal.GetYear()
if (self.spinm.GetValue() == 13):
month = 1
year = year + 1
if (self.spinm.GetValue() == 0):
month = 12
year = year - 1
self.texty.SetValue(str(year))
self.cal.SetYear(year)
self.spinm.SetValue(month)
self.textm.SetValue(str(month))
self.cal.SetMonth(month)
self.ResetDisplay()
def ResetDisplay(self):
# reset holiday colour
self.cal.AddSelect(self.set_days, 'black', 'white')
# get number of the month
month = self.cal.GetMonth()
set_days = holidays[month]
# set new holiday colour
self.cal.AddSelect(set_days, 'red', 'yellow')
self.cal.Refresh()
# keep present list to reset colour
self.set_days = set_days
# fill these dates out for the present year
# some could change with another year
# {month: list of holiday dates in month}
holidays = {
1: [1],
2: [13],
3: [22],
4: [3],
5: [29],
6: [15],
7: [4, 11],
8: [],
9: [3],
10: [],
11: [27, 26],
12: [24, 25]
}
class MyApp(wx.App):
def OnInit(self):
return 1
if __name__ == '__main__':
app = MyApp(0)
# create a window/frame, no parent, -1 is default ID
frame = wx.Frame(None, -1, "Simple calendar", size = (260, 280))
#frame=wx.MDIParentFrame(None, -1, "MDI Parent", size = (260,280))
#instanciate the class
Calendar_Panel(frame, -1)
# frame=Calendar_Frame(None)
frame.Show(1)
# frame.Show()
app.MainLoop()