From 5a2d1a6c77b61f6c829d4f1a8e84fb71a6d5cec6 Mon Sep 17 00:00:00 2001 From: PySimpleGUI Date: Thu, 23 Jul 2020 17:25:38 -0400 Subject: [PATCH 1/2] Renamed the dark theme previewer demo --- ...eme_Dump.py => Demo_Theme_Previewer_Dark.py} | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) rename DemoPrograms/{Demo_Theme_Dump.py => Demo_Theme_Previewer_Dark.py} (67%) diff --git a/DemoPrograms/Demo_Theme_Dump.py b/DemoPrograms/Demo_Theme_Previewer_Dark.py similarity index 67% rename from DemoPrograms/Demo_Theme_Dump.py rename to DemoPrograms/Demo_Theme_Previewer_Dark.py index 296e6844..905df349 100644 --- a/DemoPrograms/Demo_Theme_Dump.py +++ b/DemoPrograms/Demo_Theme_Previewer_Dark.py @@ -5,7 +5,10 @@ import PySimpleGUI as sg """ If you're using the PySimpleGUI color themes, then your code will a line that looks something like this: sg.theme('Light Green 1') or sg.theme('LightGreen1') - This demo shows how to access the list of all themes to build your own previewer + + This demo shows how to access the list of all "dark themes" as an example of how you can build your own previewer + + Copyright 2020 PySimpleGUI.org """ # Use the built-in Theme Viewer to show all of the themes and their names @@ -18,6 +21,11 @@ import PySimpleGUI as sg window_background = 'black' def sample_layout(): + """ + Creates a small window that will represent the colors of the theme. This is an individual theme's preview + :return: layout of a little preview window + :rtype: List[List[Element]] + """ return [[sg.Text('Text element'), sg.InputText('Input data here', size=(15, 1))], [sg.Button('Ok'), sg.Button('Cancel'), sg.Slider((1, 10), orientation='h', size=(10, 15))]] @@ -25,8 +33,7 @@ def sample_layout(): layout = [[sg.Text('List of Dark Themes Provided by PySimpleGUI', font='Default 18', background_color=window_background)]] FRAMES_PER_ROW = 9 -names = sg.theme_list() -names = [name for name in names if 'dark' in name.lower()] +names = [name for name in sg.theme_list() if 'dark' in name.lower()] # get list of only "dark" themes row = [] for count, theme in enumerate(names): sg.theme(theme) @@ -37,6 +44,4 @@ for count, theme in enumerate(names): if row: layout += [row] -window = sg.Window('Custom Preview of Themes', layout, background_color=window_background) -window.read() -window.close() +sg.Window('Custom Preview of Themes', layout, background_color=window_background).read(close=True) From 0b13ae8ed0cd54a10c29c00fdfc9037dd0ae3397 Mon Sep 17 00:00:00 2001 From: PySimpleGUI Date: Thu, 23 Jul 2020 17:26:15 -0400 Subject: [PATCH 2/2] ProgressBar - can use new color format, combined update_bar with update, search option for theme_preview, theme button in main --- PySimpleGUI.py | 83 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 04ab2c44..5748d828 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1,5 +1,5 @@ #!/usr/bin/python3 -version = __version__ = "4.26.0.2 Unreleased\nNew Sponsor button, highly experimental read_all_windows()" +version = __version__ = "4.26.0.3 Unreleased\nNew Sponsor button, highly experimental read_all_windows(), search option for theme previewer, theme button in main, progress bar color can use new 'on' format, combined ProgressBar.update_bar with ProgressBar.update so now only update is needed" port = 'PySimpleGUI' @@ -3495,8 +3495,7 @@ class ProgressBar(Element): Progress Bar Element - Displays a colored bar that is shaded as progress of some operation is made """ - def __init__(self, max_value, orientation=None, size=(None, None), auto_size_text=None, bar_color=(None, None), style=None, border_width=None, relief=None, - key=None, k=None, pad=None, visible=True, metadata=None): + def __init__(self, max_value, orientation=None, size=(None, None), auto_size_text=None, bar_color=None, style=None, border_width=None, relief=None, key=None, k=None, pad=None, visible=True, metadata=None): """ :param max_value: max value of progressbar :type max_value: (int) @@ -3506,8 +3505,8 @@ class ProgressBar(Element): :type size: (int, int) :param auto_size_text: Not sure why this is here :type auto_size_text: (bool) - :param bar_color: The 2 colors that make up a progress bar. One is the background, the other is the bar - :type bar_color: Tuple[str, str] + :param bar_color: The 2 colors that make up a progress bar. Easy to remember which is which if you say "ON" between colors. "red" on "green". + :type bar_color: Tuple[str, str] or str :param style: Progress bar style defined as one of these 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' :type style: (str) :param border_width: The amount of pixels that go around the outside of the bar @@ -3531,7 +3530,18 @@ class ProgressBar(Element): self.Cancelled = False self.NotRunning = True self.Orientation = orientation if orientation else DEFAULT_METER_ORIENTATION - self.BarColor = bar_color + + # Progress Bar colors can be a tuple (text, background) or a string with format "bar on background" - examples "red on white" or ("red", "white") + if bar_color is None: + bar_color = DEFAULT_PROGRESS_BAR_COLOR + else: + try: + if isinstance(bar_color,str): + bar_color = bar_color.split(' on ') + except Exception as e: + print('* ProgressBar warning * you messed up with color formatting', e) + + self.BarColor = bar_color # should be a tuple at this point self.BarStyle = style if style else DEFAULT_TTK_THEME self.BorderWidth = border_width if border_width else DEFAULT_PROGRESS_BAR_BORDER_WIDTH self.Relief = relief if relief else DEFAULT_PROGRESS_BAR_RELIEF @@ -3544,6 +3554,7 @@ class ProgressBar(Element): # returns False if update failed def UpdateBar(self, current_count, max=None): """ + DEPRECATED BUT STILL USABLE - has been combined with the normal ProgressBar.update method. Change what the bar shows by changing the current count and optionally the max count :param current_count: sets the current value @@ -3563,21 +3574,42 @@ class ProgressBar(Element): return False return True - def Update(self, visible=None): + + def Update(self, current_count, max=None, visible=None): """ Changes some of the settings for the ProgressBar Element. Must call `Window.Read` or `Window.Finalize` prior + Now has the ability to modify the count so that the update_bar method is not longer needed separately + :param current_count: sets the current value + :type current_count: (int) + :param max: changes the max value + :type max: (int) :param visible: control visibility of element :type visible: (bool) + :return: Returns True if update was OK. False means something wrong with window or it was closed + :rtype: (bool) """ if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow - return + return False + + if self.ParentForm.TKrootDestroyed: + return False if visible is False: self.TKProgressBar.TKProgressBarForReal.pack_forget() elif visible is True: self.TKProgressBar.TKProgressBarForReal.pack(padx=self.pad_used[0], pady=self.pad_used[1]) + self.TKProgressBar.Update(current_count, max=max) + try: + self.ParentForm.TKroot.update() + except: + Window._DecrementOpenCount() + # _my_windows.Decrement() + return False + return True + + set_focus = Element.SetFocus set_tooltip = Element.SetTooltip update = Update @@ -14335,7 +14367,7 @@ def theme_add_new(new_theme_name, new_theme_dict): -def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), location=(None, None)): +def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), search_string=None, location=(None, None)): """ Displays a "Quick Reference Window" showing all of the different Look and Feel settings that are available. They are sorted alphabetically. The legacy color names are mixed in, but otherwise they are sorted into Dark and Light halves @@ -14346,12 +14378,14 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), :type scrollable: bool :param scroll_area_size: Size of the scrollable area (The Column Element used to make scrollable) :type scroll_area_size: (int, int) + :param search_string: If specified then only themes containing this string will be shown + :type search_string: str :param location: Location on the screen to place the window. Defaults to the center like all windows :type location: (int, int) """ # Show a "splash" type message so the user doesn't give up waiting - popup_quick_message('Hang on for a moment, this will take a bit to create....', background_color='red', text_color='#FFFFFF', auto_close=True, non_blocking=True) + popup_quick_message('Hang on for a moment, this will take a bit to create....', keep_on_top=True, background_color='red', text_color='#FFFFFF', auto_close=True, non_blocking=True) web = False @@ -14361,10 +14395,18 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), return [[Text('Text element'), InputText('Input data here', size=(10, 1))], [Button('Ok'), Button('Cancel'), Slider((1, 10), orientation='h', size=(5, 15))]] - layout = [[Text('Here is a complete list of themes', font='Default 18', background_color=win_bg)]] names = list_of_look_and_feel_values() names.sort() + if search_string not in (None, ''): + print(f'Looking for {search_string.lower().replace(" ","")}') + names = [name for name in names if search_string.lower().replace(" ","") in name.lower().replace(" ","")] + + if search_string not in (None, ''): + layout = [[Text('Themes containing "{}"'.format(search_string), font='Default 18', background_color=win_bg)]] + else: + layout = [[Text('List of all themes', font='Default 18', background_color=win_bg)]] + col_layout = [] row = [] @@ -14378,10 +14420,9 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), col_layout += [row] layout += [[Column(col_layout, scrollable=scrollable, size=scroll_area_size, pad=(0,0), background_color=win_bg, key='-COL-')]] - window = Window('Preview of all Look and Feel choices', layout, background_color=win_bg, resizable=True, location=location, finalize=True) + window = Window('Preview of Themes', layout, background_color=win_bg, resizable=True, location=location, keep_on_top=True, finalize=True, modal=True) window['-COL-'].expand(True, True, True) # needed so that col will expand with the window - window.read() - window.close() + window.read(close=True) @@ -15690,7 +15731,7 @@ def PopupGetText(message, title=None, default_text='', password_char='', size=(N :type location: Tuple[int, int] :param image: Image to include at the top of the popup window :type image: (str) or (bytes) - :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 = False + :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 :type modal: bool :return: Text entered or None if window was closed or cancel button clicked :rtype: Union[str, None] @@ -15709,10 +15750,8 @@ def PopupGetText(message, title=None, default_text='', password_char='', size=(N [InputText(default_text=default_text, size=size, key='_INPUT_', password_char=password_char)], [Button('Ok', size=(6, 1), bind_return_key=True), Button('Cancel', size=(6, 1))]] - window = Window(title=title or message, layout=layout, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, background_color=background_color, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, finalize=True) + window = Window(title=title or message, layout=layout, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, background_color=background_color, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, finalize=True, modal=modal) - if modal: - window.make_modal() button, values = window.Read() window.close(); del window @@ -17014,7 +17053,7 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not [graph_elem], ] - tab1 = Tab('Graph', frame6, tooltip='Graph is in here', title_color='red', border_width=0) + tab1 = Tab('Graph', frame6, tooltip='Graph is in here', title_color='red') tab2 = Tab('Multiple/Binary Choice Groups', [[Frame('Multiple Choice Group', frame2, title_color='green', tooltip='Checkboxes, radio buttons, etc'), Frame('Binary Choice Group', frame3, title_color='#FFFFFF', tooltip='Binary Choice'), ]], ) tab3 = Tab('Table and Tree', [[Frame('Structured Data Group', frame5, title_color='red', element_justification='l')]], tooltip='tab 3', title_color='red', ) @@ -17038,13 +17077,14 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not VerLine(os.path.dirname(os.path.abspath(__file__)), 'PySimpleGUI Location',justification='l',size=(30,2)), VerLine(sys.version, 'Python Version', justification='l', size=(40, 2)), - [TabGroup([[tab1, tab2, tab3, tab6, tab4, tab5]], key='_TAB_GROUP_', border_width=0)], + [TabGroup([[tab1, tab2, tab3, tab6, tab4, tab5]], key='_TAB_GROUP_')], [Button('Button'), B('Hide Stuff', metadata='my metadata'), Button('ttk Button', use_ttk_buttons=True, tooltip='This is a TTK Button'), Button('See-through Mode', tooltip='Make the background transparent'), Button('Upgrade PySimpleGUI from GitHub', button_color='white on red', key='-INSTALL-'), B('Popup'), B('Sponsor this effort', button_color='white on dark green', key='-SPONSOR-2'), + B('Themes'), Button('Exit', tooltip='Exit button')], ] @@ -17106,6 +17146,9 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not elif event.startswith('-SPONSOR-'): if webbrowser_available: webbrowser.open_new_tab(r'https://www.paypal.me/psgui') + elif event == 'Themes': + search_string = popup_get_text('Enter a search term or leave blank for all themes', 'Show Available Themes', keep_on_top=True) + theme_previewer(search_string=search_string) i += 1 # _refresh_debugger()