Skip to content

Commit b39da7a

Browse files
committed
popup_get_file - HISTORY feature added! Replaced prints in packer function because can cause errors if strout has been rerouted, Combo no longer resizes on update if no size if given, combo added to the default focus list of elements
1 parent e37bfc9 commit b39da7a

File tree

1 file changed

+74
-17
lines changed

1 file changed

+74
-17
lines changed

PySimpleGUI.py

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/python3
22

3-
version = __version__ = "4.43.0.11 Unreleased\nChanged get_versions string to be more clear, removed canvas from return values, cwd is automatically set to the folder of the application being launched when execute_py_file is called with cwd=None, popup_get_file changed to set parent=None if running on Mac, better Button error handling when bad Unicode chars are used or bad colors, open GitHub issue GUI - added collapse button to top section, see-through mode in test harness changed to be a toggle, font parm for multiline update print cprint for char by char font control, clipboard_set & clipboard_get, Listbox visibility fix, Tree element expansion fixed, added new element_frame convention for elements that are in frames like the Listbox and Tree (need to check the other elements and add those that have frames), fix in debug print for font not being passed along, removed print"
3+
version = __version__ = "4.43.0.12 Unreleased\nChanged get_versions string to be more clear, removed canvas from return values, cwd is automatically set to the folder of the application being launched when execute_py_file is called with cwd=None, popup_get_file changed to set parent=None if running on Mac, better Button error handling when bad Unicode chars are used or bad colors, open GitHub issue GUI - added collapse button to top section, see-through mode in test harness changed to be a toggle, font parm for multiline update print cprint for char by char font control, clipboard_set & clipboard_get, Listbox visibility fix, Tree element expansion fixed, added new element_frame convention for elements that are in frames like the Listbox and Tree (need to check the other elements and add those that have frames), fix in debug print for font not being passed along, removed print, Combo size is not changed when updating unless user specifies a size, converted prints in the packer function into error popups, added Combo to the list of element capable of initially getting focus when default focus is used, popup_get_file gets history feature (NICE!)"
44

55
__version__ = version.split()[0] # For PEP 396 and PEP 345
66

