Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import calendar
- import tkinter as tk
- import time
- from tkinter import ttk
- class MyDatePicker(tk.Toplevel):
- """
- Description:
- A tkinter GUI date picker.
- """
- def __init__(self, widget=None, format_str=None):
- """
- :param widget: widget of parent instance.
- :param format_str: print format in which to display date.
- :type format_str: string
- Example::
- a = MyDatePicker(self, widget=self.parent widget,
- format_str='%02d-%s-%s')
- """
- super().__init__()
- self.widget = widget
- self.str_format = format_str
- self.title("Date Picker")
- self.resizable(0, 0)
- self.geometry("+630+390")
- self.init_frames()
- self.init_needed_vars()
- self.init_month_year_labels()
- self.init_buttons()
- self.space_between_widgets()
- self.fill_days()
- self.make_calendar()
- def init_frames(self):
- self.frame1 = tk.Frame(self)
- self.frame1.pack()
- self.frame_days = tk.Frame(self)
- self.frame_days.pack()
- def init_needed_vars(self):
- self.month_names = tuple(calendar.month_name)
- self.day_names = tuple(calendar.day_abbr)
- self.year = time.strftime("%Y")
- self.month = time.strftime("%B")
- def init_month_year_labels(self):
- self.year_str_var = tk.StringVar()
- self.month_str_var = tk.StringVar()
- self.year_str_var.set(self.year)
- self.year_lbl = tk.Label(self.frame1, textvariable=self.year_str_var,
- width=3)
- self.year_lbl.grid(row=0, column=5)
- self.month_str_var.set(self.month)
- self.month_lbl = tk.Label(self.frame1, textvariable=self.month_str_var,
- width=8)
- self.month_lbl.grid(row=0, column=1)
- def init_buttons(self):
- self.left_yr = ttk.Button(self.frame1, text="←", width=5,
- command=self.prev_year)
- self.left_yr.grid(row=0, column=4)
- self.right_yr = ttk.Button(self.frame1, text="→", width=5,
- command=self.next_year)
- self.right_yr.grid(row=0, column=6)
- self.left_mon = ttk.Button(self.frame1, text="←", width=5,
- command=self.prev_month)
- self.left_mon.grid(row=0, column=0)
- self.right_mon = ttk.Button(self.frame1, text="→", width=5,
- command=self.next_month)
- self.right_mon.grid(row=0, column=2)
- def space_between_widgets(self):
- self.frame1.grid_columnconfigure(3, minsize=40)
- def prev_year(self):
- self.prev_yr = int(self.year_str_var.get()) - 1
- self.year_str_var.set(self.prev_yr)
- self.make_calendar()
- def next_year(self):
- self.next_yr = int(self.year_str_var.get()) + 1
- self.year_str_var.set(self.next_yr)
- self.make_calendar()
- def prev_month(self):
- index_current_month = self.month_names.index(self.month_str_var.get())
- index_prev_month = index_current_month - 1
- # index 0 is empty string, use index 12 instead,
- # which is index of December.
- if index_prev_month == 0:
- self.month_str_var.set(self.month_names[12])
- else:
- self.month_str_var.set(self.month_names[index_current_month - 1])
- self.make_calendar()
- def next_month(self):
- index_current_month = self.month_names.index(self.month_str_var.get())
- try:
- self.month_str_var.set(self.month_names[index_current_month + 1])
- except IndexError:
- # index 13 does not exist, use index 1 instead, which is January.
- self.month_str_var.set(self.month_names[1])
- self.make_calendar()
- def fill_days(self):
- col = 0
- # Creates days label
- for day in self.day_names:
- self.lbl_day = tk.Label(self.frame_days, text=day)
- self.lbl_day.grid(row=0, column=col)
- col += 1
- def make_calendar(self):
- # Delete date buttons if already present.
- # Each button must have its own instance attribute for this to work.
- try:
- for dates in self.m_cal:
- for date in dates:
- if date == 0:
- continue
- self.delete_buttons(date)
- except AttributeError:
- pass
- year = int(self.year_str_var.get())
- month = self.month_names.index(self.month_str_var.get())
- self.m_cal = calendar.monthcalendar(year, month)
- # build dates buttons.
- for dates in self.m_cal:
- row = self.m_cal.index(dates) + 1
- for date in dates:
- col = dates.index(date)
- if date == 0:
- continue
- self.make_button(str(date), str(row), str(col))
- def make_button(self, date, row, column):
- """
- Description:
- Build a date button.
- :param date: date.
- :type date: string
- :param row: row number.
- :type row: string
- :param column: column number.
- :type column: string
- """
- exec(
- "self.btn_" + date + " = ttk.Button(self.frame_days, text=" + date
- + ", width=5)n"
- "self.btn_" + date + ".grid(row=" + row + " , column=" + column
- + ")n"
- "self.btn_" + date + ".bind("<Button-1>", self.get_date)"
- )
- def delete_buttons(self, date):
- """
- Description:
- Delete a date button.
- :param date: date.
- :type: string
- """
- exec(
- "self.btn_" + str(date) + ".destroy()"
- )
- def get_date(self, clicked=None):
- """
- Description:
- Get the date from the calendar on button click.
- :param clicked: button clicked event.
- :type clicked: tkinter event
- """
- clicked_button = clicked.widget
- year = self.year_str_var.get()
- month = self.month_str_var.get()
- date = clicked_button['text']
- self.full_date = self.str_format % (date, month, year)
- print(self.full_date)
- # Replace with parent 'widget' of your choice.
- try:
- self.widget.delete(0, tk.END)
- self.widget.insert(0, self.full_date)
- except AttributeError:
- pass
- if __name__ == '__main__':
- def application():
- MyDatePicker(format_str='%02d-%s-%s')
- root = tk.Tk()
- btn = tk.Button(root, text="test", command=application)
- btn.pack()
- root.mainloop()
Add Comment
Please, Sign In to add comment