Guest User

Untitled

a guest
May 22nd, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.58 KB | None | 0 0
  1. import calendar
  2. import tkinter as tk
  3. import time
  4. from tkinter import ttk
  5.  
  6.  
  7. class MyDatePicker(tk.Toplevel):
  8. """
  9. Description:
  10. A tkinter GUI date picker.
  11. """
  12.  
  13. def __init__(self, widget=None, format_str=None):
  14. """
  15. :param widget: widget of parent instance.
  16.  
  17. :param format_str: print format in which to display date.
  18. :type format_str: string
  19.  
  20. Example::
  21. a = MyDatePicker(self, widget=self.parent widget,
  22. format_str='%02d-%s-%s')
  23. """
  24.  
  25. super().__init__()
  26. self.widget = widget
  27. self.str_format = format_str
  28.  
  29. self.title("Date Picker")
  30. self.resizable(0, 0)
  31. self.geometry("+630+390")
  32.  
  33. self.init_frames()
  34. self.init_needed_vars()
  35. self.init_month_year_labels()
  36. self.init_buttons()
  37. self.space_between_widgets()
  38. self.fill_days()
  39. self.make_calendar()
  40.  
  41. def init_frames(self):
  42. self.frame1 = tk.Frame(self)
  43. self.frame1.pack()
  44.  
  45. self.frame_days = tk.Frame(self)
  46. self.frame_days.pack()
  47.  
  48. def init_needed_vars(self):
  49. self.month_names = tuple(calendar.month_name)
  50. self.day_names = tuple(calendar.day_abbr)
  51. self.year = time.strftime("%Y")
  52. self.month = time.strftime("%B")
  53.  
  54. def init_month_year_labels(self):
  55. self.year_str_var = tk.StringVar()
  56. self.month_str_var = tk.StringVar()
  57.  
  58. self.year_str_var.set(self.year)
  59. self.year_lbl = tk.Label(self.frame1, textvariable=self.year_str_var,
  60. width=3)
  61. self.year_lbl.grid(row=0, column=5)
  62.  
  63. self.month_str_var.set(self.month)
  64. self.month_lbl = tk.Label(self.frame1, textvariable=self.month_str_var,
  65. width=8)
  66. self.month_lbl.grid(row=0, column=1)
  67.  
  68. def init_buttons(self):
  69. self.left_yr = ttk.Button(self.frame1, text="←", width=5,
  70. command=self.prev_year)
  71. self.left_yr.grid(row=0, column=4)
  72.  
  73. self.right_yr = ttk.Button(self.frame1, text="→", width=5,
  74. command=self.next_year)
  75. self.right_yr.grid(row=0, column=6)
  76.  
  77. self.left_mon = ttk.Button(self.frame1, text="←", width=5,
  78. command=self.prev_month)
  79. self.left_mon.grid(row=0, column=0)
  80.  
  81. self.right_mon = ttk.Button(self.frame1, text="→", width=5,
  82. command=self.next_month)
  83. self.right_mon.grid(row=0, column=2)
  84.  
  85. def space_between_widgets(self):
  86. self.frame1.grid_columnconfigure(3, minsize=40)
  87.  
  88. def prev_year(self):
  89. self.prev_yr = int(self.year_str_var.get()) - 1
  90. self.year_str_var.set(self.prev_yr)
  91.  
  92. self.make_calendar()
  93.  
  94. def next_year(self):
  95. self.next_yr = int(self.year_str_var.get()) + 1
  96. self.year_str_var.set(self.next_yr)
  97.  
  98. self.make_calendar()
  99.  
  100. def prev_month(self):
  101. index_current_month = self.month_names.index(self.month_str_var.get())
  102. index_prev_month = index_current_month - 1
  103.  
  104. # index 0 is empty string, use index 12 instead,
  105. # which is index of December.
  106. if index_prev_month == 0:
  107. self.month_str_var.set(self.month_names[12])
  108. else:
  109. self.month_str_var.set(self.month_names[index_current_month - 1])
  110.  
  111. self.make_calendar()
  112.  
  113. def next_month(self):
  114. index_current_month = self.month_names.index(self.month_str_var.get())
  115.  
  116. try:
  117. self.month_str_var.set(self.month_names[index_current_month + 1])
  118. except IndexError:
  119. # index 13 does not exist, use index 1 instead, which is January.
  120. self.month_str_var.set(self.month_names[1])
  121.  
  122. self.make_calendar()
  123.  
  124. def fill_days(self):
  125. col = 0
  126. # Creates days label
  127. for day in self.day_names:
  128. self.lbl_day = tk.Label(self.frame_days, text=day)
  129. self.lbl_day.grid(row=0, column=col)
  130. col += 1
  131.  
  132. def make_calendar(self):
  133. # Delete date buttons if already present.
  134. # Each button must have its own instance attribute for this to work.
  135. try:
  136. for dates in self.m_cal:
  137. for date in dates:
  138. if date == 0:
  139. continue
  140.  
  141. self.delete_buttons(date)
  142.  
  143. except AttributeError:
  144. pass
  145.  
  146. year = int(self.year_str_var.get())
  147. month = self.month_names.index(self.month_str_var.get())
  148. self.m_cal = calendar.monthcalendar(year, month)
  149.  
  150. # build dates buttons.
  151. for dates in self.m_cal:
  152. row = self.m_cal.index(dates) + 1
  153. for date in dates:
  154. col = dates.index(date)
  155.  
  156. if date == 0:
  157. continue
  158.  
  159. self.make_button(str(date), str(row), str(col))
  160.  
  161. def make_button(self, date, row, column):
  162. """
  163. Description:
  164. Build a date button.
  165.  
  166. :param date: date.
  167. :type date: string
  168.  
  169. :param row: row number.
  170. :type row: string
  171.  
  172. :param column: column number.
  173. :type column: string
  174. """
  175. exec(
  176. "self.btn_" + date + " = ttk.Button(self.frame_days, text=" + date
  177. + ", width=5)n"
  178. "self.btn_" + date + ".grid(row=" + row + " , column=" + column
  179. + ")n"
  180. "self.btn_" + date + ".bind("<Button-1>", self.get_date)"
  181. )
  182.  
  183. def delete_buttons(self, date):
  184. """
  185. Description:
  186. Delete a date button.
  187.  
  188. :param date: date.
  189. :type: string
  190. """
  191. exec(
  192. "self.btn_" + str(date) + ".destroy()"
  193. )
  194.  
  195. def get_date(self, clicked=None):
  196. """
  197. Description:
  198. Get the date from the calendar on button click.
  199.  
  200. :param clicked: button clicked event.
  201. :type clicked: tkinter event
  202. """
  203.  
  204. clicked_button = clicked.widget
  205. year = self.year_str_var.get()
  206. month = self.month_str_var.get()
  207. date = clicked_button['text']
  208.  
  209. self.full_date = self.str_format % (date, month, year)
  210. print(self.full_date)
  211. # Replace with parent 'widget' of your choice.
  212. try:
  213. self.widget.delete(0, tk.END)
  214. self.widget.insert(0, self.full_date)
  215. except AttributeError:
  216. pass
  217.  
  218.  
  219. if __name__ == '__main__':
  220. def application():
  221. MyDatePicker(format_str='%02d-%s-%s')
  222.  
  223. root = tk.Tk()
  224. btn = tk.Button(root, text="test", command=application)
  225. btn.pack()
  226. root.mainloop()
Add Comment
Please, Sign In to add comment