@@ -1696,8 +1696,7 @@ def update(self, value=None, values=None, set_to_index=None, disabled=None, read
16961696
width = self.Size[0]
16971697
else:
16981698
width = max_line_len + 1
1699-
self.TKCombo.configure(height=self.Size[1])
1700-
self.TKCombo.configure(width=width)
1699+
# self.TKCombo.configure(width=width)
17011700
else:
17021701
self.TKCombo.configure(height=size[1])
17031702
self.TKCombo.configure(width=size[0])
@@ -12321,8 +12320,13 @@ def _string_width_in_pixels(font, string):
1232112320
def _valid_theme(style, theme_name):
1232212321
if theme_name in style.theme_names():
1232312322
return True
12324-
print('** Invalid ttk theme specified {} **'.format(theme_name),
12325-
'\nValid choices include: {}'.format(style.theme_names()))
12323+
_error_popup_with_traceback('Your Window has an invalid ttk theme specified',
12324+
'The traceback will show you the Window with the problem layout',
12325+
'** Invalid ttk theme specified {} **'.format(theme_name),
12326+
'\nValid choices include: {}'.format(style.theme_names()))
12327+
12328+
# print('** Invalid ttk theme specified {} **'.format(theme_name),
12329+
# '\nValid choices include: {}'.format(style.theme_names()))
1232612330
return False
1232712331

1232812332

@@ -12357,6 +12361,8 @@ def _add_right_click_menu(element):
1235712361
# --------------------------------------------------------------------------- #
1235812362
# **************** Use FlexForm to build the tkinter window ********** ----- #
1235912363
# Building is done row by row. #
12364+
# WARNING - You can't use print in this function. If the user has rerouted #
12365+
# stdout then there will be an error saying the window isn't finalized #
1236012366
# --------------------------------------------------------------------------- #
1236112367
######################### LOOP THROUGH ROWS #########################
1236212368
# *********** ------- Loop through ROWS ------- ***********#
@@ -12662,6 +12668,8 @@ def _add_right_click_menu(element):
1266212668

1266312669
element.TKButton = tkbutton # not used yet but save the TK button in case
1266412670
wraplen = tkbutton.winfo_reqwidth() # width of widget in Pixels
12671+
if elementpad[0] == 0 or elementpad[1] == 0:
12672+
tkbutton.config(highlightthickness=0)
1266512673

1266612674
## -------------- TK Button With Image -------------- ##
1266712675
if element.ImageFilename: # if button has an image on it
@@ -13000,6 +13008,7 @@ def _add_right_click_menu(element):
1300013008
if _valid_theme(s,toplevel_form.TtkTheme):
1300113009
s.theme_use(toplevel_form.TtkTheme)
1300213010
# s.theme_use('default')
13011+
1300313012
if element.TextColor is not None and element.TextColor != COLOR_SYSTEM_DEFAULT:
1300413013
# Creates 1 style per Text Color/ Background Color combination
1300513014
style_name = str(element.Key) + '.TCombobox'
@@ -13047,7 +13056,11 @@ def _add_right_click_menu(element):
1304713056
combostyle.configure(style_name, arrowcolor=theme_button_color()[0])
1304813057
combostyle.configure(style_name, background=theme_button_color()[1])
1304913058
except Exception as e:
13050-
print('* Problem setting combobox button color *', e)
13059+
_error_popup_with_traceback('Combo Element error {}'.format(e),
13060+
'Combo element key: {}'.format(element.Key),
13061+
'The theme button color is used to make the arrows. theme_button_color= {}'.format(theme_button_color()),
13062+
"Parent Window's Title: {}".format(toplevel_form.Title))
13063+
# print('* Problem setting combobox button color *', e)
1305113064

1305213065
# Strange code that is needed to set the font for the drop-down list
1305313066
element._newfont = tkinter.font.Font(font=font)
@@ -13061,6 +13074,10 @@ def _add_right_click_menu(element):
1306113074
element.TKCombo.bind("<Enter>", lambda event, em=element: testMouseHook2(em))
1306213075
element.TKCombo.bind("<Leave>", lambda event, em=element: testMouseUnhook2(em))
1306313076

13077+
if toplevel_form.UseDefaultFocus and not toplevel_form.FocusSet:
13078+
toplevel_form.FocusSet = True
13079+
element.TKCombo.focus_set()
13080+
1306413081
if element.Size[1] != 1 and element.Size[1] is not None:
1306513082
element.TKCombo.configure(height=element.Size[1])
1306613083
element.TKCombo['values'] = element.Values
@@ -17065,7 +17082,7 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s
1706517082
file_types=(("ALL Files", "*.*"),),
1706617083
no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None,
1706717084
icon=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False,
17068-
location=(None, None), initial_folder=None, image=None, files_delimiter=BROWSE_FILES_DELIMITER, modal=True):
17085+
location=(None, None), initial_folder=None, image=None, files_delimiter=BROWSE_FILES_DELIMITER, modal=True, history=False, history_setting_filename=None):
1706917086
"""
1707017087
Display popup window with text entry field and browse button so that a file can be chosen by user.
1707117088

@@ -17085,7 +17102,7 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s
1708517102
:type file_types: Tuple[Tuple[str,str]]
1708617103
:param no_window: if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown
1708717104
:type no_window: (bool)
17088-
:param size: (width, height) of the InputText Element
17105+
:param size: (width, height) of the InputText Element or Combo element if using history feature
1708917106
:type size: (int, int)
1709017107
:param button_color: Color of the button (text, background)
1709117108
:type button_color: (str, str) or str
@@ -17113,10 +17130,28 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s
1711317130
:type files_delimiter: str
1711417131
:param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True
1711517132
:type modal: bool
17133+
:param history: If True then enable a "history" feature that will display previous entries used. Uses settings filename provided or default if none provided
17134+
:type history: bool
17135+
:param history_setting_filename: Filename to use for the User Settings. Will store list of previous entries in this settings file
17136+
:type history_setting_filename: (str)
1711617137
:return: string representing the file(s) chosen, None if cancelled or window closed with X
1711717138
:rtype: str | None
1711817139
"""
1711917140

