Mal das ganze in einem Modul, mit zwei Klassen, in „pythonisch” statt „javaesque”, und ohne dauernd die halbe GUI neu zu erstellen und auszutauschen:
Code: Alles auswählen
from __future__ import print_function
try:
import Tkinter as tk
except ImportError:
import tkinter as tk
from calendar import Calendar, day_abbr, month_name
from datetime import date as Date
from functools import partial
try:
from future_builtins import zip
except ImportError:
pass
from itertools import chain, repeat
from locale import LC_ALL, setlocale
try:
range = xrange
except NameError:
pass
class Day(tk.Canvas, object):
def __init__(
self,
master,
day=0,
active_color='white',
disabled_color='grey',
size='2c'
):
self.active_color = active_color
self.disabled_color = disabled_color
tk.Canvas.__init__(
self,
master,
width=size,
height=size,
bg=self.disabled_color,
highlightbackground=self.disabled_color
)
self.create_text((1, 1), anchor='nw', tags='day_number')
self._day = None
self.day = day
@property
def day(self):
return self._day
@day.setter
def day(self, day):
self._day = day
self.itemconfig('day_number', text=day if day else '')
self['bg'] = self.active_color if day else self.disabled_color
class CalendarFrame(tk.Frame):
def __init__(
self, master, day_clicked_callback=lambda date: None, background='white'
):
tk.Frame.__init__(self, master)
self.day_clicked_callback = day_clicked_callback
today = Date.today()
self.year = today.year
self.month = today.month
self.calendar = Calendar()
self.header_label = tk.Label(self, font=20)
self.header_label.grid(row=0, column=1, columnspan=5)
tk.Button(
self, text='<-', command=self.goto_previous_month
).grid(row=0, column=0, sticky='news')
tk.Button(
self, text='->', command=self.goto_next_month
).grid(row=0, column=6, sticky='news')
for day in self.calendar.iterweekdays():
label = tk.Label(self, text=day_abbr[day], bg=background)
label.grid(row=1, column=day, sticky='we', padx=1)
self.cells = list()
for row_number in range(6):
row = list()
for column_number in range(7):
cell = Day(self, active_color=background)
cell.grid(row=row_number + 2, column=column_number)
cell.bind('<Button-1>', self._day_clicked)
row.append(cell)
self.cells.append(row)
self.update()
def _day_clicked(self, event):
day = event.widget.day
if day:
self.day_clicked_callback(Date(self.year, self.month, day))
def update(self):
self.header_label['text'] = '{0} - {1}'.format(
month_name[self.month], self.year
)
weeks = self.calendar.monthdayscalendar(self.year, self.month)
for cells, week in zip(self.cells, chain(weeks, repeat([0] * 7))):
for cell, day in zip(cells, week):
cell.day = day
def goto_previous_month(self):
if self.month == 1:
self.month = 12
self.year -= 1
else:
self.month -= 1
self.update()
def goto_next_month(self):
if self.month == 12:
self.month = 1
self.year += 1
else:
self.month += 1
self.update()
def main():
setlocale(LC_ALL, '')
root = tk.Tk()
calendar = CalendarFrame(root, partial(print, 'Tag:'))
calendar.pack()
root.mainloop()
if __name__ == '__main__':
main()