How to set up ttk software calendar

I am using this ttk calendar in my application.

What I want to do is set the calendar using the datetime.date instance so that when the calendar appears, the highlighted date is highlighted.

I thought I could go through the _show_selection method with manual text and bbox args. To test this idea, I put this line at the end of the __init__ method:

self._show_selection('%02d'%16,(42,61,41,20))

I was hoping this would emphasize the 16th of this month (May), but it is not.

I got arguments from running print text, bbox in the _pressed method.

If anyone can shed light on this, I would really appreciate it.

+6
source share
2 answers

__Setup_selection () has a binding to the Configure event. Presumably, he should remove the “selection canvas” when the calendar changes. However, the Configure event also fires when the calendar is first displayed on the screen, so your selected date disappears before you see it.

set_day (below) allows you to select a day programmatically. This wraps around the problem of this first Configure event, rescheduling itself if the widget is not yet visible.

Changes to Calendar:

 def __setup_selection(self, sel_bg, sel_fg): self._font = font.Font() self._canvas = canvas = tkinter.Canvas(self._calendar, background=sel_bg, borderwidth=0, highlightthickness=0) canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w') canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget()) #self._calendar.bind('<Configure>', lambda evt: canvas.place_forget()) self._calendar.bind('<Configure>', self.on_configure) self._calendar.bind('<ButtonPress-1>', self._pressed) def on_configure(self, event): self._canvas.place_forget() if self._selection is not None: text, iid, column = self._selection bbox = self._calendar.bbox(iid, column) self._show_selection(text, bbox) def _prev_month(self): """Updated calendar to show the previous month.""" self._canvas.place_forget() self._selection = None # self._date = self._date - self.timedelta(days=1) self._date = self.datetime(self._date.year, self._date.month, 1) self._build_calendar() # reconstuct calendar def _next_month(self): """Update calendar to show the next month.""" self._canvas.place_forget() self._selection = None # year, month = self._date.year, self._date.month self._date = self._date + self.timedelta( days=calendar.monthrange(year, month)[1] + 1) self._date = self.datetime(self._date.year, self._date.month, 1) self._build_calendar() # reconstruct calendar def set_day(self, day): w = self._calendar if not w.winfo_viewable(): w.after(200, self.set_day, day) return text = '%02d' % day column = None for iid in self._items: rowvals = w.item(iid, 'values') try: column = rowvals.index(text) except ValueError as err: pass else: item = iid bbox = w.bbox(iid, column) break if column is not None: self._selection = (text, item, column) self._show_selection(text, bbox) #test def test(): import sys root = tkinter.Tk() root.title('Ttk Calendar') ttkcal = Calendar(firstweekday=calendar.SUNDAY) ttkcal.pack(expand=1, fill='both') if 'win' not in sys.platform: style = ttk.Style() style.theme_use('clam') ttkcal.set_day(16) # root.mainloop() 
0
source

For the most part, @Oblivion is correct, however I want to be able to use the Datetime.date object and be able to pass months and years if necessary. As soon as I changed the set_day method below, everything works fine.

 def set_day(self, dt_object): day = dt_object.day w = self._calendar if not w.winfo_viewable(): w.after(200, self.set_day, dt_object) return while dt_object.year < self._date.year: self._prev_month() while dt_object.year > self._date.year: self._next_month() while dt_object.month < self._date.month: self._prev_month() while dt_object.month > self._date.month: self._next_month() text = '%02d' % day column = None for iid in self._items: rowvals = w.item(iid, 'values') try: column = rowvals.index(text) except ValueError as err: pass else: item = iid bbox = w.bbox(iid, column) break if column is not None: self._selection = (text, item, column) self._show_selection(text, bbox) else: print "Column is None" 
0
source

All Articles