17141+
17142+
# First setup the history settings file if history feature is enabled
17143+
if history and history_setting_filename is not None:
17144+
try:
17145+
history_settings = UserSettings(history_setting_filename)
17146+
except Exception as e:
17147+
_error_popup_with_traceback('popup_get_file - Something is wrong with your supplied history settings filename',
17148+
'Exception: {}'.format(e))
17149+
return None
17150+
elif history:
17151+
history_settings_filename = os.path.basename(inspect.stack()[1].filename)
17152+
history_settings_filename = os.path.splitext(history_settings_filename)[0] + '.json'
17153+
history_settings = UserSettings(history_settings_filename)
17154+
1712017155
if icon is None:
1712117156
icon = Window._user_defined_icon or DEFAULT_BASE64_ICON
1712217157
if no_window:
@@ -17148,7 +17183,6 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s
1714817183

1714917184
if root and icon is not None:
1715017185
_set_icon_for_tkinter_window(root, icon=icon)
17151-
# TODO - Macs will not like this code because of the filetypes being used. Need another Darwin check.
1715217186
# for Macs, setting parent=None fixes a warning problem.
1715317187
if save_as:
1715417188
filename = tk.filedialog.asksaveasfilename(filetypes=file_types,
@@ -17194,22 +17228,44 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s
1719417228
else:
1719517229
layout = [[]]
1719617230

17197-
layout += [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)],
17198-
[InputText(default_text=default_path, size=size, key='_INPUT_'), browse_button],
17199-
[Button('Ok', size=(6, 1), bind_return_key=True), Button('Cancel', size=(6, 1))]]
17231+
layout += [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)]]
17232+
17233+
if not history:
17234+
layout += [[InputText(default_text=default_path, size=size, key='-INPUT-'), browse_button]]
17235+
else:
17236+
file_list = history_settings.get("-PSG file list-", [])
17237+
last_entry = file_list[0] if file_list else ''
17238+
layout += [[Combo(file_list, default_value=last_entry, key='-INPUT-', size=size if size != (None, None) else (80,1), bind_return_key=True), browse_button,Button('Clear History')]]
17239+
17240+
layout += [[Button('Ok', size=(6, 1), bind_return_key=True), Button('Cancel', size=(6, 1))]]
1720017241

1720117242
window = Window(title=title or message, layout=layout, icon=icon, auto_size_text=True, button_color=button_color,
1720217243
font=font,
1720317244
background_color=background_color,
1720417245
no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, modal=modal)
1720517246

17206-
button, values = window.read()
17247+
while True:
17248+
event, values = window.read()
17249+
if event in ('Cancel', WIN_CLOSED):
17250+
break
17251+
elif event == 'Clear History':
17252+
history_settings.set('-PSG file list-', [])
17253+
window['-INPUT-'].update('', [])
17254+
elif event in ('Ok', '-INPUT-'):
17255+
if values['-INPUT-'] != '':
17256+
list_of_entries = history_settings.get('-PSG file list-', [])
17257+
if values['-INPUT-'] in list_of_entries:
17258+
list_of_entries.remove(values['-INPUT-'])
17259+
list_of_entries.insert(0, values['-INPUT-'])
17260+
history_settings.set('-PSG file list-', list_of_entries)
17261+
break
17262+
1720717263
window.close(); del window
17208-
if button != 'Ok':
17264+
if event in ('Cancel', WIN_CLOSED):
1720917265
return None
17210-
else:
17211-
path = values['_INPUT_']
17212-
return path
17266+
17267+
return values['-INPUT-']
17268+
1721317269

1721417270

1721517271
# --------------------------- popup_get_text ---------------------------
@@ -20757,6 +20813,7 @@ def main():
2075720813
pysimplegui_user_settings = UserSettings(filename=DEFAULT_USER_SETTINGS_PYSIMPLEGUI_FILENAME, path=DEFAULT_USER_SETTINGS_PYSIMPLEGUI_PATH)
2075820814
#------------------------ Set the "Official PySimpleGUI Theme Colors" ------------------------
2075920815

20816+
2076020817
theme(theme_global())
2076120818

2076220819
# See if running on Trinket. If Trinket, then use custom titlebars since Trinket doesn't supply any

0 commit comments

Comments
 (0)