This simple request is a bit more complicated than it first looks, as you have to wait for a result of a date selection, other than now, without over complicating it.
Putting it all in the same class would make life easier, as would using wx.DatePickerCtrl
For what it is worth, here is my attempt at answering your whole question.
import wx
import wx.calendar
import time
class MyCalendar(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self, parent, wx.ID_ANY, "Calendar",size=(300,300))
self.Panel = wx.Panel(self)
self.cal = wx.calendar.CalendarCtrl(self.Panel, 10, wx.DateTime.Now())
self.cal.Bind(wx.calendar.EVT_CALENDAR, self.OnDate)
self.Show()
def OnDate(self,event):
self.Destroy()
return self.cal.GetDate()
class Myframe(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.Panel = wx.Panel(self)
self.Button = wx.Button(self.Panel, label="Calendar",size=(60,25),pos=(10,300))
self.Selected = wx.TextCtrl(self.Panel, -1,"Selected Date",size=(300,25),pos=(10,50))
self.Button.Bind(wx.EVT_BUTTON, self.ShowCal)
self.Show()
def ShowCal(self,event):
now = wx.DateTime.Now()
now.SetHMS(0)
self.Selected_date = MyCalendar(self.Panel)
while self.Selected_date and self.Selected_date.cal.GetDate() == now:
wx.Yield()
time.sleep(0.1)
try:
self.Selected.SetValue(str(self.Selected_date.cal.GetDate()))
except:
self.Selected.SetValue("Nothing selected")
if __name__ == '__main__':
app = wx.App()
frame = Myframe(None)
app.MainLoop()
I'm sure that there must be a more elegant way of achieving this and hopefully someone else will produce an answer but as you can see I have opted to wait in a while loop until a result other than Now is selected and Now has been adjusted to be midnight, today, as that is what Calendar returns.
Edit:
The answer is to use an event, which is fired by the calendar date selection (double clicking on a date)
import wx
import wx.adv
import datetime
import wx.lib.newevent
cal_event, EVT_CAL_EVENT = wx.lib.newevent.NewEvent()
class MyCalendar(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self, parent, wx.ID_ANY, "Calendar",size=(300,300))
self.parent = parent
self.Panel = wx.Panel(self)
self.cal = wx.adv.CalendarCtrl(self.Panel, 10, wx.DateTime.Now())
self.cal.Bind(wx.adv.EVT_CALENDAR, self.OnDate)
self.Show()
def OnDate(self,event):
evt = cal_event(data=self.cal.GetDate())
wx.PostEvent(self, evt) #post EVT_CAL_EVENT
class Myframe(wx.Frame):
def __init__(self, *args, **kwargs):
wx.Frame.__init__(self, *args, **kwargs)
self.Panel = wx.Panel(self)
self.Button = wx.Button(self.Panel, label="Calendar",size=(60,25),pos=(10,300))
self.Selected = wx.TextCtrl(self.Panel, -1,"Selected Date",size=(300,25),pos=(10,50))
self.Button.Bind(wx.EVT_BUTTON, self.ShowCal)
self.Show()
def ShowCal(self,event):
now = wx.DateTime.Now()
now.SetHMS(0)
self.Selected_date = MyCalendar(self)
self.Selected_date.Bind(EVT_CAL_EVENT, self.GetCal)
def GetCal(self,event):
ymd = map(int, event.data.FormatISODate().split('-'))
d = datetime.date(*ymd) # Convert to a datetime so we can use standard formatting
self.Selected.SetValue(d.strftime("%a - %d/%m/%Y"))
self.Selected_date.Destroy()
del self.Selected_date
if __name__ == '__main__':
app = wx.App()
frame = Myframe(None)
app.MainLoop()
This provides the date as "Weekday name - dd/mm/yyyy" e.g. Tue - 23/02/2021