Integrated new date chooser!! (FINALLY)

This commit is contained in:
PySimpleGUI 2020-03-30 09:56:42 -04:00
parent 81c021332d
commit 08e11e860c
1 changed files with 92 additions and 43 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/python3
version = __version__ = "4.18.0.4 Unreleased - Print and MLine.Print fixed sep char handling, popup_get_date, icon parm popup_animated, popup button size (6,1)"
version = __version__ = "4.18.0.5 Unreleased - Print and MLine.Print fixed sep char handling, popup_get_date, icon parm popup_animated, popup button size (6,1), NEW CALENDAR chooser integrated"
port = 'PySimpleGUI'
@ -118,6 +118,7 @@ import datetime
import time
import pickle
import calendar
import datetime
import textwrap
import inspect
# from typing import List, Any, Union, Tuple, Dict # because this code has to run on 2.7 can't use real type hints. Must do typing only in comments
@ -128,7 +129,6 @@ from math import fabs
from functools import wraps
from subprocess import run, PIPE
from threading import Thread
import calendar as cal
import itertools
import os
@ -2787,6 +2787,11 @@ class Button(Element):
self.TKCal = None
self.CalendarCloseWhenChosen = None
self.CalendarDefaultDate_M_D_Y = (None, None, None)
self.CalendarCloseWhenChosen = False
self.CalendarLocale = None
self.CalendarFormat = None
self.CalendarNoTitlebar = True
self.CalendarBeginAtSundayPlus = 0
self.InitialFolder = initial_folder
self.Disabled = disabled
self.ChangeSubmits = change_submits or enable_events
@ -2937,37 +2942,48 @@ class Button(Element):
Window._DecrementOpenCount()
elif self.BType == BUTTON_TYPE_CALENDAR_CHOOSER: # this is a return type button so GET RESULTS and destroy window
# ------------ new chooser code -------------
#
# if self.CalendarDefaultDate_M_D_Y == (None, None, None):
# now = datetime.datetime.now()
# cur_month, cur_day, cur_year = now.month, now.day, now.year
# else:
# cur_month, cur_day, cur_year = self.CalendarDefaultDate_M_D_Y
#
# date_chosen = popup_get_date(start_mon=cur_month, start_day=cur_day, start_year=cur_year, close_when_chosen=self.CalendarCloseWhenChosen)
#
# strvar.set(date_chosen)
# self.TKStringVar.set(date_chosen)
if self.CalendarDefaultDate_M_D_Y == (None, None, None):
now = datetime.datetime.now()
cur_month, cur_day, cur_year = now.month, now.day, now.year
else:
cur_month, cur_day, cur_year = self.CalendarDefaultDate_M_D_Y
date_chosen = popup_get_date(start_mon=cur_month, start_day=cur_day, start_year=cur_year, close_when_chosen=self.CalendarCloseWhenChosen, no_titlebar=self.CalendarNoTitlebar, begin_at_sunday_plus=self.CalendarBeginAtSundayPlus, locale=self.CalendarLocale)
if date_chosen is not None:
month, day, year = date_chosen
now = datetime.datetime.now()
hour, minute, second = now.hour, now.minute, now.second
try:
date_string = calendar.datetime.datetime(year, month, day, hour, minute, second).strftime(self.CalendarFormat)
except Exception as e:
print('Bad format string', e)
date_string = 'Bad format string'
target_element.update(date_string)
strvar.set(date_string)
self.TKStringVar.set(date_string)
# ------------ old chooser code -------------
should_submit_window = False
root = tk.Toplevel()
root.title('Calendar Chooser')
root.wm_attributes("-topmost", 1)
self.TKCal = TKCalendar(master=root, firstweekday=calendar.SUNDAY, target_element=target_element,
close_when_chosen=self.CalendarCloseWhenChosen, default_date=self.CalendarDefaultDate_M_D_Y,
locale=self.CalendarLocale, format=self.CalendarFormat)
self.TKCal.pack(expand=1, fill='both')
root.update()
if type(Window._user_defined_icon) is bytes:
calendar_icon = tkinter.PhotoImage(data=Window._user_defined_icon)
else:
calendar_icon = tkinter.PhotoImage(data=DEFAULT_BASE64_ICON)
try:
root.tk.call('wm', 'iconphoto', root._w, calendar_icon)
except:
pass
# should_submit_window = False
# root = tk.Toplevel()
# root.title('Calendar Chooser')
# root.wm_attributes("-topmost", 1)
# self.TKCal = TKCalendar(master=root, firstweekday=calendar.SUNDAY, target_element=target_element,
# close_when_chosen=self.CalendarCloseWhenChosen, default_date=self.CalendarDefaultDate_M_D_Y,
# locale=self.CalendarLocale, format=self.CalendarFormat)
# self.TKCal.pack(expand=1, fill='both')
# root.update()
#
# if type(Window._user_defined_icon) is bytes:
# calendar_icon = tkinter.PhotoImage(data=Window._user_defined_icon)
# else:
# calendar_icon = tkinter.PhotoImage(data=DEFAULT_BASE64_ICON)
# try:
# root.tk.call('wm', 'iconphoto', root._w, calendar_icon)
# except:
# pass
elif self.BType == BUTTON_TYPE_SHOW_DEBUGGER:
if self.ParentForm.DebuggerEnabled:
_Debugger.debugger._build_floating_window()
@ -8925,21 +8941,30 @@ def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True
image_filename=None, image_data=None, image_size=(None, None),
image_subsample=None, tooltip=None, border_width=None, size=(None, None), auto_size_button=None,
button_color=None, disabled=False, font=None, bind_return_key=False, focus=False, pad=None,
key=None, locale=None, format=None, metadata=None):
key=None, locale=None, format='%Y-%m-%d %H:%M:%S', begin_at_sunday_plus=0, no_titlebar=True, metadata=None):
"""
Button that will show a calendar chooser window. Fills in the target element with result
:param button_text: text in the button
:type button_text: (str)
:param target:
:param target: Key or "coordinate" (see docs) of target element
:type target: Union[(int, int), Any]
:param close_when_date_chosen: (Default = True)
:param default_date_m_d_y: (Default = (None))
:type close_when_date_chosen: bool
:param default_date_m_d_y: Beginning date to show
:type default_date_m_d_y: (int, int or None, int)
:param image_filename: image filename if there is a button image
:type image_filename: image filename if there is a button image
:param image_data: in-RAM image to be displayed on button
:type image_data: in-RAM image to be displayed on button
:param image_size: (Default = (None))
:param image_subsample:amount to reduce the size of the image
:type image_size: (Default = (None))
:param image_subsample: amount to reduce the size of the image
:type image_subsample: amount to reduce the size of the image
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
:param border_width: width of border around element
:type border_width: width of border around element
:param size: (w,h) w=characters-wide, h=rows-high
:type size: Tuple[int, int]
:param auto_size_button: True if button size is determined by button text
@ -8951,13 +8976,21 @@ def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True
:param font: specifies the font family, size, etc
:type font: Union[str, Tuple[str, int]]
:param bind_return_key: (Default = False)
:type bind_return_key: bool
:param focus: if focus should be set to this
:type focus: bool
:param pad: Amount of padding to put around element in pixels (left/right, top/bottom)
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int)
:param key: key for uniquely identify this element (for window.FindElement)
:type key: Union[str, int, tuple]
:param locale:
:param format:
:param locale: defines the locale used to get day names
:type locale: str
:param format: formats result using this strftime format
:type format: str
:param no_titlebar: if True no titlebar will be shown on the date chooser window
:type no_titlebar: bool
:param metadata: Anything you want to store along with this button
:type metadata: Any
:return: returns a button
:rtype: (Button)
"""
@ -8970,6 +9003,8 @@ def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True
button.CalendarDefaultDate_M_D_Y = default_date_m_d_y
button.CalendarLocale = locale
button.CalendarFormat = format
button.CalendarNoTitlebar = no_titlebar
button.CalendarBeginAtSundayPlus = begin_at_sunday_plus
return button
@ -14247,20 +14282,22 @@ def PopupGetText(message, title=None, default_text='', password_char='', size=(N
def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus=0, no_titlebar=True, keep_on_top=True, location=(None, None), close_when_chosen=False, icon=None):
def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus=0, no_titlebar=True, keep_on_top=True, location=(None, None), close_when_chosen=False, icon=None, locale=None):
"""
Display a calendar window, get the user's choice, return as a tuple (mon, day, year)
:param start_mon: The starting month
:type start_mon: int
:param start_day: The starting day - optional. Set to 0 if no date to be chosen at start
:type start_day: int
:type start_day: int or None
:param start_year: The starting year
:type start_year: int
:param begin_at_sunday_plus: Determines the left-most day in the display. 0=sunday, 1=monday, etc
:type begin_at_sunday_plus: int
:param icon: Same as Window icon parameter. Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO
:type icon: str
:param locale: locale used to get the day names
:type locale: str
:return: Tuple containing (month, day, year) of chosen date or None if was cancelled
:rtype: None or (int, int, int)
"""
@ -14271,7 +14308,7 @@ def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus=0, no
def update_days(window, month, year, begin_at_sunday_plus):
[window[(week, day)].update('') for day in range(7) for week in range(6)]
weeks = cal.monthcalendar(year, month)
weeks = calendar.monthcalendar(year, month)
month_days = list(itertools.chain.from_iterable([[0 for _ in range(8 - begin_at_sunday_plus)]] + weeks))
if month_days[6] == 0:
month_days = month_days[7:]
@ -14296,12 +14333,24 @@ def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus=0, no
cur_year = start_year
cur_day = start_day
def get_month_name(month_no, locale):
with calendar.different_locale(locale):
return calendar.month_name[month_no]
def get_day_name(day_no, locale):
with calendar.different_locale(locale):
return calendar.day_abbr[day_no]
month_names = [get_month_name(month, locale) for month in range(1,13)]
day_names = [get_day_name(day, locale) for day in range(0,7)]
days_layout = make_days_layout()
layout = [[B('', font=arrow_font, border_width=0, key='-MON-DOWN-'),
Text('{} {}'.format(cal.month_name[cur_month], cur_year), size=(16,1), justification='c', font=mon_year_font, key='-MON-YEAR-'),
Text('{} {}'.format(month_names[cur_month-1], cur_year), size=(16,1), justification='c', font=mon_year_font, key='-MON-YEAR-'),
B('', font=arrow_font,border_width=0, key='-MON-UP-')]]
layout += [[Col([[T(cal.day_abbr[i - (8 - begin_at_sunday_plus) % 7], size=(4,1), font=day_font, background_color=theme_text_color(), text_color=theme_background_color(), pad=(0,0)) for i in range(7)]], background_color=theme_text_color(), pad=(0,0))]]
layout += [[Col([[T(day_names[i - (8 - begin_at_sunday_plus) % 7], size=(4,1), font=day_font, background_color=theme_text_color(), text_color=theme_background_color(), pad=(0,0)) for i in range(7)]], background_color=theme_text_color(), pad=(0,0))]]
layout += days_layout
if not close_when_chosen:
layout += [[Button('Ok', border_width=0,font='TkFixedFont 8'), Button('Cancel',border_width=0, font='TkFixedFont 8')]]
@ -14336,7 +14385,7 @@ def popup_get_date(start_mon, start_day, start_year, begin_at_sunday_plus=0, no
elif cur_month < 1:
cur_month = 12
cur_year -= 1
window['-MON-YEAR-'].update('{} {}'.format(cal.month_name[cur_month], cur_year))
window['-MON-YEAR-'].update('{} {}'.format(month_names[cur_month-1], cur_year))
update_days(window, cur_month, cur_year, begin_at_sunday_plus)
if prev_choice:
window[prev_choice].update(background_color=theme_background_color(), text_color=theme_text_color())