Python Forum
[Tkinter] tkinter calendar widget
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] tkinter calendar widget
#1
Tkinter does not have its own calendar widget. At least not by default. Here is a calendar selector widget. The Control class is just for laying a base program for testing. As well as show an example of calling the calendar widget. The choose button drops the calendar toplevel out, and is displayed in the current month and year. When you select OK, you save the date you selected shown in the label below and it disappears. Then in the test program you can see the date saved in a dictionary. 

import calendar
import datetime
import sys
if sys.version[0] == '2':
    import Tkinter as tk
else:
    import tkinter as tk

class Calendar:
    def __init__(self, parent, values):
        self.values = values
        self.parent = parent
        self.cal = calendar.TextCalendar(calendar.SUNDAY)
        self.year = datetime.date.today().year
        self.month = datetime.date.today().month
        self.wid = []
        self.day_selected = 1
        self.month_selected = self.month
        self.year_selected = self.year
        self.day_name = ''
        
        self.setup(self.year, self.month)
        
    def clear(self):
        for w in self.wid[:]:
            w.grid_forget()
            #w.destroy()
            self.wid.remove(w)
    
    def go_prev(self):
        if self.month > 1:
            self.month -= 1
        else:
            self.month = 12
            self.year -= 1
        #self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)

    def go_next(self):
        if self.month < 12:
            self.month += 1
        else:
            self.month = 1
            self.year += 1
        
        #self.selected = (self.month, self.year)
        self.clear()
        self.setup(self.year, self.month)
        
    def selection(self, day, name):
        self.day_selected = day
        self.month_selected = self.month
        self.year_selected = self.year
        self.day_name = name
        
        #data
        self.values['day_selected'] = day
        self.values['month_selected'] = self.month
        self.values['year_selected'] = self.year
        self.values['day_name'] = name
        self.values['month_name'] = calendar.month_name[self.month_selected]
        
        self.clear()
        self.setup(self.year, self.month)
        
    def setup(self, y, m):
        left = tk.Button(self.parent, text='<', command=self.go_prev)
        self.wid.append(left)
        left.grid(row=0, column=1)
        
        header = tk.Label(self.parent, height=2, text='{}   {}'.format(calendar.month_abbr[m], str(y)))
        self.wid.append(header)
        header.grid(row=0, column=2, columnspan=3)
        
        right = tk.Button(self.parent, text='>', command=self.go_next)
        self.wid.append(right)
        right.grid(row=0, column=5)
        
        days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
        for num, name in enumerate(days):
            t = tk.Label(self.parent, text=name[:3])
            self.wid.append(t)
            t.grid(row=1, column=num)
        
        for w, week in enumerate(self.cal.monthdayscalendar(y, m), 2):
            for d, day in enumerate(week):
                if day:
                    #print(calendar.day_name[day])
                    b = tk.Button(self.parent, width=1, text=day, command=lambda day=day:self.selection(day, calendar.day_name[(day-1) % 7]))
                    self.wid.append(b)
                    b.grid(row=w, column=d)
                    
        sel = tk.Label(self.parent, height=2, text='{} {} {} {}'.format(
            self.day_name, calendar.month_name[self.month_selected], self.day_selected, self.year_selected))
        self.wid.append(sel)
        sel.grid(row=8, column=0, columnspan=7)
        
        ok = tk.Button(self.parent, width=5, text='OK', command=self.kill_and_save)
        self.wid.append(ok)
        ok.grid(row=9, column=2, columnspan=3, pady=10)
        
    def kill_and_save(self):
        self.parent.destroy()


if __name__ == '__main__':

    class Control:
        def __init__(self, parent):
            self.parent = parent
            self.choose_btn = tk.Button(self.parent, text='Choose',command=self.popup)
            self.show_btn = tk.Button(self.parent, text='Show Selected',command=self.print_selected_date)
            self.choose_btn.grid()
            self.show_btn.grid()
            self.data = {}
            
        def popup(self):
            child = tk.Toplevel()
            cal = Calendar(child, self.data)
            
        def print_selected_date(self):
            print(self.data)
            

    root = tk.Tk()
    app = Control(root)
    root.mainloop()

Attached Files

Thumbnail(s)
   
Recommended Tutorials:
Reply
#2
this isn't selecting the correct day of the week. not sure how to tweak that part but something isn't right here...

https://ibb.co/nHR4VH
Reply
#3
(Mar-20-2018, 08:07 PM)thegodofcheese Wrote: this isn't selecting the correct day of the week. not sure how to tweak that part but something isn't right here...

https://ibb.co/nHR4VH

Just change this

#lines
#lines

class Calendar:
def __init__(self, parent, values):
self.values = values
self.parent = parent
self.cal = calendar.TextCalendar(calendar.SUNDAY)
self.year = datetime.date.today().year
self.month = datetime.date.today().month
day = datetime.date.today().day
self.wid = []
self.day_selected = day

#more lines

(May-18-2018, 05:22 PM)CandyMo0n Wrote:
(Mar-20-2018, 08:07 PM)thegodofcheese Wrote: this isn't selecting the correct day of the week. not sure how to tweak that part but something isn't right here...

https://ibb.co/nHR4VH

Just change this

#lines
#lines

class Calendar:
def __init__(self, parent, values):
self.values = values
self.parent = parent
self.cal = calendar.TextCalendar(calendar.SUNDAY)
self.year = datetime.date.today().year
self.month = datetime.date.today().month
actualday = datetime.date.today().day
self.wid = []
self.day_selected = actualday

#more lines
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  A Tkinter Widget-Templater/GUI Builder for Linux/Mac rootVIII 2 3,370 Jun-09-2020, 02:21 AM
Last Post: rootVIII

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020