From ef3746cb06a9ee6bc93bc3c163ba961fd1b9c413 Mon Sep 17 00:00:00 2001 From: PySimpleGUI Date: Thu, 6 Jan 2022 11:29:03 -0500 Subject: [PATCH 1/2] set_options - new parm disable_modal_windows provides ability to disable modal setting for all windows including popups --- PySimpleGUI.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 50b9e035..8a840d8e 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1,10 +1,11 @@ #!/usr/bin/python3 -version = __version__ = "4.56.0 Released 5-Jan-2022" +version = __version__ = "4.56.0.1 Uneleased" _change_log = """ Changelog since 4.56.0 released to PyPI on 5-Jan-2022 - + 4.56.0.1 + set_options - added disable_modal_windows option to provide a single call to disable the modal feature globally (including popups) """ __version__ = version.split()[0] # For PEP 396 and PEP 345 @@ -516,6 +517,7 @@ TABLE_SELECT_MODE_BROWSE = tk.BROWSE TABLE_SELECT_MODE_EXTENDED = tk.EXTENDED DEFAULT_TABLE_SELECT_MODE = TABLE_SELECT_MODE_EXTENDED +DEFAULT_MODAL_WINDOWS_ENABLED = True TAB_LOCATION_TOP = 'top' TAB_LOCATION_TOP_LEFT = 'topleft' @@ -3920,6 +3922,7 @@ class Output(Element): The Multiline Element is the superior and recommended method for showing the output of stdout. The Multiline Element has been added to significantly while the Output element has not. + If you choose to use a Multiline element to replace an Output element, be sure an turn on the write_only paramter in the Multline Of course, Output Element continues to operate and be backwards compatible, but you're missing out on features such as routing the cprint output to the element. @@ -10691,6 +10694,10 @@ class Window: if running_mac() and ENABLE_MAC_MODAL_DISABLE_PATCH: return + # if modal windows have been disabled globally + if not DEFAULT_MODAL_WINDOWS_ENABLED: + return + try: self.TKroot.transient() self.TKroot.grab_set() @@ -16617,7 +16624,8 @@ def set_options(icon=None, button_color=None, element_size=(None, None), button_ window_location=(None, None), error_button_color=(None, None), tooltip_time=None, tooltip_font=None, use_ttk_buttons=None, ttk_theme=None, suppress_error_popups=None, suppress_raise_key_errors=None, suppress_key_guessing=None,warn_button_key_duplicates=False, enable_treeview_869_patch=None, enable_mac_notitlebar_patch=None, use_custom_titlebar=None, titlebar_background_color=None, titlebar_text_color=None, titlebar_font=None, - titlebar_icon=None, user_settings_path=None, pysimplegui_settings_path=None, pysimplegui_settings_filename=None, keep_on_top=None, dpi_awareness=None, scaling=None): + titlebar_icon=None, user_settings_path=None, pysimplegui_settings_path=None, pysimplegui_settings_filename=None, keep_on_top=None, dpi_awareness=None, scaling=None, + disable_modal_windows=None): """ :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO. Most portable is to use a Base64 of a PNG file. This works universally across all OS's :type icon: bytes | str @@ -16724,7 +16732,9 @@ def set_options(icon=None, button_color=None, element_size=(None, None), button_ :param dpi_awareness: If True then will turn on DPI awareness (Windows only at the moment) :type dpi_awareness: (bool) :param scaling: Sets the default scaling for all windows including popups, etc. - :type scaling: (float) + :type scaling: (float) + :param disable_modal_windows: If True then all windows, including popups, will not be modal windows + :type disable_modal_windows: (bool) :return: None :rtype: None """ @@ -16780,6 +16790,7 @@ def set_options(icon=None, button_color=None, element_size=(None, None), button_ global DEFAULT_USER_SETTINGS_PYSIMPLEGUI_FILENAME global DEFAULT_KEEP_ON_TOP global DEFAULT_SCALING + global DEFAULT_MODAL_WINDOWS_ENABLED global _pysimplegui_user_settings # global _my_windows @@ -16955,6 +16966,10 @@ def set_options(icon=None, button_color=None, element_size=(None, None), button_ if scaling is not None: DEFAULT_SCALING = scaling + if disable_modal_windows is not None: + DEFAULT_MODAL_WINDOWS_ENABLED = not disable_modal_windows + + return True From f523e511d934bdd3685fa45aaaa9dbb49d17d961 Mon Sep 17 00:00:00 2001 From: PySimpleGUI Date: Thu, 6 Jan 2022 11:31:54 -0500 Subject: [PATCH 2/2] Swapped out Output element for Multiline. Includes the Titilebar, CustomMenubar, Sizegrip and standard "Edit Me" and "Versions" right click setting and numerous smaller changes --- DemoPrograms/Demo_All_Elements.py | 66 ++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/DemoPrograms/Demo_All_Elements.py b/DemoPrograms/Demo_All_Elements.py index a85328e0..c9e8885b 100644 --- a/DemoPrograms/Demo_All_Elements.py +++ b/DemoPrograms/Demo_All_Elements.py @@ -20,13 +20,16 @@ def make_window(theme): sg.theme(theme) menu_def = [['&Application', ['E&xit']], ['&Help', ['&About']] ] - right_click_menu_def = [[], ['Nothing','More Nothing','Exit']] + right_click_menu_def = [[], ['Edit Me', 'Versions', 'Nothing','More Nothing','Exit']] + graph_right_click_menu_def = [[], ['Erase','Draw Line', 'Draw',['Circle', 'Rectangle', 'Image'], 'Exit']] # Table Data data = [["John", 10], ["Jen", 5]] headings = ["Name", "Score"] - input_layout = [[sg.Menu(menu_def, key='-MENU-')], + input_layout = [ + + # [sg.Menu(menu_def, key='-MENU-')], [sg.Text('Anything that requires user-input is in this tab!')], [sg.Input(key='-INPUT-')], [sg.Slider(orientation='h', key='-SKIDER-'), @@ -36,17 +39,22 @@ def make_window(theme): [sg.Combo(values=('Combo 1', 'Combo 2', 'Combo 3'), default_value='Combo 1', readonly=True, k='-COMBO-'), sg.OptionMenu(values=('Option 1', 'Option 2', 'Option 3'), k='-OPTION MENU-'),], [sg.Spin([i for i in range(1,11)], initial_value=10, k='-SPIN-'), sg.Text('Spin')], - [sg.Multiline('Demo of a Multi-Line Text Element!\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nYou get the point.', size=(45,5), k='-MLINE-')], + [sg.Multiline('Demo of a Multi-Line Text Element!\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nYou get the point.', size=(45,5), expand_x=True, expand_y=True, k='-MLINE-')], [sg.Button('Button'), sg.Button('Popup'), sg.Button(image_data=sg.DEFAULT_BASE64_ICON, key='-LOGO-')]] asthetic_layout = [[sg.T('Anything that you would use for asthetics is in this tab!')], [sg.Image(data=sg.DEFAULT_BASE64_ICON, k='-IMAGE-')], - [sg.ProgressBar(1000, orientation='h', size=(20, 20), key='-PROGRESS BAR-'), sg.Button('Test Progress bar')]] + [sg.ProgressBar(100, orientation='h', size=(20, 20), key='-PROGRESS BAR-'), sg.Button('Test Progress bar')]] - logging_layout = [[sg.Text("Anything printed will display here!")], [sg.Output(size=(60,15), font='Courier 8')]] + logging_layout = [[sg.Text("Anything printed will display here!")], + [sg.Multiline(size=(60,15), font='Courier 8', expand_x=True, expand_y=True, write_only=True, + reroute_stdout=True, reroute_stderr=True, echo_stdout_stderr=True, autoscroll=True, auto_refresh=True)] + # [sg.Output(size=(60,15), font='Courier 8', expand_x=True, expand_y=True)] + ] graphing_layout = [[sg.Text("Anything you would use to graph will display here!")], - [sg.Graph((200,200), (0,0),(200,200),background_color="black", key='-GRAPH-', enable_events=True)], + [sg.Graph((200,200), (0,0),(200,200),background_color="black", key='-GRAPH-', enable_events=True, + right_click_menu=graph_right_click_menu_def)], [sg.T('Click anywhere on graph to draw a circle')], [sg.Table(values=data, headings=headings, max_col_width=25, background_color='black', @@ -58,9 +66,9 @@ def make_window(theme): key='-TABLE-', row_height=25)]] - specalty_layout = [[sg.Text("Any \"special\" elements will display here!")], - [sg.Button("Open Folder")], - [sg.Button("Open File")]] + popup_layout = [[sg.Text("Popup Testing")], + [sg.Button("Open Folder")], + [sg.Button("Open File")]] theme_layout = [[sg.Text("See how elements look under different themes by choosing a different theme here!")], [sg.Listbox(values = sg.theme_list(), @@ -69,16 +77,22 @@ def make_window(theme): enable_events = True)], [sg.Button("Set Theme")]] - layout = [[sg.Text('Demo Of (Almost) All Elements', size=(38, 1), justification='center', font=("Helvetica", 16), relief=sg.RELIEF_RIDGE, k='-TEXT HEADING-', enable_events=True)]] + layout = [ [sg.MenubarCustom(menu_def, key='-MENU-', font='Courier 15', tearoff=True)], + [sg.Text('Demo Of (Almost) All Elements', size=(38, 1), justification='center', font=("Helvetica", 16), relief=sg.RELIEF_RIDGE, k='-TEXT HEADING-', enable_events=True)]] layout +=[[sg.TabGroup([[ sg.Tab('Input Elements', input_layout), sg.Tab('Asthetic Elements', asthetic_layout), sg.Tab('Graphing', graphing_layout), - sg.Tab('Specialty', specalty_layout), + sg.Tab('Popups', popup_layout), sg.Tab('Theming', theme_layout), - sg.Tab('Output', logging_layout)]], key='-TAB GROUP-')]] - - return sg.Window('All Elements Demo', layout, right_click_menu=right_click_menu_def) + sg.Tab('Output', logging_layout)]], key='-TAB GROUP-', expand_x=True, expand_y=True), + ]] + layout[-1].append(sg.Sizegrip()) + window = sg.Window('All Elements Demo', layout, right_click_menu=right_click_menu_def, right_click_menu_tearoff=True, grab_anywhere=True, resizable=True, margins=(0,0), use_custom_titlebar=True, finalize=True, keep_on_top=True, + # scaling=2.0, + ) + window.set_min_size(window.size) + return window def main(): window = make_window(sg.theme()) @@ -102,17 +116,17 @@ def main(): 'Right click anywhere to see right click menu', 'Visit each of the tabs to see available elements', 'Output of event and values can be see in Output tab', - 'The event and values dictionary is printed after every event') + 'The event and values dictionary is printed after every event', keep_on_top=True) elif event == 'Popup': print("[LOG] Clicked Popup Button!") - sg.popup("You pressed a button!") + sg.popup("You pressed a button!", keep_on_top=True) print("[LOG] Dismissing Popup!") elif event == 'Test Progress bar': print("[LOG] Clicked Test Progress Bar!") progress_bar = window['-PROGRESS BAR-'] - for i in range(1000): + for i in range(100): print("[LOG] Updating progress bar by 1 step ("+str(i)+")") - progress_bar.UpdateBar(i + 1) + progress_bar.update(current_count=i + 1) print("[LOG] Progress bar complete!") elif event == "-GRAPH-": graph = window['-GRAPH-'] # type: sg.Graph @@ -120,13 +134,13 @@ def main(): print("[LOG] Circle drawn at: " + str(values['-GRAPH-'])) elif event == "Open Folder": print("[LOG] Clicked Open Folder!") - folder_or_file = sg.popup_get_folder('Choose your folder') - sg.popup("You chose: " + str(folder_or_file)) + folder_or_file = sg.popup_get_folder('Choose your folder', keep_on_top=True) + sg.popup("You chose: " + str(folder_or_file), keep_on_top=True) print("[LOG] User chose folder: " + str(folder_or_file)) elif event == "Open File": print("[LOG] Clicked Open File!") - folder_or_file = sg.popup_get_file('Choose your file') - sg.popup("You chose: " + str(folder_or_file)) + folder_or_file = sg.popup_get_file('Choose your file', keep_on_top=True) + sg.popup("You chose: " + str(folder_or_file), keep_on_top=True) print("[LOG] User chose file: " + str(folder_or_file)) elif event == "Set Theme": print("[LOG] Clicked Set Theme!") @@ -134,9 +148,17 @@ def main(): print("[LOG] User Chose Theme: " + str(theme_chosen)) window.close() window = make_window(theme_chosen) + elif event == 'Edit Me': + sg.execute_editor(__file__) + elif event == 'Versions': + sg.popup(sg.get_versions(), keep_on_top=True) window.close() exit(0) if __name__ == '__main__': + sg.theme('black') + sg.theme('dark red') + sg.theme('dark green 7') + # sg.theme('DefaultNoMoreNagging') main() \ No newline at end of file