From a1f4c60271a8344fbb052b9c507c0f03e91b9464 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Mon, 24 Sep 2018 18:01:00 -0400 Subject: [PATCH] Major demo refresh.. switched everything to new function names, new design patterns Out with the old, in with the new!! --- Demo_All_Widgets.py | 9 +- Demo_Borderless_Window.py | 16 +- Demo_Button_Click.py | 18 +- Demo_Button_States.py | 78 +- Demo_Calendar.py | 4 +- Demo_Canvas.py | 12 +- Demo_Chat.py | 21 +- Demo_Chat_With_History.py | 31 +- Demo_Chatterbot.py | 21 +- Demo_Color.py | 20 +- Demo_Color_Names.py | 107 +++ Demo_Columns.py | 69 +- Demo_Compare_Files.py | 20 +- Demo_Cookbook_Browser.py | 793 ------------------ Demo_DOC_Viewer_PIL.py | 14 +- Demo_Desktop_Floating_Toolbar.py | 20 +- Demo_Desktop_Widget_CPU_Graph.py | 9 +- Demo_Desktop_Widget_CPU_Utilization.py | 16 +- Demo_Desktop_Widget_CPU_Utilization_Simple.py | 11 +- Demo_Desktop_Widget_Timer.py | 27 +- Demo_Disable_Elements.py | 57 +- Demo_DisplayHash1and256.py | 124 --- Demo_Fill_Form.py | 18 +- Demo_Font_Sizer.py | 12 +- Demo_Func_Callback_Simulation.py | 4 +- Demo_GoodColors.py | 54 +- Demo_Graph_Drawing.py | 8 +- Demo_Graph_Element.py | 17 +- Demo_Graph_Element_Sine_Wave.py | 6 +- Demo_Graph_Noise.py | 29 +- Demo_HowDoI.py | 34 +- Demo_Img_Viewer.py | 8 +- Demo_Keyboard.py | 32 +- Demo_Keyboard_Realtime.py | 31 +- Demo_Keypad.py | 28 +- Demo_MIDI_Player.py | 32 +- Demo_Machine_Learning.py | 22 +- Demo_Matplotlib.py | 6 +- Demo_Matplotlib_Animated.py | 16 +- Demo_Matplotlib_Animated_Scatter.py | 12 +- Demo_Matplotlib_Browser.py | 18 +- Demo_Matplotlib_Ping_Graph.py | 10 +- Demo_Matplotlib_Ping_Graph_Large.py | 12 +- Demo_Media_Player.py | 22 +- Demo_Menus.py | 11 +- Demo_NonBlocking_Form.py | 58 +- Demo_OpenCV.py | 23 +- Demo_PDF_Viewer.py | 21 +- Demo_PNG_Viewer.py | 24 +- Demo_Password_Login.py | 12 +- Demo_Pi_LEDs.py | 20 +- Demo_Pi_Robotics.py | 33 +- Demo_Ping_Line_Graph.py | 12 +- Demo_Pong.py | 12 +- Demo_Progress_Meters.py | 12 +- Demo_Recipes.py | 237 ------ Demo_Script_Launcher.py | 10 +- Demo_Script_Parameters.py | 2 +- Demo_Spinner_Compound_Element.py | 11 +- Demo_Super_Simple_Form.py | 10 +- Demo_Tabbed_Form.py | 4 +- Demo_Table_CSV.py | 20 +- Demo_Table_Element.py | 12 +- Demo_Table_Pandas.py | 11 +- Demo_Table_Simulation.py | 16 +- Demo_Tabs.py | 26 +- Demo_Tabs_Nested.py | 29 + Demo_Youtube-dl_Frontend.py | 15 +- 68 files changed, 706 insertions(+), 1863 deletions(-) create mode 100644 Demo_Color_Names.py delete mode 100644 Demo_Cookbook_Browser.py delete mode 100644 Demo_DisplayHash1and256.py delete mode 100644 Demo_Recipes.py create mode 100644 Demo_Tabs_Nested.py diff --git a/Demo_All_Widgets.py b/Demo_All_Widgets.py index bf81163d..6a176c8a 100644 --- a/Demo_All_Widgets.py +++ b/Demo_All_Widgets.py @@ -38,15 +38,14 @@ layout = [ [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Default Folder'), sg.FolderBrowse()], [sg.Submit(tooltip='Click to submit this form'), sg.Cancel()] -] + ] +window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout) -form = sg.FlexForm('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout) - -button, values = form.Read() +button, values = window.Read() sg.Popup('Title', - 'The results of the form.', + 'The results of the window.', 'The button clicked was "{}"'.format(button), 'The values are', values) diff --git a/Demo_Borderless_Window.py b/Demo_Borderless_Window.py index 1d615059..8e28a2c4 100644 --- a/Demo_Borderless_Window.py +++ b/Demo_Borderless_Window.py @@ -11,20 +11,20 @@ layout = [[sg.T('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User [sg.T('Customer:', pad=((3, 0), 0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20, 1)), sg.T('1', size=(8, 1))], [sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black')], - [sg.ReadFormButton('Start', button_color=('white', 'black')), - sg.ReadFormButton('Stop', button_color=('gray50', 'black')), - sg.ReadFormButton('Reset', button_color=('white', '#9B0023')), - sg.ReadFormButton('Submit', button_color=('gray60', 'springgreen4')), - sg.SimpleButton('Exit', button_color=('white', '#00406B'))]] + [sg.ReadButton('Start', button_color=('white', 'black')), + sg.ReadButton('Stop', button_color=('gray50', 'black')), + sg.ReadButton('Reset', button_color=('white', '#9B0023')), + sg.ReadButton('Submit', button_color=('gray60', 'springgreen4')), + sg.Button('Exit', button_color=('white', '#00406B'))]] -form = sg.FlexForm("Time Tracker", default_element_size=(12, 1), text_justification='r', auto_size_text=False, +window = sg.Window("Time Tracker", default_element_size=(12, 1), text_justification='r', auto_size_text=False, auto_size_buttons=False, no_titlebar=True, default_button_element_size=(12, 1)) -form.Layout(layout) +window.Layout(layout) while True: - button, values = form.Read() + button, values = window.Read() if button is None or button == 'Exit': break diff --git a/Demo_Button_Click.py b/Demo_Button_Click.py index 2dfa029c..2735e0fa 100644 --- a/Demo_Button_Click.py +++ b/Demo_Button_Click.py @@ -1,24 +1,24 @@ import PySimpleGUI as sg import winsound - +import sys sg.ChangeLookAndFeel('Dark') sg.SetOptions(element_padding=(0,0)) layout = [ - [sg.ReadFormButton('Start', button_color=('white', 'black'), key='start'), - sg.ReadFormButton('Stop', button_color=('white', 'black'), key='stop'), - sg.ReadFormButton('Reset', button_color=('white', 'firebrick3'), key='reset'), - sg.ReadFormButton('Submit', button_color=('white', 'springgreen4'), key='submit')] + [sg.ReadButton('Start', button_color=('white', 'black'), key='start'), + sg.ReadButton('Stop', button_color=('white', 'black'), key='stop'), + sg.ReadButton('Reset', button_color=('white', 'firebrick3'), key='reset'), + sg.ReadButton('Submit', button_color=('white', 'springgreen4'), key='submit')] ] -form = sg.FlexForm("Button Click", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False, default_button_element_size=(12,1)).Layout(layout).Finalize() +window = sg.Window("Button Click", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False, default_button_element_size=(12,1), use_default_focus=False).Layout(layout).Finalize() -form.FindElement('submit').Update(disabled=True) +window.FindElement('submit').Update(disabled=True) recording = have_data = False while True: - button, values = form.Read() + button, values = window.Read() if button is None: - exit(69) + sys.exit(69) winsound.PlaySound("ButtonClick.wav", 1) diff --git a/Demo_Button_States.py b/Demo_Button_States.py index e3a9cfb7..3871760e 100644 --- a/Demo_Button_States.py +++ b/Demo_Button_States.py @@ -1,31 +1,57 @@ import PySimpleGUI as sg +import sys +""" +Demonstrates using a "tight" layout with a Dark theme. +Shows how button states can be controlled by a user application. The program manages the disabled/enabled +states for buttons and changes the text color to show greyed-out (disabled) buttons +""" -sg.ChangeLookAndFeel('LightGreen') -sg.SetOptions(element_padding=(0, 0)) +sg.ChangeLookAndFeel('Dark') +sg.SetOptions(element_padding=(0,0)) -# ------ Menu Definition ------ # -menu_def = [['File', ['Open', 'Save', 'Exit' ]], - ['Edit', ['Paste', ['Special', 'Normal', ], 'Undo'], ], - ['Help', 'About...'], ] +layout = [[sg.T('User:', pad=((3,0),0)), sg.OptionMenu(values = ('User 1', 'User 2'), size=(20,1)), sg.T('0', size=(8,1))], + [sg.T('Customer:', pad=((3,0),0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20,1)), sg.T('1', size=(8,1))], + [sg.T('Notes:', pad=((3,0),0)), sg.In(size=(44,1), background_color='white', text_color='black')], + [sg.ReadButton('Start', button_color=('white', 'black'), key='Start'), + sg.ReadButton('Stop', button_color=('white', 'black'), key='Stop'), + sg.ReadButton('Reset', button_color=('white', 'firebrick3'), key='Reset'), + sg.ReadButton('Submit', button_color=('white', 'springgreen4'), key='Submit')] + ] -# ------ GUI Defintion ------ # -layout = [ - [sg.Menu(menu_def)], - [sg.Output(size=(60, 20))] -] - -form = sg.FlexForm("Windows-like program", default_element_size=(12, 1), auto_size_text=False, auto_size_buttons=False, - default_button_element_size=(12, 1)).Layout(layout) - -# ------ Loop & Process button menu choices ------ # +window = sg.Window("Time Tracker", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False, + default_button_element_size=(12,1)).Layout(layout) +window.Finalize() +window.FindElement('Stop').Update(disabled=True) +window.FindElement('Reset').Update(disabled=True) +window.FindElement('Submit').Update(disabled=True) +recording = have_data = False while True: - button, values = form.Read() - if button == None or button == 'Exit': - break - print('Button = ', button) - # ------ Process menu choices ------ # - if button == 'About...': - sg.Popup('About this program', 'Version 1.0', 'PySimpleGUI rocks...') - elif button == 'Open': - filename = sg.PopupGetFile('file to open', no_window=True) - print(filename) \ No newline at end of file + button, values = window.Read() + print(button) + if button is None: + sys.exit(69) + if button is 'Start': + window.FindElement('Start').Update(disabled=True) + window.FindElement('Stop').Update(disabled=False) + window.FindElement('Reset').Update(disabled=False) + window.FindElement('Submit').Update(disabled=True) + recording = True + elif button is 'Stop' and recording: + window.FindElement('Stop').Update(disabled=True) + window.FindElement('Start').Update(disabled=False) + window.FindElement('Submit').Update(disabled=False) + recording = False + have_data = True + elif button is 'Reset': + window.FindElement('Stop').Update(disabled=True) + window.FindElement('Start').Update(disabled=False) + window.FindElement('Submit').Update(disabled=True) + window.FindElement('Reset').Update(disabled=False) + recording = False + have_data = False + elif button is 'Submit' and have_data: + window.FindElement('Stop').Update(disabled=True) + window.FindElement('Start').Update(disabled=False) + window.FindElement('Submit').Update(disabled=True) + window.FindElement('Reset').Update(disabled=False) + recording = False diff --git a/Demo_Calendar.py b/Demo_Calendar.py index 2ecc18f6..b04376c3 100644 --- a/Demo_Calendar.py +++ b/Demo_Calendar.py @@ -5,6 +5,6 @@ layout = [[sg.T('Calendar Test')], [sg.CalendarButton('Choose Date', target='input', key='date')], [sg.Ok(key=1)]] -form = sg.FlexForm('Calendar', grab_anywhere=False) -b,v = form.LayoutAndRead(layout) +window = sg.Window('Calendar', grab_anywhere=False).Layout(layout) +b,v = window.Read() sg.Popup(v['input']) diff --git a/Demo_Canvas.py b/Demo_Canvas.py index cbe01caa..01e1952d 100644 --- a/Demo_Canvas.py +++ b/Demo_Canvas.py @@ -3,18 +3,18 @@ import PySimpleGUI as sg layout = [ [sg.Canvas(size=(150, 150), background_color='red', key='canvas')], - [sg.T('Change circle color to:'), sg.ReadFormButton('Red'), sg.ReadFormButton('Blue')] + [sg.T('Change circle color to:'), sg.ReadButton('Red'), sg.ReadButton('Blue')] ] -form = sg.FlexForm('Canvas test').Layout(layout).Finalize() +window = sg.Window('Canvas test').Layout(layout).Finalize() -cir = form.FindElement('canvas').TKCanvas.create_oval(50, 50, 100, 100) +cir = window.FindElement('canvas').TKCanvas.create_oval(50, 50, 100, 100) while True: - button, values = form.Read() + button, values = window.Read() if button is None: break if button is 'Blue': - form.FindElement('canvas').TKCanvas.itemconfig(cir, fill = "Blue") + window.FindElement('canvas').TKCanvas.itemconfig(cir, fill = "Blue") elif button is 'Red': - form.FindElement('canvas').TKCanvas.itemconfig(cir, fill = "Red") + window.FindElement('canvas').TKCanvas.itemconfig(cir, fill = "Red") diff --git a/Demo_Chat.py b/Demo_Chat.py index db2b610a..09f16fd6 100644 --- a/Demo_Chat.py +++ b/Demo_Chat.py @@ -1,31 +1,28 @@ import PySimpleGUI as sg +import sys ''' A chat window. Add call to your send-routine, print the response and you're done ''' -# ------- Make a new FlexForm ------- # -sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors +sg.ChangeLookAndFeel('GreenTan') # give our window a spiffy set of colors -form = sg.FlexForm('Chat window', default_element_size=(30, 2), font=('Helvetica',' 13'), default_button_element_size=(8,2)) - -layout = [ - [sg.Text('Your output will go here', size=(40, 1))], +layout = [[sg.Text('Your output will go here', size=(40, 1))], [sg.Output(size=(127, 30), font=('Helvetica 10'))], [sg.Multiline(size=(85, 5), enter_submits=True, key='query'), - sg.ReadFormButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), - sg.SimpleButton('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))] - ] -form.Layout(layout) + sg.ReadButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), + sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]] + +window = sg.Window('Chat window', default_element_size=(30, 2), font=('Helvetica',' 13'), default_button_element_size=(8,2)).Layout(layout) # ---===--- Loop taking in user input and using it --- # while True: - (button, value) = form.Read() + (button, value) = window.Read() if button is 'SEND': query = value['query'].rstrip() # EXECUTE YOUR COMMAND HERE print('The command you entered was {}'.format(query)) elif button is None or button is 'EXIT': # quit if exit button or X break -exit(69) +sys.exit(69) diff --git a/Demo_Chat_With_History.py b/Demo_Chat_With_History.py index 3b80ea7c..5eda2b42 100644 --- a/Demo_Chat_With_History.py +++ b/Demo_Chat_With_History.py @@ -1,5 +1,5 @@ import PySimpleGUI as sg - +import sys ''' A chatbot with history Scroll up and down through prior commands using the arrow keys @@ -11,48 +11,45 @@ Special keyboard keys: ''' def ChatBotWithHistory(): - # ------- Make a new FlexForm ------- # + # ------- Make a new Window ------- # sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors - form = sg.FlexForm('Chat window with history', default_element_size=(30, 2), font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True) - - layout = [ - [sg.Text('Your output will go here', size=(40, 1))], + layout = [[sg.Text('Your output will go here', size=(40, 1))], [sg.Output(size=(127, 30), font=('Helvetica 10'))], [sg.T('Command History'), sg.T('', size=(20,3), key='history')], [sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False), - sg.ReadFormButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), - sg.SimpleButton('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))] - ] - form.Layout(layout) + sg.ReadButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), + sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]] + + window = sg.Window('Chat window with history', default_element_size=(30, 2), font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True).Layout(layout) # ---===--- Loop taking in user input and using it --- # command_history = [] history_offset = 0 while True: - (button, value) = form.Read() + (button, value) = window.Read() if button is 'SEND': query = value['query'].rstrip() # EXECUTE YOUR COMMAND HERE print('The command you entered was {}'.format(query)) command_history.append(query) history_offset = len(command_history)-1 - form.FindElement('query').Update('') # manually clear input because keyboard events blocks clear - form.FindElement('history').Update('\n'.join(command_history[-3:])) + window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear + window.FindElement('history').Update('\n'.join(command_history[-3:])) elif button is None or button is 'EXIT': # quit if exit button or X break elif 'Up' in button and len(command_history): command = command_history[history_offset] history_offset -= 1 * (history_offset > 0) # decrement is not zero - form.FindElement('query').Update(command) + window.FindElement('query').Update(command) elif 'Down' in button and len(command_history): history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list command = command_history[history_offset] - form.FindElement('query').Update(command) + window.FindElement('query').Update(command) elif 'Escape' in button: - form.FindElement('query').Update('') + window.FindElement('query').Update('') - exit(69) + sys.exit(69) ChatBotWithHistory() diff --git a/Demo_Chatterbot.py b/Demo_Chatterbot.py index 12832a46..dec613c5 100644 --- a/Demo_Chatterbot.py +++ b/Demo_Chatterbot.py @@ -1,6 +1,7 @@ import PySimpleGUI as sg from chatterbot import ChatBot import chatterbot.utils +import sys ''' Demo_Chatterbot.py @@ -22,7 +23,7 @@ for i in range(MAX_PROG_BARS): texts.append(sg.T(' ' * 20, size=(20, 1), justification='right')) training_layout += [[texts[i], bars[i]],] # add a single row -training_form = sg.FlexForm('Training').Layout(training_layout) +training_window = sg.Window('Training').Layout(training_layout) current_bar = 0 # callback function for training runs @@ -30,13 +31,13 @@ def print_progress_bar(description, iteration_counter, total_items, progress_bar global current_bar global bars global texts - global training_form - # update the form and the bars - button, values = training_form.ReadNonBlocking() - if button is None and values is None: # if user closed the form on us, exit - exit(69) + global training_window + # update the window and the bars + button, values = training_window.ReadNonBlocking() + if button is None and values is None: # if user closed the window on us, exit + sys.exit(69) if bars[current_bar].UpdateBar(iteration_counter, max=total_items) is False: - exit(69) + sys.exit(69) texts[current_bar].Update(description) # show the training dataset name if iteration_counter == total_items: current_bar += 1 @@ -53,13 +54,13 @@ chatbot.train("chatterbot.corpus.english") layout = [[sg.Output(size=(80, 20))], [sg.Multiline(size=(70, 5), enter_submits=True), - sg.ReadFormButton('SEND', bind_return_key=True), sg.ReadFormButton('EXIT')]] + sg.ReadButton('SEND', bind_return_key=True), sg.ReadButton('EXIT')]] -form = sg.FlexForm('Chat Window', auto_size_text=True, default_element_size=(30, 2)).Layout(layout) +window = sg.Window('Chat Window', auto_size_text=True, default_element_size=(30, 2)).Layout(layout) # ---===--- Loop taking in user input and using it to query HowDoI web oracle --- # while True: - button, (value,) = form.Read() + button, (value,) = window.Read() if button is not 'SEND': break string = value.rstrip() diff --git a/Demo_Color.py b/Demo_Color.py index e826ce88..ca245716 100644 --- a/Demo_Color.py +++ b/Demo_Color.py @@ -1639,7 +1639,7 @@ def show_all_colors_on_buttons(): global reverse global colorhex global colors - form = sg.FlexForm('Colors on Buttons Demo', default_element_size=(3, 1), location=(0, 0), icon=MY_WINDOW_ICON, font=("Helvetica", 7)) + window = sg.Window('Colors on Buttons Demo', default_element_size=(3, 1), location=(0, 0), icon=MY_WINDOW_ICON, font=("Helvetica", 7)) row = [] row_len = 20 for i, c in enumerate(colors): @@ -1649,11 +1649,11 @@ def show_all_colors_on_buttons(): row.append(button1) row.append(button2) if (i+1) % row_len == 0: - form.AddRow(*row) + window.AddRow(*row) row = [] if row != []: - form.AddRow(*row) - form.Show() + window.AddRow(*row) + window.Show() GoodColors = [('#0e6251', sg.RGB(255, 246, 122)), @@ -1680,16 +1680,16 @@ def main(): [sg.Text('Demonstration of colors')], [sg.Text('Enter a color name in text or hex #RRGGBB format')], [sg.InputText(key='hex')], - [sg.Listbox(list_of_colors, size=(20, 30), key='listbox'), sg.T('Or choose from list')], - [sg.Submit(), sg.SimpleButton('Many buttons', button_color=('white', '#0e6251')), sg.ColorChooserButton( 'Chooser', target=(3,0)), sg.Quit(),], + [sg.Listbox(list_of_colors, size=(20, 30), bind_return_key=True, key='listbox'), sg.T('Or choose from list')], + [sg.Submit(), sg.Button('Many buttons', button_color=('white', '#0e6251'), key='Many buttons'), sg.ColorChooserButton( 'Chooser', target=(3,0), key='Chooser'), sg.Quit(),], ] # [g.Multiline(DefaultText=str(printable), Size=(30,20))]] - button, values = sg.FlexForm('Color Demo', auto_size_buttons=False).LayoutAndRead(layout) + button, values = sg.Window('Color Demo', auto_size_buttons=False).Layout(layout).Read() # ------- OUTPUT results portion ------- # - if button == '' or button == 'Quit' or button is None: + if button == 'Quit' or button is None: exit(0) - elif button == 'Show me lots of colors!': + elif button == 'Many buttons': show_all_colors_on_buttons() drop_down_value = values['listbox'] @@ -1711,7 +1711,7 @@ def main(): [sg.Button(button_text=color_name, button_color=(color_hex, complementary_hex))], [sg.Button(button_text=complementary_hex + ' ' + complementary_color, button_color=(complementary_hex , color_hex), size=(30, 1))], ] - sg.FlexForm('Color demo', default_element_size=(100, 1), auto_size_text=True, auto_close=True, auto_close_duration=5, icon=MY_WINDOW_ICON).LayoutAndRead(layout) + sg.Window('Color demo', default_element_size=(100, 1), auto_size_text=True, auto_close=True, auto_close_duration=5, icon=MY_WINDOW_ICON).Layout(layout).Read() diff --git a/Demo_Color_Names.py b/Demo_Color_Names.py new file mode 100644 index 00000000..359bf8b8 --- /dev/null +++ b/Demo_Color_Names.py @@ -0,0 +1,107 @@ +import PySimpleGUI as sg +""" + Color names courtesy of Big Daddy's Wiki-Python + http://www.wikipython.com/tkinter-ttk-tix/summary-information/colors/ + + Shows a big chart of colors... give it a few seconds to create it + Once large window is shown, you can click on any color and another window will popup + showing both white and black text on that color +""" +COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace', + 'linen', 'antique white', 'papaya whip', 'blanched almond', 'bisque', 'peach puff', + 'navajo white', 'lemon chiffon', 'mint cream', 'azure', 'alice blue', 'lavender', + 'lavender blush', 'misty rose', 'dark slate gray', 'dim gray', 'slate gray', + 'light slate gray', 'gray', 'light gray', 'midnight blue', 'navy', 'cornflower blue', 'dark slate blue', + 'slate blue', 'medium slate blue', 'light slate blue', 'medium blue', 'royal blue', 'blue', + 'dodger blue', 'deep sky blue', 'sky blue', 'light sky blue', 'steel blue', 'light steel blue', + 'light blue', 'powder blue', 'pale turquoise', 'dark turquoise', 'medium turquoise', 'turquoise', + 'cyan', 'light cyan', 'cadet blue', 'medium aquamarine', 'aquamarine', 'dark green', 'dark olive green', + 'dark sea green', 'sea green', 'medium sea green', 'light sea green', 'pale green', 'spring green', + 'lawn green', 'medium spring green', 'green yellow', 'lime green', 'yellow green', + 'forest green', 'olive drab', 'dark khaki', 'khaki', 'pale goldenrod', 'light goldenrod yellow', + 'light yellow', 'yellow', 'gold', 'light goldenrod', 'goldenrod', 'dark goldenrod', 'rosy brown', + 'indian red', 'saddle brown', 'sandy brown', + 'dark salmon', 'salmon', 'light salmon', 'orange', 'dark orange', + 'coral', 'light coral', 'tomato', 'orange red', 'red', 'hot pink', 'deep pink', 'pink', 'light pink', + 'pale violet red', 'maroon', 'medium violet red', 'violet red', + 'medium orchid', 'dark orchid', 'dark violet', 'blue violet', 'purple', 'medium purple', + 'thistle', 'snow2', 'snow3', + 'snow4', 'seashell2', 'seashell3', 'seashell4', 'AntiqueWhite1', 'AntiqueWhite2', + 'AntiqueWhite3', 'AntiqueWhite4', 'bisque2', 'bisque3', 'bisque4', 'PeachPuff2', + 'PeachPuff3', 'PeachPuff4', 'NavajoWhite2', 'NavajoWhite3', 'NavajoWhite4', + 'LemonChiffon2', 'LemonChiffon3', 'LemonChiffon4', 'cornsilk2', 'cornsilk3', + 'cornsilk4', 'ivory2', 'ivory3', 'ivory4', 'honeydew2', 'honeydew3', 'honeydew4', + 'LavenderBlush2', 'LavenderBlush3', 'LavenderBlush4', 'MistyRose2', 'MistyRose3', + 'MistyRose4', 'azure2', 'azure3', 'azure4', 'SlateBlue1', 'SlateBlue2', 'SlateBlue3', + 'SlateBlue4', 'RoyalBlue1', 'RoyalBlue2', 'RoyalBlue3', 'RoyalBlue4', 'blue2', 'blue4', + 'DodgerBlue2', 'DodgerBlue3', 'DodgerBlue4', 'SteelBlue1', 'SteelBlue2', + 'SteelBlue3', 'SteelBlue4', 'DeepSkyBlue2', 'DeepSkyBlue3', 'DeepSkyBlue4', + 'SkyBlue1', 'SkyBlue2', 'SkyBlue3', 'SkyBlue4', 'LightSkyBlue1', 'LightSkyBlue2', + 'LightSkyBlue3', 'LightSkyBlue4', 'Slategray1', 'Slategray2', 'Slategray3', + 'Slategray4', 'LightSteelBlue1', 'LightSteelBlue2', 'LightSteelBlue3', + 'LightSteelBlue4', 'LightBlue1', 'LightBlue2', 'LightBlue3', 'LightBlue4', + 'LightCyan2', 'LightCyan3', 'LightCyan4', 'PaleTurquoise1', 'PaleTurquoise2', + 'PaleTurquoise3', 'PaleTurquoise4', 'CadetBlue1', 'CadetBlue2', 'CadetBlue3', + 'CadetBlue4', 'turquoise1', 'turquoise2', 'turquoise3', 'turquoise4', 'cyan2', 'cyan3', + 'cyan4', 'DarkSlategray1', 'DarkSlategray2', 'DarkSlategray3', 'DarkSlategray4', + 'aquamarine2', 'aquamarine4', 'DarkSeaGreen1', 'DarkSeaGreen2', 'DarkSeaGreen3', + 'DarkSeaGreen4', 'SeaGreen1', 'SeaGreen2', 'SeaGreen3', 'PaleGreen1', 'PaleGreen2', + 'PaleGreen3', 'PaleGreen4', 'SpringGreen2', 'SpringGreen3', 'SpringGreen4', + 'green2', 'green3', 'green4', 'chartreuse2', 'chartreuse3', 'chartreuse4', + 'OliveDrab1', 'OliveDrab2', 'OliveDrab4', 'DarkOliveGreen1', 'DarkOliveGreen2', + 'DarkOliveGreen3', 'DarkOliveGreen4', 'khaki1', 'khaki2', 'khaki3', 'khaki4', + 'LightGoldenrod1', 'LightGoldenrod2', 'LightGoldenrod3', 'LightGoldenrod4', + 'LightYellow2', 'LightYellow3', 'LightYellow4', 'yellow2', 'yellow3', 'yellow4', + 'gold2', 'gold3', 'gold4', 'goldenrod1', 'goldenrod2', 'goldenrod3', 'goldenrod4', + 'DarkGoldenrod1', 'DarkGoldenrod2', 'DarkGoldenrod3', 'DarkGoldenrod4', + 'RosyBrown1', 'RosyBrown2', 'RosyBrown3', 'RosyBrown4', 'IndianRed1', 'IndianRed2', + 'IndianRed3', 'IndianRed4', 'sienna1', 'sienna2', 'sienna3', 'sienna4', 'burlywood1', + 'burlywood2', 'burlywood3', 'burlywood4', 'wheat1', 'wheat2', 'wheat3', 'wheat4', 'tan1', + 'tan2', 'tan4', 'chocolate1', 'chocolate2', 'chocolate3', 'firebrick1', 'firebrick2', + 'firebrick3', 'firebrick4', 'brown1', 'brown2', 'brown3', 'brown4', 'salmon1', 'salmon2', + 'salmon3', 'salmon4', 'LightSalmon2', 'LightSalmon3', 'LightSalmon4', 'orange2', + 'orange3', 'orange4', 'DarkOrange1', 'DarkOrange2', 'DarkOrange3', 'DarkOrange4', + 'coral1', 'coral2', 'coral3', 'coral4', 'tomato2', 'tomato3', 'tomato4', 'OrangeRed2', + 'OrangeRed3', 'OrangeRed4', 'red2', 'red3', 'red4', 'DeepPink2', 'DeepPink3', 'DeepPink4', + 'HotPink1', 'HotPink2', 'HotPink3', 'HotPink4', 'pink1', 'pink2', 'pink3', 'pink4', + 'LightPink1', 'LightPink2', 'LightPink3', 'LightPink4', 'PaleVioletRed1', + 'PaleVioletRed2', 'PaleVioletRed3', 'PaleVioletRed4', 'maroon1', 'maroon2', + 'maroon3', 'maroon4', 'VioletRed1', 'VioletRed2', 'VioletRed3', 'VioletRed4', + 'magenta2', 'magenta3', 'magenta4', 'orchid1', 'orchid2', 'orchid3', 'orchid4', 'plum1', + 'plum2', 'plum3', 'plum4', 'MediumOrchid1', 'MediumOrchid2', 'MediumOrchid3', + 'MediumOrchid4', 'DarkOrchid1', 'DarkOrchid2', 'DarkOrchid3', 'DarkOrchid4', + 'purple1', 'purple2', 'purple3', 'purple4', 'MediumPurple1', 'MediumPurple2', + 'MediumPurple3', 'MediumPurple4', 'thistle1', 'thistle2', 'thistle3', 'thistle4', + 'grey1', 'grey2', 'grey3', 'grey4', 'grey5', 'grey6', 'grey7', 'grey8', 'grey9', 'grey10', + 'grey11', 'grey12', 'grey13', 'grey14', 'grey15', 'grey16', 'grey17', 'grey18', 'grey19', + 'grey20', 'grey21', 'grey22', 'grey23', 'grey24', 'grey25', 'grey26', 'grey27', 'grey28', + 'grey29', 'grey30', 'grey31', 'grey32', 'grey33', 'grey34', 'grey35', 'grey36', 'grey37', + 'grey38', 'grey39', 'grey40', 'grey42', 'grey43', 'grey44', 'grey45', 'grey46', 'grey47', + 'grey48', 'grey49', 'grey50', 'grey51', 'grey52', 'grey53', 'grey54', 'grey55', 'grey56', + 'grey57', 'grey58', 'grey59', 'grey60', 'grey61', 'grey62', 'grey63', 'grey64', 'grey65', + 'grey66', 'grey67', 'grey68', 'grey69', 'grey70', 'grey71', 'grey72', 'grey73', 'grey74', + 'grey75', 'grey76', 'grey77', 'grey78', 'grey79', 'grey80', 'grey81', 'grey82', 'grey83', + 'grey84', 'grey85', 'grey86', 'grey87', 'grey88', 'grey89', 'grey90', 'grey91', 'grey92', + 'grey93', 'grey94', 'grey95', 'grey97', 'grey98', 'grey99'] + +sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=0) + +layout = [[sg.Text('Click on a color square to see both white and black text on that color', text_color='blue', font='Any 15')]] +row = [] +# -- Create primary color viewer window -- +for i, color in enumerate(COLORS): + row.append(sg.RButton(color, button_color=('black', color), key=color)) + if (i+1) % 12 == 0: + layout.append(row) + row = [] + +window = sg.Window('Color Viewer', grab_anywhere=False, font=('any 9')).Layout(layout) + +# -- Event loop -- +while True: + b, v = window.Read() + if b is None: + break + # -- Create a secondary window that shows white and black text on chosen color + layout2 =[[sg.Button(b, button_color=('white', b)), sg.Button(b, button_color=('black', b))] ] + sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read() \ No newline at end of file diff --git a/Demo_Columns.py b/Demo_Columns.py index 9ca240a2..82258316 100644 --- a/Demo_Columns.py +++ b/Demo_Columns.py @@ -1,61 +1,20 @@ import PySimpleGUI as sg -# Demo of how columns work -# Form has on row 1 a vertical slider followed by a COLUMN with 7 rows -# Prior to the Column element, this layout was not possible -# Columns layouts look identical to form layouts, they are a list of lists of elements. +sg.ChangeLookAndFeel('BlueMono') -# sg.ChangeLookAndFeel('BlueMono') +# Column layout +col = [[sg.Text('col Row 1', text_color='white', background_color='blue')], + [sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')], + [sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]] +# Window layout +layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'), + select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20, 3)), + sg.Column(col, background_color='blue')], + [sg.Input('Last input')], + [sg.OK()]] +# Display the window and get values +button, values = sg.Window('Compact 1-line form with column').Layout(layout).Read() -def ScrollableColumns(): - # sg.ChangeLookAndFeel('Dark') +sg.Popup(button, values, line_width=200) - column1 = [[sg.Text('Column 1', justification='center', size=(20, 1))], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1', key='spin1', size=(30,1))], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3', key='spin3')]] - - - column2 = [[sg.T('Table Test')]] - - for i in range(50): - column2.append([sg.T(f'{i}{j}', size=(4, 1), background_color='gray25', text_color='white', pad=(1, 1)) for j in range(10)]) - - layout = [[sg.Column(column2, scrollable=True), sg.Column(column1, scrollable=True, size=(200,150))], - [sg.OK()]] - - form = sg.FlexForm('Form Fill Demonstration', grab_anywhere=False, default_element_size=(40, 1)) - b, v = form.LayoutAndRead(layout) - - sg.Popup(v) - -def NormalColumns(): - # Column layout - col = [[sg.Text('col Row 1', text_color='white', background_color='blue')], - [sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')], - [sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]] - - layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'), select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20,3)), sg.Column(col, background_color='blue')], - [sg.Input('Last input')], - [sg.OK()]] - - # Display the form and get values - # If you're willing to not use the "context manager" design pattern, then it's possible - # to collapse the form display and read down to a single line of code. - button, values = sg.FlexForm('Compact 1-line form with column', grab_anywhere=False).LayoutAndRead(layout) - - sg.Popup(button, values, line_width=200) - -# NormalColumns() -ScrollableColumns() \ No newline at end of file diff --git a/Demo_Compare_Files.py b/Demo_Compare_Files.py index b00fc5fb..638a1c31 100644 --- a/Demo_Compare_Files.py +++ b/Demo_Compare_Files.py @@ -1,24 +1,28 @@ import PySimpleGUI as sg +import sys -sg.SetOptions(button_color=sg.COLOR_SYSTEM_DEFAULT) +# sg.SetOptions(button_color=sg.COLOR_SYSTEM_DEFAULT) def GetFilesToCompare(): - with sg.FlexForm('File Compare') as form: - form_rows = [[sg.Text('Enter 2 files to comare')], - [sg.Text('File 1', size=(15, 1)), sg.InputText(key='file1'), sg.FileBrowse()], - [sg.Text('File 2', size=(15, 1)), sg.InputText(key='file2'), sg.FileBrowse(target='file2')], - [sg.Submit(), sg.Cancel()]] - button, values = form.LayoutAndRead(form_rows) + form_rows = [[sg.Text('Enter 2 files to comare')], + [sg.Text('File 1', size=(15, 1)), sg.InputText(key='file1'), sg.FileBrowse()], + [sg.Text('File 2', size=(15, 1)), sg.InputText(key='file2'), sg.FileBrowse(target='file2')], + [sg.Submit(), sg.Cancel()]] + + window = sg.Window('File Compare') + button, values = window.Layout(form_rows).Read() return button, values def main(): button, values = GetFilesToCompare() f1 = values['file1'] f2 = values['file2'] + if any((button != 'Submit', f1 =='', f2 == '')): sg.PopupError('Operation cancelled') - exit(69) + sys.exit(69) + # --- This portion of the code is not GUI related --- with open(f1, 'rb') as file1: with open(f2, 'rb') as file2: a = file1.read() diff --git a/Demo_Cookbook_Browser.py b/Demo_Cookbook_Browser.py deleted file mode 100644 index 2eeb06d1..00000000 --- a/Demo_Cookbook_Browser.py +++ /dev/null @@ -1,793 +0,0 @@ - - -# import PySimpleGUI as sg -import inspect - -def SimpleDataEntry(): - """Simple Data Entry - Return Values As List - Same GUI screen except the return values are in a list instead of a dictionary and doesn't have initial values. - """ - import PySimpleGUI as sg - # Very basic form. Return values as a list - form = sg.FlexForm('Simple data entry form') # begin with a blank form - - layout = [ - [sg.Text('Please enter your Name, Address, Phone')], - [sg.Text('Name', size=(15, 1)), sg.InputText()], - [sg.Text('Address', size=(15, 1)), sg.InputText()], - [sg.Text('Phone', size=(15, 1)), sg.InputText()], - [sg.Submit(), sg.Cancel()] - ] - - button, values = form.LayoutAndRead(layout) - - print(button, values[0], values[1], values[2]) - -def SimpleReturnAsDict(): - """ - Simple data entry - Return Values As Dictionary - A simple form with default values. Results returned in a dictionary. Does not use a context manager - """ - import PySimpleGUI as sg - - # Very basic form. Return values as a dictionary - form = sg.FlexForm('Simple data entry form') # begin with a blank form - - layout = [ - [sg.Text('Please enter your Name, Address, Phone')], - [sg.Text('Name', size=(15, 1)), sg.InputText('name', key='name')], - [sg.Text('Address', size=(15, 1)), sg.InputText('address', key='address')], - [sg.Text('Phone', size=(15, 1)), sg.InputText('phone', key='phone')], - [sg.Submit(), sg.Cancel()] - ] - - button, values = form.LayoutAndRead(layout) - - print(button, values['name'], values['address'], values['phone']) - -def FileBrowse(): - """ - Simple File Browse - Browse for a filename that is populated into the input field. - """ - import PySimpleGUI as sg - - with sg.FlexForm('SHA-1 & 256 Hash') as form: - form_rows = [[sg.Text('SHA-1 and SHA-256 Hashes for the file')], - [sg.InputText(), sg.FileBrowse()], - [sg.Submit(), sg.Cancel()]] - (button, (source_filename,)) = form.LayoutAndRead(form_rows) - - print(button, source_filename) - -def GUIAddOn(): - """ - Add GUI to Front-End of Script - Quickly add a GUI allowing the user to browse for a filename if a filename is not supplied on the command line using this 1-line GUI. It's the best of both worlds. - """ - import PySimpleGUI as sg - import sys - - if len(sys.argv) == 1: - button, (fname,) = sg.FlexForm('My Script').LayoutAndRead([[sg.T('Document to open')], - [sg.In(), sg.FileBrowse()], - [sg.Open(), sg.Cancel()]]) - else: - fname = sys.argv[1] - - if not fname: - sg.Popup("Cancel", "No filename supplied") - # raise SystemExit("Cancelling: no filename supplied") - -def Compare2Files(): - """ - Compare 2 Files - Browse to get 2 file names that can be then compared. Uses a context manager - """ - import PySimpleGUI as sg - - with sg.FlexForm('File Compare') as form: - form_rows = [[sg.Text('Enter 2 files to comare')], - [sg.Text('File 1', size=(8, 1)), sg.InputText(), sg.FileBrowse()], - [sg.Text('File 2', size=(8, 1)), sg.InputText(), sg.FileBrowse()], - [sg.Submit(), sg.Cancel()]] - - button, values = form.LayoutAndRead(form_rows) - - print(button, values) - -def AllWidgetsWithContext(): - """ - Nearly All Widgets with Green Color Theme with Context Manager - Example of nearly all of the widgets in a single form. Uses a customized color scheme. This recipe uses a context manager, the preferred method. - """ - import PySimpleGUI as sg - # Green & tan color scheme - sg.ChangeLookAndFeel('GreenTan') - - - # sg.ChangeLookAndFeel('GreenTan') - - with sg.FlexForm('Everything bagel', default_element_size=(40, 1), grab_anywhere=False) as form: - - column1 = [[sg.Text('Column 1', background_color='#F7F3EC', justification='center', size=(10, 1))], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]] - - layout = [ - [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))], - [sg.Text('Here is some text.... and a place to enter text')], - [sg.InputText('This is my text')], - [sg.Checkbox('Checkbox'), sg.Checkbox('My second checkbox!', default=True)], - [sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")], - [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)), - sg.Multiline(default_text='A second multi-line', size=(35, 3))], - [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)), - sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)], - [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))], - [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10), - sg.Column(column1, background_color='#F7F3EC')], - [sg.Text('_' * 80)], - [sg.Text('Choose A Folder', size=(35, 1))], - [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), - sg.InputText('Default Folder'), sg.FolderBrowse()], - [sg.Submit(), sg.Cancel()] - ] - - button, values = form.LayoutAndRead(layout) - -def AllWidgetsNoContext(): - """ - All Widgets No Context Manager - """ - import PySimpleGUI as sg - - sg.ChangeLookAndFeel('GreenTan') - - form = sg.FlexForm('Everything bagel', default_element_size=(40, 1), grab_anywhere=False) - - column1 = [[sg.Text('Column 1', background_color='#F7F3EC', justification='center', size=(10, 1))], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')], - [sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]] - - layout = [ - [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))], - [sg.Text('Here is some text.... and a place to enter text')], - [sg.InputText('This is my text')], - [sg.Checkbox('Checkbox'), sg.Checkbox('My second checkbox!', default=True)], - [sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")], - [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)), - sg.Multiline(default_text='A second multi-line', size=(35, 3))], - [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)), - sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)], - [sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))], - [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10), - sg.Column(column1, background_color='#F7F3EC')], - [sg.Text('_' * 80)], - [sg.Text('Choose A Folder', size=(35, 1))], - [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), - sg.InputText('Default Folder'), sg.FolderBrowse()], - [sg.Submit(), sg.Cancel()] - ] - - button, values = form.LayoutAndRead(layout) - -def NonBlockingWithUpdates(): - """ - Non-Blocking Form With Periodic Update - An async form that has a button read loop. A Text Element is updated periodically with a running timer. There is no context manager for this recipe because the loop that reads the form is likely to be some distance away from where the form was initialized. - """ - import PySimpleGUI as sg - import time - - form = sg.FlexForm('Running Timer') - # create a text element that will be updated periodically - - form_rows = [[sg.Text('Stopwatch', size=(20,2), justification='center')], - [ sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center', key='output')], - [sg.T(' ' * 5), sg.ReadFormButton('Start/Stop', focus=True), sg.Quit()]] - - form.LayoutAndRead(form_rows, non_blocking=True) - - timer_running = True - i = 0 - # loop to process user clicks - while True: - i += 1 * (timer_running is True) - button, values = form.ReadNonBlocking() - if values is None or button == 'Quit': # if user closed the window using X or clicked Quit button - break - elif button == 'Start/Stop': - timer_running = not timer_running - form.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) - - time.sleep(.01) - # if the loop finished then need to close the form for the user - form.CloseNonBlockingForm() - -def NonBlockingWithContext(): - """ - Async Form (Non-Blocking) with Context Manager - Like the previous recipe, this form is an async form. The difference is that this form uses a context manager. - """ - import PySimpleGUI as sg - import time - - with sg.FlexForm('Running Timer') as form: - layout = [[sg.Text('Non blocking GUI with updates', justification='center')], - [sg.Text('', size=(10, 2), font=('Helvetica', 20), text_color='red', justification='center', key='output')], - [sg.T(' ' * 15), sg.Quit()]] - form.LayoutAndRead(layout, non_blocking=True) - - for i in range(1, 500): - form.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) - button, values = form.ReadNonBlocking() - if values is None or button == 'Quit': # if user closed the window using X - break - time.sleep(.01) - else: - # if the loop finished then need to close the form for the user - form.CloseNonBlockingForm() - -def CallbackSimulation(): - """ - Callback Function Simulation - The architecture of some programs works better with button callbacks instead of handling in-line. While button callbacks are part of the PySimpleGUI implementation, they are not directly exposed to the caller. The way to get the same result as callbacks is to simulate them with a recipe like this one. - """ - import PySimpleGUI as sg - - # This design pattern simulates button callbacks - # Note that callbacks are NOT a part of the package's interface to the - # caller intentionally. The underlying implementation actually does use - # tkinter callbacks. They are simply hidden from the user. - - # The callback functions - def button1(): - print('Button 1 callback') - - def button2(): - print('Button 2 callback') - - # Create a standard form - form = sg.FlexForm('Button callback example') - # Layout the design of the GUI - layout = [[sg.Text('Please click a button')], - [sg.ReadFormButton('1'), sg.ReadFormButton('2'), sg.Quit()]] - # Show the form to the user - form.Layout(layout) - - # Event loop. Read buttons, make callbacks - while True: - # Read the form - button, value = form.Read() - # Take appropriate action based on button - if button == '1': - button1() - elif button == '2': - button2() - elif button =='Quit' or button is None: - break - - # All done! - sg.PopupOk('Done') - -def RealtimeButtons(): - """ - Realtime Buttons (Good For Raspberry Pi) - This recipe implements a remote control interface for a robot. There are 4 directions, forward, reverse, left, right. When a button is clicked, PySimpleGUI immediately returns button events for as long as the buttons is held down. When released, the button events stop. This is an async/non-blocking form. - """ - import PySimpleGUI as sg - - # Make a form, but don't use context manager - form = sg.FlexForm('Robotics Remote Control') - - form_rows = [[sg.Text('Robotics Remote Control')], - [sg.T(' ' * 10), sg.RealtimeButton('Forward')], - [sg.RealtimeButton('Left'), sg.T(' ' * 15), sg.RealtimeButton('Right')], - [sg.T(' ' * 10), sg.RealtimeButton('Reverse')], - [sg.T('')], - [sg.Quit(button_color=('black', 'orange'))] - ] - - form.LayoutAndRead(form_rows, non_blocking=True) - - # - # Some place later in your code... - # You need to perform a ReadNonBlocking on your form every now and then or - # else it won't refresh. - # - # your program's main loop - while (True): - # This is the code that reads and updates your window - button, values = form.ReadNonBlocking() - if button is not None: - print(button) - if button is 'Quit' or values is None: - break - - form.CloseNonBlockingForm() - -def EasyProgressMeter(): - """ - Easy Progress Meter - This recipe shows just how easy it is to add a progress meter to your code. - """ - import PySimpleGUI as sg - - for i in range(1000): - sg.EasyProgressMeter('Easy Meter Example', i+1, 1000) - -def TabbedForm(): - """ - Tabbed Form - Tabbed forms are easy to make and use in PySimpleGUI. You simple may your layouts for each tab and then instead of LayoutAndRead you call ShowTabbedForm. Results are returned as a list of form results. Each tab acts like a single form. - """ - import PySimpleGUI as sg - - with sg.FlexForm('') as form: - with sg.FlexForm('') as form2: - - layout_tab_1 = [[sg.Text('First tab', size=(20, 1), font=('helvetica', 15))], - [sg.InputText(), sg.Text('Enter some info')], - [sg.Submit(button_color=('red', 'yellow')), sg.Cancel(button_color=('white', 'blue'))]] - - layout_tab_2 = [[sg.Text('Second Tab', size=(20, 1), font=('helvetica', 15))], - [sg.InputText(), sg.Text('Enter some info')], - [sg.Submit(button_color=('red', 'yellow')), sg.Cancel(button_color=('white', 'blue'))]] - - results = sg.ShowTabbedForm('Tabbed form example', (form, layout_tab_1, 'First Tab'), - (form2, layout_tab_2,'Second Tab')) - - sg.Popup(results) - -def MediaPlayer(): - """ - Button Graphics (Media Player) - Buttons can have PNG of GIF images on them. This Media Player recipe requires 4 images in order to function correctly. The background is set to the same color as the button background so that they blend together. - """ - import PySimpleGUI as sg - - background = '#F0F0F0' - # Set the backgrounds the same as the background on the buttons - sg.SetOptions(background_color=background, element_background_color=background) - # Images are located in a subfolder in the Demo Media Player.py folder - image_pause = './ButtonGraphics/Pause.png' - image_restart = './ButtonGraphics/Restart.png' - image_next = './ButtonGraphics/Next.png' - image_exit = './ButtonGraphics/Exit.png' - - # Open a form, note that context manager can't be used generally speaking for async forms - form = sg.FlexForm('Media File Player', default_element_size=(20, 1), - font=("Helvetica", 25)) - # define layout of the rows - layout = [[sg.Text('Media File Player', size=(17, 1), font=("Helvetica", 25))], - [sg.Text('', size=(15, 2), font=("Helvetica", 14), key='out')], - [sg.ReadFormButton('Restart Song', button_color=(background, background), - image_filename=image_restart, image_size=(50, 50), image_subsample=2, border_width=0), - sg.Text(' ' * 2), - sg.ReadFormButton('Pause', button_color=(background, background), - image_filename=image_pause, image_size=(50, 50), image_subsample=2, border_width=0), - sg.Text(' ' * 2), - sg.ReadFormButton('Next', button_color=(background, background), - image_filename=image_next, image_size=(50, 50), image_subsample=2, border_width=0), - sg.Text(' ' * 2), - sg.Text(' ' * 2), sg.SimpleButton('Exit', button_color=(background, background), - image_filename=image_exit, image_size=(50, 50), image_subsample=2, - border_width=0)], - [sg.Text('_' * 20)], - [sg.Text(' ' * 30)], - [sg.Slider(range=(-10, 10), default_value=0, size=(10, 20), orientation='vertical', - font=("Helvetica", 15)), - sg.Text(' ' * 2), - sg.Slider(range=(-10, 10), default_value=0, size=(10, 20), orientation='vertical', - font=("Helvetica", 15)), - sg.Text(' ' * 8), - sg.Slider(range=(-10, 10), default_value=0, size=(10, 20), orientation='vertical', - font=("Helvetica", 15))], - [sg.Text('Bass', font=("Helvetica", 15), size=(6, 1)), - sg.Text('Treble', font=("Helvetica", 15), size=(10, 1)), - sg.Text('Volume', font=("Helvetica", 15), size=(7, 1))] ] - - # Call the same LayoutAndRead but indicate the form is non-blocking - form.LayoutAndRead(layout, non_blocking=True) - # Our event loop - while (True): - # Read the form (this call will not block) - button, values = form.ReadNonBlocking() - if button == 'Exit' or values is None: - break - # If a button was pressed, display it on the GUI by updating the text element - if button: - form.FindElement('out').Update(button) - -def ScriptLauncher(): - """ - Script Launcher - Persistent Form - This form doesn't close after button clicks. To achieve this the buttons are specified as sg.ReadFormButton instead of sg.SimpleButton. The exception to this is the EXIT button. Clicking it will close the form. This program will run commands and display the output in the scrollable window. - """ - import PySimpleGUI as sg - import subprocess - - def Launcher(): - - form = sg.FlexForm('Script launcher') - - layout = [ - [sg.Text('Script output....', size=(40, 1))], - [sg.Output(size=(88, 20))], - [sg.ReadFormButton('script1'), sg.ReadFormButton('script2'), sg.SimpleButton('EXIT')], - [sg.Text('Manual command', size=(15,1)), sg.InputText(focus=True), sg.ReadFormButton('Run', bind_return_key=True)] - ] - - form.Layout(layout) - - # ---===--- Loop taking in user input and using it to query HowDoI --- # - while True: - (button, value) = form.Read() - if button == 'EXIT' or button is None: - break # exit button clicked - if button == 'script1': - ExecuteCommandSubprocess('pip','list') - elif button == 'script2': - ExecuteCommandSubprocess('python', '--version') - elif button == 'Run': - ExecuteCommandSubprocess(value[0]) - - - def ExecuteCommandSubprocess(command, *args): - try: - expanded_args = [] - for a in args: - expanded_args += a - sp = subprocess.Popen([command,expanded_args], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - out, err = sp.communicate() - if out: - print(out.decode("utf-8")) - if err: - print(err.decode("utf-8")) - except: pass - - Launcher() - -def MachineLearning(): - """ - Machine Learning GUI - A standard non-blocking GUI with lots of inputs. - """ - import PySimpleGUI as sg - - sg.ChangeLookAndFeel('LightGreen') - - sg.SetOptions(text_justification='right') - - form = sg.FlexForm('Machine Learning Front End', font=("Helvetica", 12)) # begin with a blank form - - layout = [[sg.Text('Machine Learning Command Line Parameters', font=('Helvetica', 16))], - [sg.Text('Passes', size=(15, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1)), - sg.Text('Steps', size=(18, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1))], - [sg.Text('ooa', size=(15, 1)), sg.In(default_text='6', size=(10, 1)), sg.Text('nn', size=(15, 1)), sg.In(default_text='10', size=(10, 1))], - [sg.Text('q', size=(15, 1)), sg.In(default_text='ff', size=(10, 1)), sg.Text('ngram', size=(15, 1)), sg.In(default_text='5', size=(10, 1))], - [sg.Text('l', size=(15, 1)), sg.In(default_text='0.4', size=(10, 1)), sg.Text('Layers', size=(15, 1)), sg.Drop(values=('BatchNorm', 'other'),auto_size_text=True)], - [sg.Text('_' * 100, size=(65, 1))], - [sg.Text('Flags', font=('Helvetica', 15), justification='left')], - [sg.Checkbox('Normalize', size=(12, 1), default=True), sg.Checkbox('Verbose', size=(20, 1))], - [sg.Checkbox('Cluster', size=(12, 1)), sg.Checkbox('Flush Output', size=(20, 1), default=True)], - [sg.Checkbox('Write Results', size=(12, 1)), sg.Checkbox('Keep Intermediate Data', size=(20, 1))], - [sg.Text('_' * 100, size=(65, 1))], - [sg.Text('Loss Functions', font=('Helvetica', 15), justification='left')], - [sg.Radio('Cross-Entropy', 'loss', size=(12, 1)), sg.Radio('Logistic', 'loss', default=True, size=(12, 1))], - [sg.Radio('Hinge', 'loss', size=(12, 1)), sg.Radio('Huber', 'loss', size=(12, 1))], - [sg.Radio('Kullerback', 'loss', size=(12, 1)), sg.Radio('MAE(L1)', 'loss', size=(12, 1))], - [sg.Radio('MSE(L2)', 'loss', size=(12, 1)), sg.Radio('MB(L0)', 'loss', size=(12, 1))], - [sg.Submit(), sg.Cancel()]] - - button, values = form.LayoutAndRead(layout) - -def CustromProgressMeter(): - """" - Custom Progress Meter / Progress Bar - Perhaps you don't want all the statistics that the EasyProgressMeter provides and want to create your own progress bar. Use this recipe to do just that. - """ - import PySimpleGUI as sg - - def CustomMeter(): - # create the progress bar element - progress_bar = sg.ProgressBar(10000, orientation='h', size=(20,20)) - # layout the form - layout = [[sg.Text('A custom progress meter')], - [progress_bar], - [sg.Cancel()]] - - # create the form - form = sg.FlexForm('Custom Progress Meter') - # display the form as a non-blocking form - form.LayoutAndRead(layout, non_blocking=True) - # loop that would normally do something useful - for i in range(10000): - # check to see if the cancel button was clicked and exit loop if clicked - button, values = form.ReadNonBlocking() - if button == 'Cancel' or values == None: - break - # update bar with loop value +1 so that bar eventually reaches the maximum - progress_bar.UpdateBar(i+1) - # done with loop... need to destroy the window as it's still open - form.CloseNonBlockingForm() - - CustomMeter() - -def OneLineGUI(): - """ - The One-Line GUI - For those of you into super-compact code, a complete customized GUI can be specified, shown, and received the results using a single line of Python code. The way this is done is to combine the call to FlexForm and the call to LayoutAndRead. FlexForm returns a FlexForm object which has the LayoutAndRead method. - """ - import PySimpleGUI as sg - - layout = [[sg.Text('Filename')], - [sg.Input(), sg.FileBrowse()], - [sg.OK(), sg.Cancel()] ] - - button, (number,) = sg.FlexForm('Get filename example').LayoutAndRead(layout) - - """ - you can write this line of code for the exact same result (OK, two lines with the import): - """ - # import PySimpleGUI as sg - - button, (filename,) = sg.FlexForm('Get filename example'). LayoutAndRead([[sg.Text('Filename')], [sg.Input(), sg.FileBrowse()], [sg.OK(), sg.Cancel()] ]) - -def MultipleColumns(): - """ - Multiple Columns - Starting in version 2.9 (not yet released but you can get from current GitHub) you can use the Column Element. A Column is required when you have a tall element to the left of smaller elements. - - This example uses a Column. There is a Listbox on the left that is 3 rows high. To the right of it are 3 single rows of text and input. These 3 rows are in a Column Element. - - To make it easier to see the Column in the window, the Column background has been shaded blue. The code is wordier than normal due to the blue shading. Each element in the column needs to have the color set to match blue background. - """ - import PySimpleGUI as sg - - # Demo of how columns work - # Form has on row 1 a vertical slider followed by a COLUMN with 7 rows - # Prior to the Column element, this layout was not possible - # Columns layouts look identical to form layouts, they are a list of lists of elements. - - # sg.ChangeLookAndFeel('BlueMono') - - # Column layout - col = [[sg.Text('col Row 1', text_color='white', background_color='blue')], - [sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')], - [sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]] - - layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'), select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20,3)), sg.Column(col, background_color='blue')], - [sg.Input('Last input')], - [sg.OK()]] - - # Display the form and get values - # If you're willing to not use the "context manager" design pattern, then it's possible - # to collapse the form display and read down to a single line of code. - button, values = sg.FlexForm('Compact 1-line form with column').LayoutAndRead(layout) - - sg.Popup(button, values, line_width=200) - -def PersistentForm(): - """ - Persistent Form With Text Element Updates - This simple program keep a form open, taking input values until the user terminates the program using the "X" button. - """ - import PySimpleGUI as sg - - form = sg.FlexForm('Math') - - output = sg.Txt('', size=(8,1)) - - layout = [ [sg.Txt('Enter values to calculate')], - [sg.In(size=(8,1), key='numerator')], - [sg.Txt('_' * 10)], - [sg.In(size=(8,1), key='denominator')], - [output], - [sg.ReadFormButton('Calculate', bind_return_key=True)]] - - form.Layout(layout) - - while True: - button, values = form.Read() - - if button is not None: - try: - numerator = float(values['numerator']) - denominator = float(values['denominator']) - calc = numerator / denominator - except: - calc = 'Invalid' - - output.Update(calc) - else: - break - -def CanvasWidget(): - """ - tkinter Canvas Widget - The Canvas Element is one of the few tkinter objects that are directly accessible. The tkinter Canvas widget itself can be retrieved from a Canvas Element like this: - """ - - import PySimpleGUI as gui - - canvas = gui.Canvas(size=(100,100), background_color='red') - - layout = [ - [canvas], - [gui.T('Change circle color to:'), gui.ReadFormButton('Red'), gui.ReadFormButton('Blue')] - ] - - form = gui.FlexForm('Canvas test', grab_anywhere=True) - form.Layout(layout) - form.ReadNonBlocking() - - cir = canvas.TKCanvas.create_oval(50, 50, 100, 100) - - while True: - button, values = form.Read() - if button is None: - break - if button is 'Blue': - canvas.TKCanvas.itemconfig(cir, fill = "Blue") - elif button is 'Red': - canvas.TKCanvas.itemconfig(cir, fill = "Red") - -def InputElementUpdate(): - """ - Input Element Update - This Recipe implements a Raspberry Pi touchscreen based keypad entry. As the digits are entered using the buttons, the Input Element above it is updated with the input digits. There are a number of features used in this Recipe including: Default Element Size auto_size_buttons ReadFormButton Dictionary Return values Update of Elements in form (Input, Text) do_not_clear of Input Elements - """ - import PySimpleGUI as g - - # Demonstrates a number of PySimpleGUI features including: - # Default element size - # auto_size_buttons - # ReadFormButton - # Dictionary return values - # Update of elements in form (Text, Input) - # do_not_clear of Input elements - - layout = [[g.Text('Enter Your Passcode')], - [g.Input(size=(10, 1), do_not_clear=True, key='input')], - [g.ReadFormButton('1'), g.ReadFormButton('2'), g.ReadFormButton('3')], - [g.ReadFormButton('4'), g.ReadFormButton('5'), g.ReadFormButton('6')], - [g.ReadFormButton('7'), g.ReadFormButton('8'), g.ReadFormButton('9')], - [g.ReadFormButton('Submit'), g.ReadFormButton('0'), g.ReadFormButton('Clear')], - [ g.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='output')], - ] - - form = g.FlexForm('Keypad', default_element_size=(5, 2), auto_size_buttons=False) - form.Layout(layout) - - # Loop forever reading the form's values, updating the Input field - keys_entered = '' - while True: - button, values = form.Read() # read the form - if button is None: # if the X button clicked, just exit - break - if button is 'Clear': # clear keys if clear button - keys_entered = '' - elif button in '1234567890': - keys_entered = values['input'] # get what's been entered so far - keys_entered += button # add the new digit - elif button is 'Submit': - keys_entered = values['input'] - form.FindElement('output').Update(keys_entered) # output the final string - - form.FindElement('input').Update(keys_entered) # change the form to reflect current key string - - -def TableSimulation(): - """ - Display data in a table format - """ - import PySimpleGUI as sg - sg.ChangeLookAndFeel('Dark1') - - layout = [[sg.T('Table Test')]] - - for i in range(20): - layout.append([sg.T('{} {}'.format(i,j), size=(4, 1), background_color='black', pad=(1, 1)) for j in range(10)]) - - sg.FlexForm('Table').LayoutAndRead(layout) - - -def TightLayout(): - """ - Turn off padding in order to get a really tight looking layout. - """ - import PySimpleGUI as sg - - sg.ChangeLookAndFeel('Dark') - sg.SetOptions(element_padding=(0, 0)) - layout = [[sg.T('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User 2'), size=(20, 1)), - sg.T('0', size=(8, 1))], - [sg.T('Customer:', pad=((3, 0), 0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20, 1)), - sg.T('1', size=(8, 1))], - [sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black')], - [sg.ReadFormButton('Start', button_color=('white', 'black')), - sg.ReadFormButton('Stop', button_color=('white', 'black')), - sg.ReadFormButton('Reset', button_color=('white', '#9B0023')), - sg.ReadFormButton('Submit', button_color=('white', 'springgreen4')), - sg.SimpleButton('Exit', button_color=('white', '#00406B')), - ] - ] - - form = sg.FlexForm("Time Tracker", default_element_size=(12, 1), text_justification='r', auto_size_text=False, - auto_size_buttons=False, no_titlebar=True, - default_button_element_size=(12, 1)) - form.Layout(layout) - while True: - button, values = form.Read() - if button is None or button == 'Exit': - return - -# -------------------------------- GUI Starts Here -------------------------------# -# fig = your figure you want to display. Assumption is that 'fig' holds the # -# information to display. # -# --------------------------------------------------------------------------------# - - -import PySimpleGUI as sg - -fig_dict = {'Simple Data Entry':SimpleDataEntry, 'Simple Entry Return Data as Dict':SimpleReturnAsDict, 'File Browse' : FileBrowse, - 'GUI Add On':GUIAddOn, 'Compare 2 Files':Compare2Files, 'All Widgets With Context Manager':AllWidgetsWithContext, 'All Widgets No Context Manager':AllWidgetsNoContext, - 'Non-Blocking With Updates':NonBlockingWithUpdates, 'Non-Bocking With Context Manager':NonBlockingWithContext, 'Callback Simulation':CallbackSimulation, - 'Realtime Buttons':RealtimeButtons, 'Easy Progress Meter':EasyProgressMeter, 'Tabbed Form':TabbedForm, 'Media Player':MediaPlayer, 'Script Launcher':ScriptLauncher, - 'Machine Learning':MachineLearning, 'Custom Progress Meter':CustromProgressMeter, 'One Line GUI':OneLineGUI, 'Multiple Columns':MultipleColumns, - 'Persistent Form':PersistentForm, 'Canvas Widget':CanvasWidget, 'Input Element Update':InputElementUpdate, - 'Table Simulation':TableSimulation, 'Tight Layout':TightLayout} - - -# define the form layout -listbox_values = [key for key in fig_dict.keys()] - -while True: - sg.ChangeLookAndFeel('Dark') - # sg.SetOptions(element_padding=(0,0)) - - col_listbox = [[sg.Listbox(values=listbox_values, size=(max(len(x) for x in listbox_values),min(len(listbox_values), 20)), change_submits=False, key='func')], - [sg.ReadFormButton('Run', pad=(0,0)), sg.ReadFormButton('Show Code', button_color=('white', 'gray25'), pad=(0,0)), sg.Exit(button_color=('white', 'firebrick4'), pad=(0,0))]] - - layout = [[sg.Text('PySimpleGUI Coookbook', font=('current 18'))], - [sg.Column(col_listbox), sg.Multiline(size=(50,min(len(listbox_values), 20)), do_not_clear=True, key='multi')], - ] - -# create the form and show it without the plot -# form.Layout(layout) - - form = sg.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI', default_button_element_size=(9,1),auto_size_buttons=False, grab_anywhere=False) - form.Layout(layout) - # show it all again and get buttons - while True: - button, values = form.Read() - - if button is None or button == 'Exit': - exit(69) - try: - choice = values['func'][0] - func = fig_dict[choice] - except: - continue - - if button == 'Show Code' and values['multi']: - form.FindElement('multi').Update(inspect.getsource(func)) - elif button is 'Run' and values['func']: - # sg.ChangeLookAndFeel('SystemDefault') - form.CloseNonBlockingForm() - func() - break - else: - print('ILLEGAL values') - break - diff --git a/Demo_DOC_Viewer_PIL.py b/Demo_DOC_Viewer_PIL.py index 423be3ee..927027f1 100644 --- a/Demo_DOC_Viewer_PIL.py +++ b/Demo_DOC_Viewer_PIL.py @@ -22,7 +22,7 @@ This version contains enhancements: We also interpret keyboard events (PageDown / PageUp) and mouse wheel actions to support paging as if a button was clicked. Similarly, we do not include -a 'Quit' button. Instead, the ESCAPE key can be used, or cancelling the form. +a 'Quit' button. Instead, the ESCAPE key can be used, or cancelling the window. To improve paging performance, we are not directly creating pixmaps from pages, but instead from the fitz.DisplayList of the page. A display list will be stored in a list and looked up by page number. This way, zooming @@ -121,7 +121,7 @@ max_size = (max_width, max_height) root.destroy() del root -form = sg.FlexForm(title, return_keyboard_events = True, +window = sg.Window(title, return_keyboard_events = True, location = (0,0), use_default_focus = False, no_titlebar=False) cur_page = 0 @@ -137,18 +137,18 @@ goto = sg.InputText(str(cur_page + 1), size=(5, 1), do_not_clear=True, layout = [ [ - sg.ReadFormButton('Next'), - sg.ReadFormButton('Prev'), + sg.ReadButton('Next'), + sg.ReadButton('Prev'), sg.Text('Page:'), goto, sg.Text('(%i)' % page_count), - sg.ReadFormButton('Zoom'), + sg.ReadButton('Zoom'), sg.Text('(toggle on/off, use arrows to navigate while zooming)'), ], [image_elem], ] -form.Layout(layout) +window.Layout(layout) # now define the buttons / events we want to handle enter_buttons = [chr(13), "Return:13"] @@ -169,7 +169,7 @@ old_page = 0 old_zoom = False while True: - button, value = form.Read() + button, value = window.Read() if button is None and (value is None or value['PageNumber'] is None): break if button in quit_buttons: diff --git a/Demo_Desktop_Floating_Toolbar.py b/Demo_Desktop_Floating_Toolbar.py index 07d806f5..39630845 100644 --- a/Demo_Desktop_Floating_Toolbar.py +++ b/Demo_Desktop_Floating_Toolbar.py @@ -17,28 +17,28 @@ ROOT_PATH = './' def Launcher(): # def print(line): - # form.FindElement('output').Update(line) + # window.FindElement('output').Update(line) sg.ChangeLookAndFeel('Dark') namesonly = [f for f in os.listdir(ROOT_PATH) if f.endswith('.py') ] sg.SetOptions(element_padding=(0,0), button_element_size=(12,1), auto_size_buttons=False) + layout = [[sg.Combo(values=namesonly, size=(35,30), key='demofile'), - sg.ReadFormButton('Run', button_color=('white', '#00168B')), - sg.ReadFormButton('Program 1'), - sg.ReadFormButton('Program 2'), - sg.ReadFormButton('Program 3', button_color=('white', '#35008B')), - sg.SimpleButton('EXIT', button_color=('white','firebrick3'))], + sg.ReadButton('Run', button_color=('white', '#00168B')), + sg.ReadButton('Program 1'), + sg.ReadButton('Program 2'), + sg.ReadButton('Program 3', button_color=('white', '#35008B')), + sg.Button('EXIT', button_color=('white','firebrick3'))], [sg.T('', text_color='white', size=(50,1), key='output')]] - form = sg.FlexForm('Floating Toolbar', no_titlebar=True, keep_on_top=True) + window = sg.Window('Floating Toolbar', no_titlebar=True, keep_on_top=True).Layout(layout) - form.Layout(layout) - # ---===--- Loop taking in user input and using it to query HowDoI --- # + # ---===--- Loop taking in user input and executing appropriate program --- # while True: - (button, value) = form.Read() + (button, value) = window.Read() if button is 'EXIT' or button is None: break # exit button clicked if button is 'Program 1': diff --git a/Demo_Desktop_Widget_CPU_Graph.py b/Demo_Desktop_Widget_CPU_Graph.py index 3456ce3e..e7653b4e 100644 --- a/Demo_Desktop_Widget_CPU_Graph.py +++ b/Demo_Desktop_Widget_CPU_Graph.py @@ -36,10 +36,10 @@ def main(): layout = [ [sg.Quit( button_color=('white','black')), sg.T('', pad=((100,0),0), font='Any 15', key='output')], [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,SAMPLE_MAX),background_color='black', key='graph')],] - form = sg.FlexForm('CPU Graph', grab_anywhere=True, keep_on_top=True, background_color='black', no_titlebar=True, use_default_focus=False).Layout(layout) + window = sg.Window('CPU Graph', grab_anywhere=True, keep_on_top=True, background_color='black', no_titlebar=True, use_default_focus=False).Layout(layout) - graph = form.FindElement('graph') - output = form.FindElement('output') + graph = window.FindElement('graph') + output = window.FindElement('output') # start cpu measurement thread thread = Thread(target=CPU_thread,args=(None,)) thread.start() @@ -48,7 +48,7 @@ def main(): prev_x, prev_y = 0, 0 while True: # the Event Loop time.sleep(.5) - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button == 'Quit' or values is None: # always give ths user a way out break # do CPU measurement and graph it @@ -69,4 +69,3 @@ def main(): if __name__ == '__main__': main() - exit(69) diff --git a/Demo_Desktop_Widget_CPU_Utilization.py b/Demo_Desktop_Widget_CPU_Utilization.py index 69178101..60bb1ebf 100644 --- a/Demo_Desktop_Widget_CPU_Utilization.py +++ b/Demo_Desktop_Widget_CPU_Utilization.py @@ -39,19 +39,20 @@ def main(): # ---------------- Create Form ---------------- sg.ChangeLookAndFeel('Black') - form_rows = [[sg.Text('', size=(8,1), font=('Helvetica', 20),text_color=sg.YELLOWS[0], justification='center', key='text')], + layout = [[sg.Text('', size=(8,1), font=('Helvetica', 20),text_color=sg.YELLOWS[0], justification='center', key='text')], [sg.Text('', size=(30, 8), font=('Courier New', 12),text_color='white', justification='left', key='processes')], [sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0)), sg.Spin([x+1 for x in range(10)], 1, key='spin')],] - form = sg.FlexForm('CPU Utilization', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True) - form.Layout(form_rows) + window = sg.Window('CPU Utilization', no_titlebar=True, auto_size_buttons=False, + keep_on_top=True, grab_anywhere=True).Layout(layout) + # start cpu measurement thread thread = Thread(target=CPU_thread,args=(None,)) thread.start() # ---------------- main loop ---------------- while (True): # --------- Read and update window -------- - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() # --------- Do Button Operations -------- if values is None or button == 'Exit': @@ -84,14 +85,13 @@ def main(): # --------- Display timer in window -------- - form.FindElement('text').Update('CPU {}'.format(cpu_percent)) - form.FindElement('processes').Update(display_string) + window.FindElement('text').Update('CPU {}'.format(cpu_percent)) + window.FindElement('processes').Update(display_string) # Broke out of main loop. Close the window. - form.CloseNonBlockingForm() + window.CloseNonBlocking() g_exit = True thread.join() - exit(69) if __name__ == "__main__": main() \ No newline at end of file diff --git a/Demo_Desktop_Widget_CPU_Utilization_Simple.py b/Demo_Desktop_Widget_CPU_Utilization_Simple.py index 17583aab..7e9aa653 100644 --- a/Demo_Desktop_Widget_CPU_Utilization_Simple.py +++ b/Demo_Desktop_Widget_CPU_Utilization_Simple.py @@ -3,18 +3,17 @@ import psutil # ---------------- Create Form ---------------- sg.ChangeLookAndFeel('Black') -form_rows = [[sg.Text('')], +layout = [[sg.Text('')], [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')], [sg.Exit(button_color=('white', 'firebrick4'), pad=((15, 0), 0)), sg.Spin([x + 1 for x in range(10)], 1, key='spin')]] # Layout the rows of the form and perform a read. Indicate the form is non-blocking! -form = sg.FlexForm('CPU Meter', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True) -form.Layout(form_rows) +window = sg.Window('CPU Meter', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout) # ---------------- main loop ---------------- while (True): # --------- Read and update window -------- - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() # --------- Do Button Operations -------- if values is None or button == 'Exit': @@ -28,7 +27,7 @@ while (True): # --------- Display timer in window -------- - form.FindElement('text').Update(f'CPU {cpu_percent:02.0f}%') + window.FindElement('text').Update(f'CPU {cpu_percent:02.0f}%') # Broke out of main loop. Close the window. -form.CloseNonBlockingForm() \ No newline at end of file +window.CloseNonBlocking() \ No newline at end of file diff --git a/Demo_Desktop_Widget_Timer.py b/Demo_Desktop_Widget_Timer.py index b8ce0ae9..1c905a3f 100644 --- a/Demo_Desktop_Widget_Timer.py +++ b/Demo_Desktop_Widget_Timer.py @@ -11,14 +11,13 @@ import time sg.ChangeLookAndFeel('Black') sg.SetOptions(element_padding=(0, 0)) -form_rows = [[sg.Text('')], - [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')], - [sg.ReadFormButton('Pause', key='button', button_color=('white', '#001480')), - sg.ReadFormButton('Reset', button_color=('white', '#007339'), key='Reset'), - sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]] +layout = [[sg.Text('')], + [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')], + [sg.ReadButton('Pause', key='button', button_color=('white', '#001480')), + sg.ReadButton('Reset', button_color=('white', '#007339'), key='Reset'), + sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]] -form = sg.FlexForm('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True) -form.Layout(form_rows) +window = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout) # ---------------- main loop ---------------- current_time = 0 @@ -27,12 +26,12 @@ start_time = int(round(time.time() * 100)) while (True): # --------- Read and update window -------- if not paused: - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() current_time = int(round(time.time() * 100)) - start_time else: - button, values = form.Read() + button, values = window.Read() if button == 'button': - button = form.FindElement(button).GetText() + button = window.FindElement(button).GetText() # --------- Do Button Operations -------- if values is None or button == 'Exit': break @@ -43,16 +42,16 @@ while (True): elif button == 'Pause': paused = True paused_time = int(round(time.time() * 100)) - element = form.FindElement('button') + element = window.FindElement('button') element.Update(text='Run') elif button == 'Run': paused = False start_time = start_time + int(round(time.time() * 100)) - paused_time - element = form.FindElement('button') + element = window.FindElement('button') element.Update(text='Pause') # --------- Display timer in window -------- - form.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60, + window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60, (current_time // 100) % 60, current_time % 100)) time.sleep(.01) @@ -60,4 +59,4 @@ while (True): # --------- After loop -------- # Broke out of main loop. Close the window. -form.CloseNonBlockingForm() +window.CloseNonBlocking() diff --git a/Demo_Disable_Elements.py b/Demo_Disable_Elements.py index aed84807..789011c5 100644 --- a/Demo_Disable_Elements.py +++ b/Demo_Disable_Elements.py @@ -1,11 +1,8 @@ import PySimpleGUI as sg -""" -Turn off padding in order to get a really tight looking layout. -""" - sg.ChangeLookAndFeel('Dark') sg.SetOptions(element_padding=(0, 0)) + layout = [ [sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black', key='notes')], [sg.T('Output:', pad=((3, 0), 0)), sg.T('', size=(44, 1), text_color='white', key='output')], @@ -14,56 +11,28 @@ layout = [ [sg.Spin((1,2,3,4),1, key='spin'), sg.OptionMenu((1,2,3,4), key='option'), sg.Combo(values=(1,2,3,4),key='combo')], [sg.Multiline('Multiline', size=(20,3), key='multi')], [sg.Slider((1,10), size=(20,20), orientation='h', key='slider')], - [sg.ReadFormButton('Enable', button_color=('white', 'black')), - sg.ReadFormButton('Disable', button_color=('white', 'black')), - sg.ReadFormButton('Reset', button_color=('white', '#9B0023'), key='reset'), - sg.ReadFormButton('Values', button_color=('white', 'springgreen4')), - sg.SimpleButton('Exit', button_color=('white', '#00406B'))]] + [sg.ReadButton('Enable', button_color=('white', 'black')), + sg.ReadButton('Disable', button_color=('white', 'black')), + sg.ReadButton('Reset', button_color=('white', '#9B0023'), key='reset'), + sg.ReadButton('Values', button_color=('white', 'springgreen4')), + sg.Button('Exit', button_color=('white', '#00406B'))]] -form = sg.FlexForm("Disable Elements Demo", default_element_size=(12, 1), text_justification='r', auto_size_text=False, +window = sg.Window("Disable Elements Demo", default_element_size=(12, 1), text_justification='r', auto_size_text=False, auto_size_buttons=False, keep_on_top=True, grab_anywhere=False, default_button_element_size=(12, 1)).Layout(layout).Finalize() -form.FindElement('cbox').Update(disabled=True) -form.FindElement('listbox').Update(disabled=True) -form.FindElement('radio1').Update(disabled=True) -form.FindElement('radio2').Update(disabled=True) -form.FindElement('spin').Update(disabled=True) -form.FindElement('option').Update(disabled=True) -form.FindElement('combo').Update(disabled=True) -form.FindElement('reset').Update(disabled=True) -form.FindElement('notes').Update(disabled=True) -form.FindElement('multi').Update(disabled=True) -form.FindElement('slider').Update(disabled=True) +key_list = 'cbox', 'listbox', 'radio1', 'radio2', 'spin', 'option', 'combo', 'reset', 'notes', 'multi', 'slider' + +for key in key_list: window.FindElement(key).Update(disabled=True) # don't do this kind of for-loop while True: - button, values = form.Read() + button, values = window.Read() if button is None or button == 'Exit': break elif button == 'Disable': - form.FindElement('cbox').Update(disabled=True) - form.FindElement('listbox').Update(disabled=True) - form.FindElement('radio1').Update(disabled=True) - form.FindElement('radio2').Update(disabled=True) - form.FindElement('spin').Update(disabled=True) - form.FindElement('option').Update(disabled=True) - form.FindElement('combo').Update(disabled=True) - form.FindElement('reset').Update(disabled=True) - form.FindElement('notes').Update(disabled=True) - form.FindElement('multi').Update(disabled=True) - form.FindElement('slider').Update(disabled=True) + for key in key_list: window.FindElement(key).Update(disabled=True) elif button == 'Enable': - form.FindElement('cbox').Update(disabled=False) - form.FindElement('listbox').Update(disabled=False) - form.FindElement('radio1').Update(disabled=False) - form.FindElement('radio2').Update(disabled=False) - form.FindElement('spin').Update(disabled=False) - form.FindElement('option').Update(disabled=False) - form.FindElement('combo').Update(disabled=False) - form.FindElement('reset').Update(disabled=False) - form.FindElement('notes').Update(disabled=False) - form.FindElement('multi').Update(disabled=False) - form.FindElement('slider').Update(disabled=False) + for key in key_list: window.FindElement(key).Update(disabled=False) elif button == 'Values': sg.Popup(values, keep_on_top=True) diff --git a/Demo_DisplayHash1and256.py b/Demo_DisplayHash1and256.py deleted file mode 100644 index bff8a836..00000000 --- a/Demo_DisplayHash1and256.py +++ /dev/null @@ -1,124 +0,0 @@ -#!Python 3 -import hashlib -import PySimpleGUI as sg - - ######################################################################### -# DisplayHash # -# A PySimpleGUI demo app that displays SHA1 hash for user browsed file # -# Useful and a recipe for GUI success # - ######################################################################### - -# ====____====____==== FUNCTION compute_hash_for_file(filename) ====____====____==== # -# Reads a file, computes the Hash # -# ---------------------------------------------------------------------------------- # -def compute_sha1_hash_for_file(filename): - try: - x = open(filename, "rb").read() - except: - return 0 - - m = hashlib.sha1() - m.update(x) - f_sha = m.hexdigest() - - return f_sha - - -# ====____====____==== FUNCTION compute_hash_for_file(filename) ====____====____==== # -# Reads a file, computes the Hash # -# ---------------------------------------------------------------------------------- # -def compute_sha256_hash_for_file(filename): - try: - f = open(filename, "rb") - x = f.read() - except: - return 0 - - m = hashlib.sha256() - m.update(x) - f_sha = m.hexdigest() - - return f_sha - - - # ====____====____==== Uses A GooeyGUI GUI ====____====____== # -# Get the filename, display the hash, dirt simple all around # - # ----------------------------------------------------------- # - -# ---------------------------------------------------------------------- # -# Compute and display SHA1 hash # -# Builds and displays the form using the most basic building blocks # -# ---------------------------------------------------------------------- # -def HashManuallyBuiltGUI(): - # ------- Form design ------- # - with sg.FlexForm('SHA-1 & 256 Hash', auto_size_text=True) as form: - form_rows = [[sg.Text('SHA-1 and SHA-256 Hashes for the file')], - [sg.InputText(), sg.FileBrowse()], - [sg.Submit(), sg.Cancel()]] - (button, (source_filename, )) = form.LayoutAndRead(form_rows) - - if button == 'Submit': - if source_filename != '': - hash_sha1 = compute_sha1_hash_for_file(source_filename).upper() - hash_sha256 = compute_sha256_hash_for_file(source_filename).upper() - sg.Popup('Display A Hash in PySimpleGUI', 'The SHA-1 Hash for the file\n', source_filename, hash_sha1, 'SHA-256 is', hash_sha256, line_width=75) - else: sg.PopupError('Display A Hash in PySimpleGUI', 'Illegal filename') - else: - sg.PopupError('Display A Hash in PySimpleGUI', '* Cancelled *') - -def HashManuallyBuiltGUINonContext(): - # ------- Form design ------- # - form = sg.FlexForm('SHA-1 & 256 Hash', auto_size_text=True) - form_rows = [[sg.Text('SHA-1 and SHA-256 Hashes for the file')], - [sg.InputText(), sg.FileBrowse()], - [sg.Submit(), sg.Cancel()]] - button, (source_filename, ) = form.LayoutAndRead(form_rows) - - if button == 'Submit': - if source_filename != '': - hash_sha1 = compute_sha1_hash_for_file(source_filename).upper() - hash_sha256 = compute_sha256_hash_for_file(source_filename).upper() - sg.Popup('Display A Hash in PySimpleGUI', 'The SHA-1 Hash for the file\n', source_filename, hash_sha1, 'SHA-256 is', hash_sha256, line_width=75) - else: sg.PopupError('Display A Hash in PySimpleGUI', 'Illegal filename') - else: - sg.PopupError('Display A Hash in PySimpleGUI', '* Cancelled *') - - - - -# ---------------------------------------------------------------------- # -# Compute and display SHA1 hash # -# This one cheats and uses the higher-level Get A File pre-made func # -# Hey, it's a really common operation so why not? # -# ---------------------------------------------------------------------- # -def HashMostCompactGUI(): - # ------- INPUT GUI portion ------- # - - source_filename = sg.PopupGetFile('Display a Hash code for file of your choice') - - # ------- OUTPUT GUI results portion ------- # - if source_filename != None: - hash = compute_sha1_hash_for_file(source_filename) - sg.Print(hash) - sg.Popup('Display Hash - Compact GUI', 'The SHA-1 Hash for the file\n', source_filename, hash) - else: - sg.Popup('Display Hash - Compact GUI', '* Cancelled *') - - -# ---------------------------------------------------------------------- # -# Our main calls two GUIs that act identically but use different calls # -# ---------------------------------------------------------------------- # -def main(): - # HashManuallyBuiltGUI() - # HashManuallyBuiltGUINonContext() - HashMostCompactGUI() - - -# ====____====____==== Pseudo-MAIN program ====____====____==== # -# This is our main-alike piece of code # -# + Starts up the GUI # -# + Gets values from GUI # -# + Runs DeDupe_folder based on GUI inputs # -# ------------------------------------------------------------- # -if __name__ == '__main__': - main() diff --git a/Demo_Fill_Form.py b/Demo_Fill_Form.py index aaa0ae18..30c20544 100644 --- a/Demo_Fill_Form.py +++ b/Demo_Fill_Form.py @@ -31,29 +31,29 @@ def Everything(): [sg.Text('Choose A Folder', size=(35, 1))], [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Default Folder', key='folder', do_not_clear=True), sg.FolderBrowse()], - [sg.ReadFormButton('Exit'), - sg.Text(' ' * 40), sg.ReadFormButton('SaveSettings'), sg.ReadFormButton('LoadSettings')] + [sg.ReadButton('Exit'), + sg.Text(' ' * 40), sg.ReadButton('SaveSettings'), sg.ReadButton('LoadSettings')] ] - form = sg.FlexForm('Form Fill Demonstration', default_element_size=(40, 1), grab_anywhere=False) - # button, values = form.LayoutAndRead(layout, non_blocking=True) - form.Layout(layout) + window = sg.Window('Form Fill Demonstration', default_element_size=(40, 1), grab_anywhere=False) + # button, values = window.LayoutAndRead(layout, non_blocking=True) + window.Layout(layout) while True: - button, values = form.Read() + button, values = window.Read() if button is 'SaveSettings': filename = sg.PopupGetFile('Save Settings', save_as=True, no_window=True) - form.SaveToDisk(filename) + window.SaveToDisk(filename) # save(values) elif button is 'LoadSettings': filename = sg.PopupGetFile('Load Settings', no_window=True) - form.LoadFromDisk(filename) + window.LoadFromDisk(filename) # load(form) elif button in ['Exit', None]: break - # form.CloseNonBlockingForm() + # window.CloseNonBlocking() if __name__ == '__main__': diff --git a/Demo_Font_Sizer.py b/Demo_Font_Sizer.py index d030af93..861b0b8e 100644 --- a/Demo_Font_Sizer.py +++ b/Demo_Font_Sizer.py @@ -7,10 +7,10 @@ fontSize = 12 layout = [[sg.Spin([sz for sz in range(6, 172)], font=('Helvetica 20'), initial_value=fontSize, change_submits=True, key='spin'), sg.Slider(range=(6,172), orientation='h', size=(10,20), change_submits=True, key='slider', font=('Helvetica 20')), sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontSize), key='text')]] sz = fontSize -form = sg.FlexForm("Font size selector", grab_anywhere=False) -form.Layout(layout) +window = sg.Window("Font size selector", grab_anywhere=False) +window.Layout(layout) while True: - button, values= form.Read() + button, values= window.Read() if button is None or button == 'Quit': break sz_spin = int(values['spin']) @@ -19,8 +19,8 @@ while True: if sz != fontSize: fontSize = sz font = "Helvetica " + str(fontSize) - form.FindElement('text').Update(font=font) - form.FindElement('slider').Update(sz) - form.FindElement('spin').Update(sz) + window.FindElement('text').Update(font=font) + window.FindElement('slider').Update(sz) + window.FindElement('spin').Update(sz) print("Done.") diff --git a/Demo_Func_Callback_Simulation.py b/Demo_Func_Callback_Simulation.py index a3f5df84..5b0ef2d0 100644 --- a/Demo_Func_Callback_Simulation.py +++ b/Demo_Func_Callback_Simulation.py @@ -4,11 +4,11 @@ layout = [[sg.Text('Filename', )], [sg.Input(), sg.FileBrowse()], [sg.OK(), sg.Cancel()]] -button, (number,) = sg.FlexForm('Get filename example').LayoutAndRead(layout) +button, (number,) = sg.Window('Get filename example').LayoutAndRead(layout) import PySimpleGUI as sg -button, (filename,) = sg.FlexForm('Get filename example').LayoutAndRead( +button, (filename,) = sg.Window('Get filename example').LayoutAndRead( [[sg.Text('Filename')], [sg.Input(), sg.FileBrowse()], [sg.OK(), sg.Cancel()]]) \ No newline at end of file diff --git a/Demo_GoodColors.py b/Demo_GoodColors.py index f1c0a09c..33289861 100644 --- a/Demo_GoodColors.py +++ b/Demo_GoodColors.py @@ -2,48 +2,48 @@ import PySimpleGUI as gg import time def main(): - # ------- Make a new FlexForm ------- # - form = gg.FlexForm('GoodColors', auto_size_text=True, default_element_size=(30,2)) - form.AddRow(gg.Text('Having trouble picking good colors? Try one of the colors defined by PySimpleGUI')) - form.AddRow(gg.Text('Here come the good colors as defined by PySimpleGUI')) + # ------- Make a new Window ------- # + window = gg.Window('GoodColors', auto_size_text=True, default_element_size=(30,2)) + window.AddRow(gg.Text('Having trouble picking good colors? Try one of the colors defined by PySimpleGUI')) + window.AddRow(gg.Text('Here come the good colors as defined by PySimpleGUI')) #===== Show some nice BLUE colors with yellow text ===== ===== ===== ===== ===== ===== =====# text_color = gg.YELLOWS[0] - buttons = (gg.SimpleButton('BLUES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.BLUES)) - form.AddRow(gg.T('Button Colors Using PySimpleGUI.BLUES')) - form.AddRow(*buttons) - form.AddRow(gg.Text('_' * 100, size=(65, 1))) + buttons = (gg.Button('BLUES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.BLUES)) + window.AddRow(gg.T('Button Colors Using PySimpleGUI.BLUES')) + window.AddRow(*buttons) + window.AddRow(gg.Text('_' * 100, size=(65, 1))) #===== Show some nice PURPLE colors with yellow text ===== ===== ===== ===== ===== ===== =====# - buttons = (gg.SimpleButton('PURPLES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.PURPLES)) - form.AddRow(gg.T('Button Colors Using PySimpleGUI.PURPLES')) - form.AddRow(*buttons) - form.AddRow(gg.Text('_' * 100, size=(65, 1))) + buttons = (gg.Button('PURPLES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.PURPLES)) + window.AddRow(gg.T('Button Colors Using PySimpleGUI.PURPLES')) + window.AddRow(*buttons) + window.AddRow(gg.Text('_' * 100, size=(65, 1))) #===== Show some nice GREEN colors with yellow text ===== ===== ===== ===== ===== ===== =====# - buttons = (gg.SimpleButton('GREENS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.GREENS)) - form.AddRow(gg.T('Button Colors Using PySimpleGUI.GREENS')) - form.AddRow(*buttons) - form.AddRow(gg.Text('_' * 100, size=(65, 1))) + buttons = (gg.Button('GREENS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.GREENS)) + window.AddRow(gg.T('Button Colors Using PySimpleGUI.GREENS')) + window.AddRow(*buttons) + window.AddRow(gg.Text('_' * 100, size=(65, 1))) #===== Show some nice TAN colors with yellow text ===== ===== ===== ===== ===== ===== =====# text_color = gg.GREENS[0] # let's use GREEN text on the tan - buttons = (gg.SimpleButton('TANS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.TANS)) - form.AddRow(gg.T('Button Colors Using PySimpleGUI.TANS')) - form.AddRow(*buttons) - form.AddRow(gg.Text('_' * 100, size=(65, 1))) + buttons = (gg.Button('TANS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.TANS)) + window.AddRow(gg.T('Button Colors Using PySimpleGUI.TANS')) + window.AddRow(*buttons) + window.AddRow(gg.Text('_' * 100, size=(65, 1))) #===== Show some nice YELLOWS colors with black text ===== ===== ===== ===== ===== ===== =====# text_color = 'black' # let's use black text on the tan - buttons = (gg.SimpleButton('YELLOWS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.YELLOWS)) - form.AddRow(gg.T('Button Colors Using PySimpleGUI.YELLOWS')) - form.AddRow(*buttons) - form.AddRow(gg.Text('_' * 100, size=(65, 1))) + buttons = (gg.Button('YELLOWS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(gg.YELLOWS)) + window.AddRow(gg.T('Button Colors Using PySimpleGUI.YELLOWS')) + window.AddRow(*buttons) + window.AddRow(gg.Text('_' * 100, size=(65, 1))) - #===== Add a click me button for fun and SHOW the form ===== ===== ===== ===== ===== ===== =====# - form.AddRow(gg.SimpleButton('Click ME!')) - (button, value) = form.Show() # show it! + #===== Add a click me button for fun and SHOW the window ===== ===== ===== ===== ===== ===== =====# + window.AddRow(gg.Button('Click ME!')) + (button, value) = window.Show() # show it! if __name__ == '__main__': diff --git a/Demo_Graph_Drawing.py b/Demo_Graph_Drawing.py index de8a82f7..ee812c52 100644 --- a/Demo_Graph_Drawing.py +++ b/Demo_Graph_Drawing.py @@ -2,12 +2,12 @@ import PySimpleGUI as sg layout = [ [sg.Graph(canvas_size=(400, 400), graph_bottom_left=(0,0), graph_top_right=(400, 400), background_color='red', key='graph')], - [sg.T('Change circle color to:'), sg.ReadFormButton('Red'), sg.ReadFormButton('Blue'), sg.ReadFormButton('Move')] + [sg.T('Change circle color to:'), sg.ReadButton('Red'), sg.ReadButton('Blue'), sg.ReadButton('Move')] ] -form = sg.FlexForm('Graph test').Layout(layout).Finalize() +window = sg.Window('Graph test').Layout(layout) -graph = form.FindElement('graph') +graph = window.FindElement('graph') circle = graph.DrawCircle((75,75), 25, fill_color='black',line_color='white') point = graph.DrawPoint((75,75), 10, color='green') oval = graph.DrawOval((25,300), (100,280), fill_color='purple', line_color='purple' ) @@ -15,7 +15,7 @@ rectangle = graph.DrawRectangle((25,300), (100,280), line_color='purple' ) line = graph.DrawLine((0,0), (100,100)) while True: - button, values = form.Read() + button, values = window.Read() if button is None: break if button is 'Blue': diff --git a/Demo_Graph_Element.py b/Demo_Graph_Element.py index 174ce1fb..da50d3ae 100644 --- a/Demo_Graph_Element.py +++ b/Demo_Graph_Element.py @@ -5,8 +5,8 @@ import PySimpleGUI as sg STEP_SIZE=1 -SAMPLES = 6000 -CANVAS_SIZE = (6000,500) +SAMPLES = 1000 +CANVAS_SIZE = (1000,500) # globale used to communicate with thread.. yea yea... it's working fine g_exit = False @@ -29,11 +29,11 @@ def main(): layout = [ [sg.T('Ping times to Google.com', font='Any 12'), sg.Quit(pad=((100,0), 0), button_color=('white', 'black'))], [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,500),background_color='black', key='graph')],] - form = sg.FlexForm('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False) - form.Layout(layout) + window = sg.Window('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False) + window.Layout(layout) - form.Finalize() - graph = form.FindElement('graph') + window.Finalize() + graph = window.FindElement('graph') prev_response_time = None i=0 @@ -41,7 +41,7 @@ def main(): while True: time.sleep(.2) - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button == 'Quit' or values is None: break if g_response_time is None or prev_response_time == g_response_time: @@ -52,7 +52,7 @@ def main(): graph.Move(-STEP_SIZE,0) prev_x = prev_x - STEP_SIZE graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white') - # form.FindElement('graph').DrawPoint((new_x, new_y), color='red') + # window.FindElement('graph').DrawPoint((new_x, new_y), color='red') prev_x, prev_y = new_x, new_y i += STEP_SIZE if i < SAMPLES else 0 @@ -63,4 +63,3 @@ def main(): if __name__ == '__main__': main() - exit(69) \ No newline at end of file diff --git a/Demo_Graph_Element_Sine_Wave.py b/Demo_Graph_Element_Sine_Wave.py index 5d922fde..2609f6a8 100644 --- a/Demo_Graph_Element_Sine_Wave.py +++ b/Demo_Graph_Element_Sine_Wave.py @@ -3,8 +3,8 @@ import PySimpleGUI as sg layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-100,-100), graph_top_right=(100,100), background_color='white', key='graph', tooltip='This is a cool graph!')],] -form = sg.FlexForm('Graph of Sine Function', grab_anywhere=True).Layout(layout).Finalize() -graph = form.FindElement('graph') +window = sg.Window('Graph of Sine Function', grab_anywhere=True).Layout(layout).Finalize() +graph = window.FindElement('graph') graph.DrawLine((-100,0), (100,0)) graph.DrawLine((0,-100), (0,100)) @@ -13,4 +13,4 @@ for x in range(-100,100): y = math.sin(x/20)*50 graph.DrawPoint((x,y), color='red') -button, values = form.Read() +button, values = window.Read() diff --git a/Demo_Graph_Noise.py b/Demo_Graph_Noise.py index fbef4bc4..88b7c52b 100644 --- a/Demo_Graph_Noise.py +++ b/Demo_Graph_Noise.py @@ -1,7 +1,7 @@ import time import random import PySimpleGUI as sg - +import sys STEP_SIZE=1 SAMPLES = 300 @@ -12,16 +12,16 @@ CANVAS_SIZE = (300,300) def main(): global g_exit, g_response_time - with sg.FlexForm('Enter graph size') as form: - layout = [[sg.T('Enter width, height of graph')], - [sg.In(size=(6, 1)), sg.In(size=(6, 1))], - [sg.Ok(), sg.Cancel()]] + layout = [[sg.T('Enter width, height of graph')], + [sg.In(size=(6, 1)), sg.In(size=(6, 1))], + [sg.Ok(), sg.Cancel()]] - b,v = form.LayoutAndRead(layout) - if b is None or b == 'Cancel': - exit(69) - w, h = int(v[0]), int(v[1]) - CANVAS_SIZE = (w,h) + window = sg.Window('Enter graph size').Layout(layout) + b,v = window.Read() + if b is None or b == 'Cancel': + sys.exit(69) + w, h = int(v[0]), int(v[1]) + CANVAS_SIZE = (w,h) # start ping measurement thread @@ -31,8 +31,8 @@ def main(): layout = [ [sg.Quit( button_color=('white','black'))], [sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,SAMPLE_MAX),background_color='black', key='graph')],] - form = sg.FlexForm('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False).Layout(layout).Finalize() - graph = form.FindElement('graph') + window = sg.Window('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False).Layout(layout).Finalize() + graph = window.FindElement('graph') prev_response_time = None i=0 @@ -40,7 +40,7 @@ def main(): graph_value = 250 while True: # time.sleep(.2) - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button == 'Quit' or values is None: break graph_offset = random.randint(-10, 10) @@ -55,7 +55,7 @@ def main(): graph.Move(-STEP_SIZE,0) prev_x = prev_x - STEP_SIZE graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white') - # form.FindElement('graph').DrawPoint((new_x, new_y), color='red') + # window.FindElement('graph').DrawPoint((new_x, new_y), color='red') prev_x, prev_y = new_x, new_y i += STEP_SIZE if i < SAMPLES else 0 @@ -63,4 +63,3 @@ def main(): if __name__ == '__main__': main() - exit(69) \ No newline at end of file diff --git a/Demo_HowDoI.py b/Demo_HowDoI.py index 83c7c660..cb1c42ce 100644 --- a/Demo_HowDoI.py +++ b/Demo_HowDoI.py @@ -1,17 +1,6 @@ import PySimpleGUI as sg import subprocess -import ctypes -import os -import win32process - -# hwnd = ctypes.windll.kernel32.GetConsoleWindow() -# if hwnd != 0: -# ctypes.windll.user32.ShowWindow(hwnd, 0) -# ctypes.windll.kernel32.CloseHandle(hwnd) -# _, pid = win32process.GetWindowThreadProcessId(hwnd) -# os.system('taskkill /PID ' + str(pid) + ' /f') - # Test this command in a dos window if you are having trouble. HOW_DO_I_COMMAND = 'python -m howdoi.howdoi' @@ -27,7 +16,7 @@ def HowDoI(): 2. Non-Window-Closing Buttons - These buttons will cause the form to return with the form's values, but doesn't close the form :return: never returns ''' - # ------- Make a new FlexForm ------- # + # ------- Make a new Window ------- # sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors layout = [ @@ -37,39 +26,38 @@ def HowDoI(): sg.Text('Num Answers',font='Helvetica 15'), sg.Checkbox('Display Full Text', key='full text', font='Helvetica 15'), sg.T('Command History', font='Helvetica 15'), sg.T('', size=(40,3), text_color=sg.BLUES[0], key='history')], [sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False), - sg.ReadFormButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), - sg.SimpleButton('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))] + sg.ReadButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), + sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))] ] - form = sg.FlexForm('How Do I ??', default_element_size=(30, 2), icon=DEFAULT_ICON, font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True, no_titlebar=True) - form.Layout(layout) + window = sg.Window('How Do I ??', default_element_size=(30, 2), icon=DEFAULT_ICON, font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True, no_titlebar=True) + window.Layout(layout) # ---===--- Loop taking in user input and using it to query HowDoI --- # command_history = [] history_offset = 0 while True: - (button, value) = form.Read() + (button, value) = window.Read() if button is 'SEND': query = value['query'].rstrip() print(query) QueryHowDoI(query, value['Num Answers'], value['full text']) # send the string to HowDoI command_history.append(query) history_offset = len(command_history)-1 - form.FindElement('query').Update('') # manually clear input because keyboard events blocks clear - form.FindElement('history').Update('\n'.join(command_history[-3:])) + window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear + window.FindElement('history').Update('\n'.join(command_history[-3:])) elif button is None or button is 'EXIT': # if exit button or closed using X break elif 'Up' in button and len(command_history): # scroll back in history command = command_history[history_offset] history_offset -= 1 * (history_offset > 0) # decrement is not zero - form.FindElement('query').Update(command) + window.FindElement('query').Update(command) elif 'Down' in button and len(command_history): # scroll forward in history history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list command = command_history[history_offset] - form.FindElement('query').Update(command) + window.FindElement('query').Update(command) elif 'Escape' in button: # clear currently line - form.FindElement('query').Update('') + window.FindElement('query').Update('') - exit(69) def QueryHowDoI(Query, num_answers, full_text): ''' diff --git a/Demo_Img_Viewer.py b/Demo_Img_Viewer.py index df075f69..0b257e55 100644 --- a/Demo_Img_Viewer.py +++ b/Demo_Img_Viewer.py @@ -57,7 +57,7 @@ def get_img_data(f, maxsize = (1200, 850), first = False): # create the form that also returns keyboard events -form = sg.FlexForm('Image Browser', return_keyboard_events=True, +window = sg.Window('Image Browser', return_keyboard_events=True, location=(0, 0), use_default_focus=False) # make these 2 elements outside the layout as we want to "update" them later @@ -72,18 +72,18 @@ col = [[filename_display_elem], [image_elem]] col_files = [[sg.Listbox(values = fnames, change_submits=True, size=(60, 30), key='listbox')], - [sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', + [sg.ReadButton('Next', size=(8,2)), sg.ReadButton('Prev', size=(8,2)), file_num_display_elem]] layout = [[sg.Column(col_files), sg.Column(col)]] -form.Layout(layout) # Shows form on screen +window.Layout(layout) # Shows form on screen # loop reading the user input and displaying image, filename i=0 while True: # read the form - button, values = form.Read() + button, values = window.Read() # perform button and keyboard operations if button is None: diff --git a/Demo_Keyboard.py b/Demo_Keyboard.py index 9bbde27d..e413ac4f 100644 --- a/Demo_Keyboard.py +++ b/Demo_Keyboard.py @@ -3,22 +3,22 @@ import PySimpleGUI as sg # Recipe for getting keys, one at a time as they are released # If want to use the space bar, then be sure and disable the "default focus" -with sg.FlexForm("Keyboard Test", return_keyboard_events=True, use_default_focus=False) as form: - layout = [[sg.Text("Press a key or scroll mouse")], - [sg.Text("", size=(18,1), key='text')], - [sg.SimpleButton("OK", key='OK')]] +layout = [[sg.Text("Press a key or scroll mouse")], + [sg.Text("", size=(18,1), key='text')], + [sg.Button("OK", key='OK')]] - form.Layout(layout) - # ---===--- Loop taking in user input --- # - while True: - button, value = form.Read() - text_elem = form.FindElement('text') - if button in ("OK", None): - print(button, "exiting") - break - if len(button) == 1: - text_elem.Update(value='%s - %s' % (button, ord(button))) - if button is not None: - text_elem.Update(button) +window = sg.Window("Keyboard Test", return_keyboard_events=True, use_default_focus=False).Layout(layout) + +# ---===--- Loop taking in user input --- # +while True: + button, value = window.Read() + text_elem = window.FindElement('text') + if button in ("OK", None): + print(button, "exiting") + break + if len(button) == 1: + text_elem.Update(value='%s - %s' % (button, ord(button))) + if button is not None: + text_elem.Update(button) diff --git a/Demo_Keyboard_Realtime.py b/Demo_Keyboard_Realtime.py index ab48ce73..ff94f29e 100644 --- a/Demo_Keyboard_Realtime.py +++ b/Demo_Keyboard_Realtime.py @@ -1,21 +1,20 @@ import PySimpleGUI as sg -with sg.FlexForm("Realtime Keyboard Test", return_keyboard_events=True, use_default_focus=False) as form: - layout = [[sg.Text("Hold down a key")], - [sg.SimpleButton("OK")]] +layout = [[sg.Text("Hold down a key")], + [sg.Button("OK")]] - form.Layout(layout) +window = sg.Window("Realtime Keyboard Test", return_keyboard_events=True, use_default_focus=False).Layout(layout) - while True: - button, value = form.ReadNonBlocking() +while True: + button, value = window.ReadNonBlocking() - if button == "OK": - print(button, value, "exiting") - break - if button is not None: - if len(button) == 1: - print('%s - %s'%(button, ord(button))) - else: - print(button) - elif value is None: - break + if button == "OK": + print(button, value, "exiting") + break + if button is not None: + if len(button) == 1: + print('%s - %s'%(button, ord(button))) + else: + print(button) + elif value is None: + break diff --git a/Demo_Keypad.py b/Demo_Keypad.py index 501e9d4b..d51f32f5 100644 --- a/Demo_Keypad.py +++ b/Demo_Keypad.py @@ -1,43 +1,39 @@ import PySimpleGUI as sg -# g.SetOptions(button_color=g.COLOR_SYSTEM_DEFAULT) # because some people like gray buttons - # Demonstrates a number of PySimpleGUI features including: # Default element size # auto_size_buttons -# ReadFormButton +# ReadButton # Dictionary return values # Update of elements in form (Text, Input) # do_not_clear of Input elements -# create the 2 Elements we want to control outside the form layout = [[sg.Text('Enter Your Passcode')], [sg.Input(size=(10, 1), do_not_clear=True, key='input')], - [sg.ReadFormButton('1'), sg.ReadFormButton('2'), sg.ReadFormButton('3')], - [sg.ReadFormButton('4'), sg.ReadFormButton('5'), sg.ReadFormButton('6')], - [sg.ReadFormButton('7'), sg.ReadFormButton('8'), sg.ReadFormButton('9')], - [sg.ReadFormButton('Submit'), sg.ReadFormButton('0'), sg.ReadFormButton('Clear')], + [sg.ReadButton('1'), sg.ReadButton('2'), sg.ReadButton('3')], + [sg.ReadButton('4'), sg.ReadButton('5'), sg.ReadButton('6')], + [sg.ReadButton('7'), sg.ReadButton('8'), sg.ReadButton('9')], + [sg.ReadButton('Submit'), sg.ReadButton('0'), sg.ReadButton('Clear')], [sg.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='out')], ] -form = sg.FlexForm('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False, grab_anywhere=False) -form.Layout(layout) +window = sg.Window('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False, grab_anywhere=False).Layout(layout) # Loop forever reading the form's values, updating the Input field keys_entered = '' while True: - button, values = form.Read() # read the form + button, values = window.Read() # read the form if button is None: # if the X button clicked, just exit break - if button is 'Clear': # clear keys if clear button + if button == 'Clear': # clear keys if clear button keys_entered = '' elif button in '1234567890': - keys_entered = values['input'] # get what's been entered so far + keys_entere=d = values['input'] # get what's been entered so far keys_entered += button # add the new digit - elif button is 'Submit': + elif button == 'Submit': keys_entered = values['input'] - form.FindElement('out').Update(keys_entered) # output the final string + window.FindElement('out').Update(keys_entered) # output the final string - form.FindElement('input').Update(keys_entered) # change the form to reflect current key string \ No newline at end of file + window.FindElement('input').Update(keys_entered) # change the form to reflect current key string \ No newline at end of file diff --git a/Demo_MIDI_Player.py b/Demo_MIDI_Player.py index 3e4e5008..87131a1f 100644 --- a/Demo_MIDI_Player.py +++ b/Demo_MIDI_Player.py @@ -2,6 +2,7 @@ import os import PySimpleGUI as g import mido import time +import sys PLAYER_COMMAND_NONE = 0 PLAYER_COMMAND_EXIT = 1 @@ -18,7 +19,7 @@ class PlayerGUI(): ''' def __init__(self): - self.Form = None + self.Window = None self.TextElem = None self.PortList = mido.get_output_names() # use to get the list of midi ports self.PortList = self.PortList[::-1] # reverse the list so the last one is first @@ -30,10 +31,8 @@ class PlayerGUI(): def PlayerChooseSongGUI(self): # ---------------------- DEFINION OF CHOOSE WHAT TO PLAY GUI ---------------------------- - with g.FlexForm('MIDI File Player', auto_size_text=False, - default_element_size=(30, 1), - font=("Helvetica", 12)) as form: - layout = [[g.Text('MIDI File Player', font=("Helvetica", 15), size=(20, 1), text_color='green')], + + layout = [[g.Text('MIDI File Player', font=("Helvetica", 15), size=(20, 1), text_color='green')], [g.Text('File Selection', font=("Helvetica", 15), size=(20, 1))], [g.Text('Single File Playback', justification='right'), g.InputText(size=(65, 1), key='midifile'), g.FileBrowse(size=(10, 1), file_types=(("MIDI files", "*.mid"),))], [g.Text('Or Batch Play From This Folder', auto_size_text=False, justification='right'), g.InputText(size=(65, 1), key='folder'), g.FolderBrowse(size=(10, 1))], @@ -43,9 +42,9 @@ class PlayerGUI(): [g.Text('_' * 250, auto_size_text=False, size=(100, 1))], [g.SimpleButton('PLAY', size=(12, 2), button_color=('red', 'white'), font=("Helvetica", 15), bind_return_key=True), g.Text(' ' * 2, size=(4, 1)), g.Cancel(size=(8, 2), font=("Helvetica", 15))]] - - self.Form = form - return form.LayoutAndRead(layout) + window = g.Window('MIDI File Player', auto_size_text=False, default_element_size=(30, 1), font=("Helvetica", 12)).Layout(layout) + self.Window = window + return window.Read() def PlayerPlaybackGUIStart(self, NumFiles=1): @@ -58,7 +57,6 @@ class PlayerGUI(): self.TextElem = g.T('Song loading....', size=(70,5 + NumFiles), font=("Helvetica", 14), auto_size_text=False) self.SliderElem = g.Slider(range=(1,100), size=(50, 8), orientation='h', text_color='#f0f0f0') - form = g.FlexForm('MIDI File Player', default_element_size=(30,1),font=("Helvetica", 25)) layout = [ [g.T('MIDI File Player', size=(30,1), font=("Helvetica", 25))], [self.TextElem], @@ -73,8 +71,8 @@ class PlayerGUI(): image_filename=image_exit, image_size=(50,50), image_subsample=2, border_width=0,)] ] - form.LayoutAndRead(layout, non_blocking=True) - self.Form = form + window = g.FlexForm('MIDI File Player', default_element_size=(30,1),font=("Helvetica", 25)).Layout(layout).Finalize() + self.Window = window @@ -83,11 +81,11 @@ class PlayerGUI(): # Refresh the GUI for the main playback interface (must call periodically # # ------------------------------------------------------------------------- # def PlayerPlaybackGUIUpdate(self, DisplayString): - form = self.Form - if 'form' not in locals() or form is None: # if the form has been destoyed don't mess with it + window = self.Window + if 'window' not in locals() or window is None: # if the form has been destoyed don't mess with it return PLAYER_COMMAND_EXIT self.TextElem.Update(DisplayString) - button, (values) = form.ReadNonBlocking() + button, (values) = window.ReadNonBlocking() if values is None: return PLAYER_COMMAND_EXIT if button == 'PAUSE': @@ -121,7 +119,7 @@ def main(): button, values = pback.PlayerChooseSongGUI() if button != 'PLAY': g.PopupCancel('Cancelled...\nAutoclose in 2 sec...', auto_close=True, auto_close_duration=2) - exit(69) + sys.exit(69) if values['device']: midi_port = values['device'][0] else: @@ -139,7 +137,7 @@ def main(): filetitles = [os.path.basename(midi_filename),] else: g.PopupError('*** Error - No MIDI files specified ***') - exit(666) + sys.exit(666) # ------ LOOP THROUGH MULTIPLE FILES --------------------------------------------------------- # pback.PlayerPlaybackGUIStart(NumFiles=len(filelist) if len(filelist) <=10 else 10) @@ -215,7 +213,6 @@ def main(): if cancelled: break - exit(69) # ---------------------------------------------------------------------- # # LAUNCH POINT -- program starts and ends here # @@ -223,4 +220,3 @@ def main(): if __name__ == '__main__': main() - exit(69) diff --git a/Demo_Machine_Learning.py b/Demo_Machine_Learning.py index cc26952f..4b7e7265 100644 --- a/Demo_Machine_Learning.py +++ b/Demo_Machine_Learning.py @@ -29,38 +29,32 @@ def MachineLearningGUI(): [sg.Frame('Loss Functions', loss_functions, font='Any 12', title_color='red')], [sg.Submit(), sg.Cancel()]] - - form = sg.FlexForm('Machine Learning Front End', font=("Helvetica", 12)) - button, values = form.LayoutAndRead(layout) - del(form) + window = sg.Window('Machine Learning Front End', font=("Helvetica", 12)).Layout(layout) + button, values = window.Read() sg.SetOptions(text_justification='left') print(button, values) - def CustomMeter(): - # create the progress bar element - progress_bar = sg.ProgressBar(10000, orientation='h', size=(20,20)) # layout the form layout = [[sg.Text('A custom progress meter')], - [progress_bar], + [sg.ProgressBar(10000, orientation='h', size=(20,20), key='progress')], [sg.Cancel()]] # create the form` - form = sg.FlexForm('Custom Progress Meter') - # display the form as a non-blocking form - form.LayoutAndRead(layout, non_blocking=True) + window = sg.Window('Custom Progress Meter').Layout(layout) + progress_bar = window.FindElement('progress') # loop that would normally do something useful for i in range(10000): # check to see if the cancel button was clicked and exit loop if clicked - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button == 'Cancel' or values == None: break # update bar with loop value +1 so that bar eventually reaches the maximum progress_bar.UpdateBar(i+1) # done with loop... need to destroy the window as it's still open - form.CloseNonBlockingForm() + window.CloseNonBlocking() if __name__ == '__main__': - # CustomMeter() + CustomMeter() MachineLearningGUI() diff --git a/Demo_Matplotlib.py b/Demo_Matplotlib.py index 7b2553f7..e7cbb863 100644 --- a/Demo_Matplotlib.py +++ b/Demo_Matplotlib.py @@ -113,10 +113,10 @@ layout = [[sg.Text('Plot test')], [sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]] # create the form and show it without the plot -form = sg.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize() +window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize() # add the plot to the window -fig_photo = draw_figure(form.FindElement('canvas').TKCanvas, fig) +fig_photo = draw_figure(window.FindElement('canvas').TKCanvas, fig) # show it all again and get buttons -button, values = form.Read() +button, values = window.Read() diff --git a/Demo_Matplotlib_Animated.py b/Demo_Matplotlib_Animated.py index da813c47..e3b33b75 100644 --- a/Demo_Matplotlib_Animated.py +++ b/Demo_Matplotlib_Animated.py @@ -14,25 +14,23 @@ def main(): ax.set_ylabel("Y axis") ax.grid() - canvas_elem = sg.Canvas(size=(640, 480)) # get the canvas we'll be drawing on - slider_elem = sg.Slider(range=(0, 10000), size=(60, 10), orientation='h') # define the form layout layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')], - [canvas_elem], - [slider_elem], - [sg.ReadFormButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] + [sg.Canvas(size=(640, 480), key='canvas')], + [sg.Slider(range=(0, 10000), size=(60, 10), orientation='h', key='slider')], + [sg.ReadButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] # create the form and show it without the plot - form = sg.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI') - form.Layout(layout) - form.Finalize() + window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize() + canvas_elem = window.FindElement('canvas') + slider_elem = window.FindElement('slider') graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas) canvas = canvas_elem.TKCanvas dpts = [randint(0, 10) for x in range(10000)] for i in range(len(dpts)): - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is 'Exit' or values is None: exit(69) diff --git a/Demo_Matplotlib_Animated_Scatter.py b/Demo_Matplotlib_Animated_Scatter.py index 0005d681..26c2c7fc 100644 --- a/Demo_Matplotlib_Animated_Scatter.py +++ b/Demo_Matplotlib_Animated_Scatter.py @@ -7,21 +7,19 @@ import tkinter as tk def main(): - canvas_elem = sg.Canvas(size=(640, 480)) # get the canvas we'll be drawing on # define the form layout layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')], - [canvas_elem], - [sg.ReadFormButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] + [sg.Canvas(size=(640, 480), key='canvas')], + [sg.ReadButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] # create the form and show it without the plot - form = sg.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI') - form.Layout(layout) - form.Finalize() + window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize() + canvas_elem = window.FindElement('canvas') canvas = canvas_elem.TKCanvas while True: - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is 'Exit' or values is None: exit(69) diff --git a/Demo_Matplotlib_Browser.py b/Demo_Matplotlib_Browser.py index 5ab902a4..a7c6ab5e 100644 --- a/Demo_Matplotlib_Browser.py +++ b/Demo_Matplotlib_Browser.py @@ -247,7 +247,7 @@ def PyplotLineStyles(): # For each line style, add a text annotation with a small offset from # the reference point (0 in Axes coords, y tick value in Data coords). - reference_transform = blended_transform_factory(ax.transAxes, ax.transData) + reference_transwindow = blended_transform_factory(ax.transAxes, ax.transData) for i, (name, linestyle) in enumerate(linestyles.items()): ax.annotate(str(linestyle), xy=(0.0, i), xycoords=reference_transform, xytext=(-6, -12), textcoords='offset points', color="blue", @@ -864,23 +864,24 @@ fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'Py sg.ChangeLookAndFeel('LightGreen') figure_w, figure_h = 650, 650 -canvas_elem = sg.Canvas(size=(figure_w, figure_h)) # get the canvas we'll be drawing on -multiline_elem = sg.Multiline(size=(70, 35), pad=(5, (3, 90))) # define the form layout listbox_values = [key for key in fig_dict.keys()] col_listbox = [[sg.Listbox(values=listbox_values, change_submits=True, size=(28, len(listbox_values)), key='func')], [sg.T(' ' * 12), sg.Exit(size=(5, 2))]] layout = [[sg.Text('Matplotlib Plot Test', font=('current 18'))], - [sg.Column(col_listbox, pad=(5, (3, 330))), canvas_elem, multiline_elem], - ] + [sg.Column(col_listbox, pad=(5, (3, 330))), sg.Canvas(size=(figure_w, figure_h), key='canvas') , + sg.Multiline(size=(70, 35), pad=(5, (3, 90)), key='multiline')],] # create the form and show it without the plot -form = sg.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI', grab_anywhere=False) -form.Layout(layout) +window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', grab_anywhere=False).Layout(layout) +window.Finalize() + +canvas_elem = window.FindElement('canvas') +multiline_elem= window.FindElement('multiline') while True: - button, values = form.Read() + button, values = window.Read() print(button) # show it all again and get buttons if button is None or button is 'Exit': @@ -891,7 +892,6 @@ while True: func = fig_dict[choice] except: pass - # func = fig_dict['Pyplot Simple'] multiline_elem.Update(inspect.getsource(func)) plt.clf() diff --git a/Demo_Matplotlib_Ping_Graph.py b/Demo_Matplotlib_Ping_Graph.py index 39111a98..a302d53c 100644 --- a/Demo_Matplotlib_Ping_Graph.py +++ b/Demo_Matplotlib_Ping_Graph.py @@ -640,15 +640,13 @@ def draw(fig, canvas): def main(): global g_my_globals - canvas_elem = sg.Canvas(size=SIZE, background_color='white') # get the canvas we'll be drawing on # define the form layout - layout = [[canvas_elem, sg.ReadFormButton('Exit', pad=(0, (210, 0)))]] + layout = [[ sg.Canvas(size=SIZE, background_color='white',key='canvas') , sg.ReadButton('Exit', pad=(0, (210, 0)))]] # create the form and show it without the plot - form = sg.FlexForm('Ping Graph', background_color='white', grab_anywhere=True) - form.Layout(layout) - form.Finalize() + window = sg.Window('Ping Graph', background_color='white', grab_anywhere=True).Layout(layout).Finalize() + canvas_elem = window.FindElement('canvas') canvas = canvas_elem.TKCanvas fig = plt.figure(figsize=(3.1, 2.25), tight_layout={'pad':0}) @@ -659,7 +657,7 @@ def main(): plt.tight_layout() while True: - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is 'Exit' or values is None: exit(0) diff --git a/Demo_Matplotlib_Ping_Graph_Large.py b/Demo_Matplotlib_Ping_Graph_Large.py index 23bb678f..38032997 100644 --- a/Demo_Matplotlib_Ping_Graph_Large.py +++ b/Demo_Matplotlib_Ping_Graph_Large.py @@ -74,17 +74,15 @@ def draw(fig, canvas): def main(): global g_my_globals - canvas_elem = sg.Canvas(size=(640, 480)) # get the canvas we'll be drawing on # define the form layout layout = [[sg.Text('Animated Ping', size=(40, 1), justification='center', font='Helvetica 20')], - [canvas_elem], - [sg.ReadFormButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] + [sg.Canvas(size=(640, 480), key='canvas')], + [sg.ReadButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]] # create the form and show it without the plot - form = sg.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI') - form.Layout(layout) - form.Finalize() + window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize() + canvas_elem = window.FindElement('canvas') canvas = canvas_elem.TKCanvas fig = plt.figure() @@ -93,7 +91,7 @@ def main(): plt.tight_layout() while True: - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is 'Exit' or values is None: break diff --git a/Demo_Media_Player.py b/Demo_Media_Player.py index b1128f3e..aef039f6 100644 --- a/Demo_Media_Player.py +++ b/Demo_Media_Player.py @@ -18,22 +18,20 @@ def MediaPlayerGUI(): # A text element that will be changed to display messages in the GUI - # Open a form, note that context manager can't be used generally speaking for async forms - form = sg.FlexForm('Media File Player', auto_size_text=True, default_element_size=(20, 1), - font=("Helvetica", 25), no_titlebar=True) + # define layout of the rows layout= [[sg.Text('Media File Player',size=(17,1), font=("Helvetica", 25))], [sg.Text('', size=(15, 2), font=("Helvetica", 14), key='output')], - [sg.ReadFormButton('Restart Song', button_color=(background,background), + [sg.ReadButton('Restart Song', button_color=(background,background), image_filename=image_restart, image_size=(50, 50), image_subsample=2, border_width=0), sg.Text(' ' * 2), - sg.ReadFormButton('Pause', button_color=(background,background), + sg.ReadButton('Pause', button_color=(background,background), image_filename=image_pause, image_size=(50, 50), image_subsample=2, border_width=0), sg.Text(' ' * 2), - sg.ReadFormButton('Next', button_color=(background,background), + sg.ReadButton('Next', button_color=(background,background), image_filename=image_next, image_size=(50, 50), image_subsample=2, border_width=0), sg.Text(' ' * 2), - sg.Text(' ' * 2), sg.SimpleButton('Exit', button_color=(background,background), + sg.Text(' ' * 2), sg.Button('Exit', button_color=(background,background), image_filename=image_exit, image_size=(50, 50), image_subsample=2, border_width=0)], [sg.Text('_'*20)], [sg.Text(' '*30)], @@ -46,20 +44,20 @@ def MediaPlayerGUI(): [sg.Text(' Bass', font=("Helvetica", 15), size=(9, 1)), sg.Text('Treble', font=("Helvetica", 15), size=(7, 1)), sg.Text('Volume', font=("Helvetica", 15), size=(7, 1))] - ] - # Call the same LayoutAndRead but indicate the form is non-blocking - form.LayoutAndRead(layout, non_blocking=True) + # Open a form, note that context manager can't be used generally speaking for async forms + window = sg.Window('Media File Player', auto_size_text=True, default_element_size=(20, 1), + font=("Helvetica", 25), no_titlebar=True).Layout(layout) # Our event loop while(True): # Read the form (this call will not block) - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button == 'Exit': break # If a button was pressed, display it on the GUI by updating the text element if button: - form.FindElement('output').Update(button) + window.FindElement('output').Update(button) MediaPlayerGUI() diff --git a/Demo_Menus.py b/Demo_Menus.py index 8462881f..fe4634b0 100644 --- a/Demo_Menus.py +++ b/Demo_Menus.py @@ -11,8 +11,8 @@ def SecondForm(): layout = [[sg.Text('The second form is small \nHere to show that opening a window using a window works')], [sg.OK()]] - form = sg.FlexForm('Second Form') - b, v = form.LayoutAndRead(layout) + window = sg.Window('Second Form').Layout(layout) + b, v = window.Read() def TestMenus(): @@ -33,13 +33,12 @@ def TestMenus(): [sg.In('Test', key='input', do_not_clear=True)] ] - form = sg.FlexForm("Windows-like program", default_element_size=(12, 1), auto_size_text=False, auto_size_buttons=False, - default_button_element_size=(12, 1)) - form.Layout(layout) + window = sg.Window("Windows-like program", default_element_size=(12, 1), auto_size_text=False, auto_size_buttons=False, + default_button_element_size=(12, 1)).Layout(layout) # ------ Loop & Process button menu choices ------ # while True: - button, values = form.Read() + button, values = window.Read() if button is None or button == 'Exit': return print('Button = ', button) diff --git a/Demo_NonBlocking_Form.py b/Demo_NonBlocking_Form.py index b08b85c2..667b43e5 100644 --- a/Demo_NonBlocking_Form.py +++ b/Demo_NonBlocking_Form.py @@ -1,31 +1,28 @@ import PySimpleGUI as sg import time - -# form that doen't block +# Window that doen't block # good for applications with an loop that polls hardware def StatusOutputExample(): - # Make a form, but don't use context manager - form = sg.FlexForm('Running Timer', auto_size_text=True) # Create a text element that will be updated with status information on the GUI itself # Create the rows - form_rows = [[sg.Text('Non-blocking GUI with updates')], + layout = [[sg.Text('Non-blocking GUI with updates')], [sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='output')], - [sg.ReadFormButton('LED On'), sg.ReadFormButton('LED Off'), sg.ReadFormButton('Quit')]] - # Layout the rows of the form and perform a read. Indicate the form is non-blocking! - form.LayoutAndRead(form_rows, non_blocking=True) + [sg.ReadButton('LED On'), sg.ReadButton('LED Off'), sg.ReadButton('Quit')]] + # Layout the rows of the Window and perform a read. Indicate the Window is non-blocking! + window = sg.Window('Running Timer', auto_size_text=True).Layout(layout) # # Some place later in your code... - # You need to perform a ReadNonBlocking on your form every now and then or + # You need to perform a ReadNonBlocking on your window every now and then or # else it won't refresh. # # your program's main loop i=0 while (True): # This is the code that reads and updates your window - form.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() + window.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) if button == 'Quit' or values is None: break if button == 'LED On': @@ -38,14 +35,12 @@ def StatusOutputExample(): time.sleep(.01) # Broke out of main loop. Close the window. - form.CloseNonBlockingForm() + window.CloseNonBlocking() def RemoteControlExample(): - # Make a form, but don't use context manager - form = sg.FlexForm('Robotics Remote Control', auto_size_text=True) - form_rows = [[sg.Text('Robotics Remote Control')], + layout = [[sg.Text('Robotics Remote Control')], [sg.T(' '*10), sg.RealtimeButton('Forward')], [ sg.RealtimeButton('Left'), sg.T(' '*15), sg.RealtimeButton('Right')], [sg.T(' '*10), sg.RealtimeButton('Reverse')], @@ -53,55 +48,30 @@ def RemoteControlExample(): [sg.Quit(button_color=('black', 'orange'))] ] - form.LayoutAndRead(form_rows, non_blocking=True) + window = sg.Window('Robotics Remote Control', auto_size_text=True).Layout(layout).Finalize() # # Some place later in your code... - # You need to perform a ReadNonBlocking on your form every now and then or + # You need to perform a ReadNonBlocking on your window every now and then or # else it won't refresh. # # your program's main loop while (True): # This is the code that reads and updates your window - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is not None: print(button) if button == 'Quit' or values is None: break # time.sleep(.01) - form.CloseNonBlockingForm() + window.CloseNonBlocking() - - -# This design pattern follows the uses a context manager to better control the resources -# It may not be realistic to use a context manager within an embedded (Pi) environment -# If on a Pi, then consider the above design patterns instead -def StatusOutputExample_context_manager(): - with sg.FlexForm('Running Timer', auto_size_text=True) as form: - output_element = sg.Text('', size=(8, 2), font=('Helvetica', 20)) - form_rows = [[sg.Text('Non-blocking GUI with updates')], - [output_element], - [sg.SimpleButton('Quit')]] - - form.LayoutAndRead(form_rows, non_blocking=True) - - for i in range(1, 1000): - output_element.Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) - button, values = form.ReadNonBlocking() - if values is None or button == 'Quit': - break - time.sleep(.01) - else: - form.CloseNonBlockingForm() - def main(): RemoteControlExample() StatusOutputExample() - StatusOutputExample() sg.Popup('End of non-blocking demonstration') - # StatusOutputExample_context_manager() if __name__ == '__main__': diff --git a/Demo_OpenCV.py b/Demo_OpenCV.py index 2c8feb7b..078eff13 100644 --- a/Demo_OpenCV.py +++ b/Demo_OpenCV.py @@ -3,6 +3,7 @@ from PIL import Image import tempfile import PySimpleGUI as sg import os +from sys import exit as exit """ Demo program to open and play a file using OpenCV @@ -14,8 +15,8 @@ Until then enjoy it working somewhat slowly. def main(): - filename = 'C:/Python/MIDIVideo/PlainVideos/- 08-30 Ted Talk/TED Talk Short - Video+.mp4' - # filename = sg.PopupGetFile('Filename to play') + # filename = 'C:/Python/MIDIVideo/PlainVideos/- 08-30 Ted Talk/TED Talk Short - Video+.mp4' + filename = sg.PopupGetFile('Filename to play') if filename is None: exit(69) vidFile = cv.VideoCapture(filename) @@ -25,23 +26,23 @@ def main(): sg.ChangeLookAndFeel('Dark') - # define the form layout + # define the window layout layout = [[sg.Text('OpenCV Demo', size=(15, 1),pad=((510,0),3), justification='center', font='Helvetica 20')], [sg.Image(filename='', key='image')], [sg.Slider(range=(0, num_frames), size=(115, 10), orientation='h', key='slider')], - [sg.ReadFormButton('Exit', size=(10, 2), pad=((600, 0), 3), font='Helvetica 14')]] + [sg.ReadButton('Exit', size=(10, 2), pad=((600, 0), 3), font='Helvetica 14')]] - # create the form and show it without the plot - form = sg.FlexForm('Demo Application - OpenCV Integration', no_titlebar=False, location=(0,0)) - form.Layout(layout) - form.ReadNonBlocking() + # create the window and show it without the plot + window = sg.Window('Demo Application - OpenCV Integration', no_titlebar=False, location=(0,0)) + window.Layout(layout) + window.ReadNonBlocking() # ---===--- LOOP through video file by frame --- # i = 0 temp_filename = next(tempfile._get_candidate_names()) + '.png' while vidFile.isOpened(): - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is 'Exit' or values is None: os.remove(temp_filename) exit(69) @@ -49,12 +50,12 @@ def main(): if not ret: # if out of data stop looping break - form.FindElement('slider').Update(i) + window.FindElement('slider').Update(i) i += 1 with open(temp_filename, 'wb') as f: Image.fromarray(frame).save(temp_filename, 'PNG') # save the PIL image as file - form.FindElement('image').Update(filename=temp_filename) + window.FindElement('image').Update(filename=temp_filename) main() \ No newline at end of file diff --git a/Demo_PDF_Viewer.py b/Demo_PDF_Viewer.py index 32889695..96e55fd0 100644 --- a/Demo_PDF_Viewer.py +++ b/Demo_PDF_Viewer.py @@ -24,7 +24,7 @@ into the four page quadrants (top-left, bottom-right, etc.). We also interpret keyboard events to support paging by PageDown / PageUp keys as if the resp. buttons were clicked. Similarly, we do not include -a 'Quit' button. Instead, the ESCAPE key can be used, or cancelling the form. +a 'Quit' button. Instead, the ESCAPE key can be used, or cancelling the window. To improve paging performance, we are not directly creating pixmaps from pages, but instead from the fitz.DisplayList of the page. A display list @@ -35,6 +35,7 @@ pixmaps and page re-visits will re-use a once-created display list. import sys import fitz import PySimpleGUI as sg +from sys import exit as exit from binascii import hexlify sg.ChangeLookAndFeel('GreenTan') @@ -86,7 +87,7 @@ def get_page(pno, zoom=0): return pix.getPNGData() # return the PNG image -form = sg.FlexForm(title, return_keyboard_events=True, use_default_focus=False) +window = sg.Window(title, return_keyboard_events=True, use_default_focus=False) cur_page = 0 data = get_page(cur_page) # show page 1 for start @@ -95,22 +96,22 @@ goto = sg.InputText(str(cur_page + 1), size=(5, 1), do_not_clear=True) layout = [ [ - sg.ReadFormButton('Next'), - sg.ReadFormButton('Prev'), + sg.ReadButton('Next'), + sg.ReadButton('Prev'), sg.Text('Page:'), goto, ], [ sg.Text("Zoom:"), - sg.ReadFormButton('Top-L'), - sg.ReadFormButton('Top-R'), - sg.ReadFormButton('Bot-L'), - sg.ReadFormButton('Bot-R'), + sg.ReadButton('Top-L'), + sg.ReadButton('Top-R'), + sg.ReadButton('Bot-L'), + sg.ReadButton('Bot-R'), ], [image_elem], ] -form.Layout(layout) +window.Layout(layout) my_keys = ("Next", "Next:34", "Prev", "Prior:33", "Top-L", "Top-R", "Bot-L", "Bot-R", "MouseWheel:Down", "MouseWheel:Up") zoom_buttons = ("Top-L", "Top-R", "Bot-L", "Bot-R") @@ -120,7 +121,7 @@ old_zoom = 0 # used for zoom on/off # the zoom buttons work in on/off mode. while True: - button, value = form.ReadNonBlocking() + button, value = window.ReadNonBlocking() zoom = 0 force_page = False if button is None and value is None: diff --git a/Demo_PNG_Viewer.py b/Demo_PNG_Viewer.py index 1af28f72..d90bb9b7 100644 --- a/Demo_PNG_Viewer.py +++ b/Demo_PNG_Viewer.py @@ -1,5 +1,6 @@ import PySimpleGUI as sg import os +from sys import exit as exit # Simple Image Browser based on PySimpleGUI @@ -20,24 +21,23 @@ if len(png_files) == 0: # define menu layout menu = [['File', ['Open Folder', 'Exit']], ['Help', ['About',]]] -# create the form that also returns keyboard events -form = sg.FlexForm('Image Browser', return_keyboard_events=True, location=(0,0), use_default_focus=False ) -# define layout, show and read the form +# define layout, show and read the window col = [[sg.Text(png_files[0], size=(80, 3), key='filename')], [sg.Image(filename=png_files[0], key='image')], - [sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2)), + [sg.ReadButton('Next', size=(8,2)), sg.ReadButton('Prev', size=(8,2)), sg.Text('File 1 of {}'.format(len(png_files)), size=(15,1), key='filenum')]] col_files = [[sg.Listbox(values=filenames_only, size=(60,30), key='listbox')], - [sg.ReadFormButton('Read')]] + [sg.ReadButton('Read')]] layout = [[sg.Menu(menu)], [sg.Column(col_files), sg.Column(col)]] -button, values = form.LayoutAndRead(layout) # Shows form on screen +window = sg.Window('Image Browser', return_keyboard_events=True, location=(0,0), use_default_focus=False ).Layout(layout) # loop reading the user input and displaying image, filename i=0 while True: + button, values = window.Read() # --------------------- Button & Keyboard --------------------- if button is None: break @@ -58,18 +58,16 @@ while True: folder = newfolder png_files = [folder + '/' + f for f in os.listdir(folder) if '.png' in f] filenames_only = [f for f in os.listdir(folder) if '.png' in f] - form.FindElement('listbox').Update(values=filenames_only) - form.Refresh() + window.FindElement('listbox').Update(values=filenames_only) + window.Refresh() i = 0 elif button == 'About': sg.Popup('Demo PNG Viewer Program', 'Please give PySimpleGUI a try!') # update window with new image - form.FindElement('image').Update(filename=filename) + window.FindElement('image').Update(filename=filename) # update window with filename - form.FindElement('filename').Update(filename) + window.FindElement('filename').Update(filename) # update page display - form.FindElement('filenum').Update('File {} of {}'.format(i+1, len(png_files))) + window.FindElement('filenum').Update('File {} of {}'.format(i+1, len(png_files))) - # read the form - button, values = form.Read() diff --git a/Demo_Password_Login.py b/Demo_Password_Login.py index be3e764a..84662b24 100644 --- a/Demo_Password_Login.py +++ b/Demo_Password_Login.py @@ -1,5 +1,6 @@ import PySimpleGUI as sg import hashlib +from sys import exit as exit """ Create a secure login for your scripts without having to include your password @@ -7,7 +8,7 @@ import hashlib 1. Choose a password 2. Generate a hash code for your chosen password by running program and entering 'gui' as the password 3. Type password into the GUI - 4. Copy and paste hash code form GUI into variable named login_password_hash + 4. Copy and paste hash code from GUI into variable named login_password_hash 5. Run program again and test your login! 6. Are you paying attention? The first person that can post an issue on GitHub with the matching password to the hash code in this example gets a $5 PayPal payment @@ -20,12 +21,11 @@ def HashGeneratorGUI(): [sg.T('SHA Hash'), sg.In('', size=(40,1), key='hash')], ] - form = sg.FlexForm('SHA Generator', auto_size_text=False, default_element_size=(10,1), - text_justification='r', return_keyboard_events=True, grab_anywhere=False) - form.Layout(layout) + window = sg.Window('SHA Generator', auto_size_text=False, default_element_size=(10,1), + text_justification='r', return_keyboard_events=True, grab_anywhere=False).Layout(layout) while True: - button, values = form.Read() + button, values = window.Read() if button is None: exit(69) @@ -35,7 +35,7 @@ def HashGeneratorGUI(): sha1hash = hashlib.sha1() sha1hash.update(password_utf) password_hash = sha1hash.hexdigest() - form.FindElement('hash').Update(password_hash) + window.FindElement('hash').Update(password_hash) except: pass diff --git a/Demo_Pi_LEDs.py b/Demo_Pi_LEDs.py index 6ec26c5e..68db1713 100644 --- a/Demo_Pi_LEDs.py +++ b/Demo_Pi_LEDs.py @@ -30,25 +30,23 @@ def FlashLED(): layout = [[rg.T('Raspberry Pi LEDs')], [rg.T('', size=(14, 1), key='output')], - [rg.ReadFormButton('Switch LED')], - [rg.ReadFormButton('Flash LED')], - [rg.Exit()] - ] + [rg.ReadButton('Switch LED')], + [rg.ReadButton('Flash LED')], + [rg.Exit()]] -form = rg.FlexForm('Raspberry Pi GUI', grab_anywhere=False) -form.Layout(layout) +window = rg.Window('Raspberry Pi GUI', grab_anywhere=False).Layout(layout) while True: - button, values = form.Read() + button, values = window.Read() if button is None: break if button is 'Switch LED': - form.FindElement('output').Update(SwitchLED()) + window.FindElement('output').Update(SwitchLED()) elif button is 'Flash LED': - form.FindElement('output').Update('LED is Flashing') - form.ReadNonBlocking() + window.FindElement('output').Update('LED is Flashing') + window.ReadNonBlocking() FlashLED() - form.FindElement('output').Update('') + window.FindElement('output').Update('') rg.Popup('Done... exiting') diff --git a/Demo_Pi_Robotics.py b/Demo_Pi_Robotics.py index e7efa24b..829f08be 100644 --- a/Demo_Pi_Robotics.py +++ b/Demo_Pi_Robotics.py @@ -17,18 +17,15 @@ def RemoteControlExample(): sg.SetOptions(border_width=0, button_color=('black', back), background_color=back, element_background_color=back, text_element_background_color=back) - form = sg.FlexForm('Robotics Remote Control', auto_size_text=True, grab_anywhere=False) - - form_rows = [[sg.Text('Robotics Remote Control')], + layout = [[sg.Text('Robotics Remote Control')], [sg.T('', justification='center', size=(19,1), key='status')], [ sg.RealtimeButton('Forward', image_filename=image_forward, pad=((50,0),0))], [ sg.RealtimeButton('Left', image_filename=image_left), sg.RealtimeButton('Right', image_filename=image_right, pad=((50,0), 0))], [ sg.RealtimeButton('Reverse', image_filename=image_backward, pad=((50,0),0))], [sg.T('')], - [sg.Quit(button_color=('black', 'orange'))] - ] + [sg.Quit(button_color=('black', 'orange'))]] - form.LayoutAndRead(form_rows, non_blocking=True) + window = sg.Window('Robotics Remote Control', auto_size_text=True, grab_anywhere=False).Layout(layout) # # Some place later in your code... @@ -38,32 +35,30 @@ def RemoteControlExample(): # your program's main loop while (True): # This is the code that reads and updates your window - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is not None: - form.FindElement('status').Update(button) + window.FindElement('status').Update(button) else: - form.FindElement('status').Update('') + window.FindElement('status').Update('') # if user clicked quit button OR closed the form using the X, then break out of loop if button == 'Quit' or values is None: break - form.CloseNonBlockingForm() + window.CloseNonBlocking() def RemoteControlExample_NoGraphics(): # Make a form, but don't use context manager - form = sg.FlexForm('Robotics Remote Control', auto_size_text=True, grab_anywhere=False) - form_rows = [[sg.Text('Robotics Remote Control', justification='center')], + layout = [[sg.Text('Robotics Remote Control', justification='center')], [sg.T('', justification='center', size=(19,1), key='status')], [sg.T(' '*8), sg.RealtimeButton('Forward')], [ sg.RealtimeButton('Left'), sg.T(' '), sg.RealtimeButton('Right')], [sg.T(' '*8), sg.RealtimeButton('Reverse')], [sg.T('')], - [sg.Quit(button_color=('black', 'orange'))] - ] + [sg.Quit(button_color=('black', 'orange'))]] # Display form to user - form.LayoutAndRead(form_rows, non_blocking=True) + window = sg.Window('Robotics Remote Control', auto_size_text=True, grab_anywhere=False).Layout(layout) # # Some place later in your code... @@ -73,16 +68,16 @@ def RemoteControlExample_NoGraphics(): # your program's main loop while (True): # This is the code that reads and updates your window - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button is not None: - form.FindElement('status').Update(button) + window.FindElement('status').Update(button) else: - form.FindElement('status').Update('') + window.FindElement('status').Update('') # if user clicked quit button OR closed the form using the X, then break out of loop if button == 'Quit' or values is None: break - form.CloseNonBlockingForm() + window.CloseNonBlocking() diff --git a/Demo_Ping_Line_Graph.py b/Demo_Ping_Line_Graph.py index ef6e2f4d..310089b1 100644 --- a/Demo_Ping_Line_Graph.py +++ b/Demo_Ping_Line_Graph.py @@ -1,6 +1,7 @@ from threading import Thread import time import PySimpleGUI as sg +from sys import exit as exit # !/usr/bin/env python3 # -*- coding: utf-8 -*- @@ -214,7 +215,7 @@ import os, sys, socket, struct, select, time, signal __description__ = 'A pure python ICMP ping implementation using raw sockets.' -if sys.platform == "win32": +if sys.platwindow == "win32": # On Windows, the best timer is time.clock() default_timer = time.clock else: @@ -619,12 +620,11 @@ thread.start() layout = [ [sg.T('Ping times to Google.com', font='Any 18')], [sg.Canvas(size=(canvas_right, canvas_bottom), background_color='white', key='canvas')], - [sg.Quit()] - ] + [sg.Quit()] ] -form = sg.FlexForm('Ping Times To Google.com', grab_anywhere=True).Layout(layout).Finalize() +window = sg.Window('Ping Times To Google.com', grab_anywhere=True).Layout(layout).Finalize() -canvas = form.FindElement('canvas').TKCanvas +canvas = window.FindElement('canvas').TKCanvas prev_response_time = None i=0 @@ -632,7 +632,7 @@ prev_x, prev_y = canvas_left, canvas_bottom while True: time.sleep(.2) - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() if button == 'Quit' or values is None: break diff --git a/Demo_Pong.py b/Demo_Pong.py index 3aef52c7..dbbaa0e5 100644 --- a/Demo_Pong.py +++ b/Demo_Pong.py @@ -1,6 +1,8 @@ import random import PySimpleGUI as sg import time +from sys import exit as exit + """ Pong code supplied by Daniel Young (Neonzz) @@ -126,13 +128,13 @@ class pongbat2(): def pong(): # ------------- Define GUI layout ------------- layout = [[sg.Canvas(size=(700, 400), background_color='black', key='canvas')], - [sg.T(''), sg.ReadFormButton('Quit')]] + [sg.T(''), sg.ReadButton('Quit')]] # ------------- Create window ------------- - form = sg.FlexForm('The Classic Game of Pong', return_keyboard_events=True).Layout(layout).Finalize() - # form.Finalize() # TODO Replace with call to form.Finalize once code released + window = sg.Window('The Classic Game of Pong', return_keyboard_events=True).Layout(layout).Finalize() + # window.Finalize() # TODO Replace with call to window.Finalize once code released # ------------- Get the tkinter Canvas we're drawing on ------------- - canvas = form.FindElement('canvas').TKCanvas + canvas = window.FindElement('canvas').TKCanvas # ------------- Create line down center, the bats and ball ------------- canvas.create_line(350, 0, 350, 400, fill='white') @@ -148,7 +150,7 @@ def pong(): bat2.draw() # ------------- Read the form, get keypresses ------------- - button, values = form.ReadNonBlocking() + button, values = window.ReadNonBlocking() # ------------- If quit ------------- if button is None and values is None or button == 'Quit': exit(69) diff --git a/Demo_Progress_Meters.py b/Demo_Progress_Meters.py index 2b902fb7..9a594516 100644 --- a/Demo_Progress_Meters.py +++ b/Demo_Progress_Meters.py @@ -1,5 +1,7 @@ from time import sleep import PySimpleGUI as sg +from sys import exit as exit + """ Demonstration of simple and multiple OneLineProgressMeter's @@ -17,7 +19,6 @@ import PySimpleGUI as sg The simple case is that you want to add a single meter to your code. The one-line solution """ -import PySimpleGUI as sg # Display a progress meter in work loop. User is not allowed to break out of the loop for i in range(10000): @@ -29,22 +30,19 @@ for i in range(10000): break - - layout = [ [sg.T('One-Line Progress Meter Demo', font=('Any 18'))], [sg.T('Outer Loop Count', size=(15,1), justification='r'), sg.In(default_text='100', size=(5,1), key='CountOuter', do_not_clear=True), sg.T('Delay'), sg.In(default_text='10', key='TimeOuter', size=(5,1), do_not_clear=True), sg.T('ms')], [sg.T('Inner Loop Count', size=(15,1), justification='r'), sg.In(default_text='100', size=(5,1), key='CountInner', do_not_clear=True) , sg.T('Delay'), sg.In(default_text='10', key='TimeInner', size=(5,1), do_not_clear=True), sg.T('ms')], - [sg.SimpleButton('Show', pad=((0,0), 3), bind_return_key=True), sg.T('me the meters!')] + [sg.Button('Show', pad=((0,0), 3), bind_return_key=True), sg.T('me the meters!')] ] -form = sg.FlexForm('One-Line Progress Meter Demo') -form.Layout(layout) +window = sg.Window('One-Line Progress Meter Demo').Layout(layout) while True: - button, values = form.Read() + button, values = window.Read() if button is None: break if button == 'Show': diff --git a/Demo_Recipes.py b/Demo_Recipes.py deleted file mode 100644 index 585fd133..00000000 --- a/Demo_Recipes.py +++ /dev/null @@ -1,237 +0,0 @@ -import time -from random import randint -import PySimpleGUI as sg - -# A simple blocking form. Your best starter-form -def SourceDestFolders(): - with sg.FlexForm('Demo Source / Destination Folders') as form: - form_rows = ([sg.Text('Enter the Source and Destination folders')], - [sg.Text('Source Folder', size=(15, 1), justification='right'), sg.InputText('Source', key='source'), sg.FolderBrowse()], - [sg.Text('Destination Folder', size=(15, 1), justification='right'), sg.InputText('Dest', key='dest'), sg.FolderBrowse()], - [sg.Submit(), sg.Cancel()]) - - button, values = form.LayoutAndRead(form_rows) - if button is 'Submit': - sg.Popup('Submitted', values, 'The user entered source:', values['source'], 'Destination folder:', values['dest'], 'Using button', button) - else: - sg.PopupError('Cancelled', 'User Cancelled') - - -def MachineLearningGUI(): - sg.SetOptions(text_justification='right') - form = sg.FlexForm('Machine Learning Front End', font=("Helvetica", 12)) # begin with a blank form - - layout = [[sg.Text('Machine Learning Command Line Parameters', font=('Helvetica', 16))], - [sg.Text('Passes', size =(15, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1)), - sg.Text('Steps', size=(18, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1))], - [sg.Text('ooa', size=(15, 1)), sg.In(default_text='6', size=(10, 1)), sg.Text('nn', size=(15, 1)), sg.In(default_text='10', size=(10, 1))], - [sg.Text('q', size=(15, 1)), sg.In(default_text='ff', size=(10, 1)), sg.Text('ngram', size=(15, 1)), sg.In(default_text='5', size=(10, 1))], - [sg.Text('l', size=(15, 1)), sg.In(default_text='0.4', size=(10, 1)), sg.Text('Layers', size=(15, 1)), sg.Drop(values=('BatchNorm', 'other'),auto_size_text=True)], - [sg.Text('_' * 100, size=(65, 1))], - [sg.Text('Flags', font=('Helvetica', 15), justification='left')], - [sg.Checkbox('Normalize', size=(12, 1), default=True), sg.Checkbox('Verbose', size=(20, 1))], - [sg.Checkbox('Cluster', size=(12, 1)), sg.Checkbox('Flush Output', size=(20, 1), default=True)], - [sg.Checkbox('Write Results', size=(12, 1)), sg.Checkbox('Keep Intermediate Data', size=(20, 1))], - [sg.Text('_' * 100, size=(65, 1))], - [sg.Text('Loss Functions', font=('Helvetica', 15), justification='left')], - [sg.Radio('Cross-Entropy', 'loss', size=(12, 1)), sg.Radio('Logistic', 'loss', default=True, size=(12, 1))], - [sg.Radio('Hinge', 'loss', size=(12, 1)), sg.Radio('Huber', 'loss', size=(12, 1))], - [sg.Radio('Kullerback', 'loss', size=(12, 1)), sg.Radio('MAE(L1)', 'loss', size=(12, 1))], - [sg.Radio('MSE(L2)', 'loss', size=(12, 1)), sg.Radio('MB(L0)', 'loss', size=(12, 1))], - [sg.Submit(), sg.Cancel()]] - button, values = form.LayoutAndRead(layout) - del(form) - sg.SetOptions(text_justification='left') - - return button, values - -# YOUR BEST STARTING POINT -# This is a form showing you all of the basic Elements (widgets) -# Some have a few of the optional parameters set, but there are more to choose from -# You want to use the context manager because it will free up resources when you are finished -# Use this especially if you are runningm multi-threaded -# Where you free up resources is really important to tkinter -def Everything(): - - with sg.FlexForm('Everything bagel', auto_size_text=True, default_element_size=(40, 1)) as form: - layout = [ - [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))], - [sg.Text('Here is some text.... and a place to enter text')], - [sg.InputText()], - [sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)], - [sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")], - [sg.Multiline(default_text='This is the default Text should you decide not to type anything',size=(35,3)), - sg.Multiline(default_text='A second multi-line',size=(35,3))], - [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 3)), - sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)], - [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3', 'Listbox 4'), size=(30, 3)), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10), - sg.Spin(values=('Spin Box 1', '2','3'), initial_value='Spin Box 1')], - [sg.Text('_' * 80)], - [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Default Folder'), sg.FolderBrowse()], - [sg.Submit(), sg.Cancel()] ] - - button, values = form.LayoutAndRead(layout) - - sg.Popup('Title', 'The results of the form.', 'The button clicked was "{}"'.format(button), 'The values are', values) - -# Should you decide not to use a context manager, then try this form as your starting point -# Be aware that tkinter, which this is based on, is picky about who frees up resources, especially if -# you are running multithreaded -def Everything_NoContextManager(): - form = sg.FlexForm('Everything bagel', default_element_size=(40, 1)) - layout = [ - [sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))], - [sg.Text('Here is some text.... and a place to enter text')], - [sg.InputText('This is my text')], - [sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)], - [sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")], - [sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)), - sg.Multiline(default_text='A second multi-line', size=(35, 3))], - [sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 3)), - sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)], - [sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75), - sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10), - sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')], - [sg.Text('_' * 80)], - [sg.Text('Choose A Folder', size=(35, 1))], - [sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'), - sg.InputText('Default Folder'), sg.FolderBrowse()], - [sg.Submit(), sg.Cancel()] - ] - - button, values = form.LayoutAndRead(layout) - del(form) - - sg.Popup('Title', 'The results of the form.', 'The button clicked was "{}"'.format(button), 'The values are', values) - - -def ProgressMeter(): - for i in range(1,1000): - if not sg.EasyProgressMeter('My Meter', i + 1, 1000, orientation='h'): break - time.sleep(.01) - -# Blocking form that doesn't close -def ChatBot(): - with sg.FlexForm('Chat Window', auto_size_text=True, default_element_size=(30, 2), default_button_element_size=(10,2)) as form: - layout = [[(sg.Text('This is where standard out is being routed', size=(40, 1)))], - [sg.Output(size=(80, 20), font=('Courier 10'))], - [sg.Multiline(size=(70, 5), enter_submits=True), sg.ReadFormButton('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True), sg.SimpleButton('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]] - # notice this is NOT the usual LayoutAndRead call because you don't yet want to read the form - # if you call LayoutAndRead from here, then you will miss the first button click - form.Layout(layout) - # ---===--- Loop taking in user input and using it to query HowDoI web oracle --- # - while True: - button, value = form.Read() - if button is not 'SEND': - break - print(value[0]) - -# Shows a form that's a running counter -# this is the basic design pattern if you can keep your reading of the -# form within the 'with' block. If your read occurs far away in your code from the form creation -# then you will want to use the NonBlockingPeriodicUpdateForm example -def NonBlockingPeriodicUpdateForm_ContextManager(): - with sg.FlexForm('Running Timer', auto_size_text=True) as form: - text_element = sg.Text('', size=(15, 2), font=('Helvetica', 20), text_color='red', justification='center') - layout = [[sg.Text('Non blocking GUI with updates', justification='center')], - [text_element], - [sg.T(' ' * 22), sg.Quit()]] - form.LayoutAndRead(layout, non_blocking=True) - - for i in range(1,500): - text_element.Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) - button, values = form.ReadNonBlocking() - if values is None or button is 'Quit': # if user closed the window using X - break - time.sleep(.01) - else: - # if the loop finished then need to close the form for the user - form.CloseNonBlockingForm() - -# Use this context-manager-free version if your read of the form occurs far away in your code -# from the form creation (call to LayoutAndRead) -def NonBlockingPeriodicUpdateForm(): - # Show a form that's a running counter - form = sg.FlexForm('Running Timer', auto_size_text=True) - text_element = sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center') - form_rows = [[sg.Text('Stopwatch')], - [text_element], - [sg.T(' ' * 5), sg.ReadFormButton('Start/Stop', focus=True), sg.Quit()]] - - form.LayoutAndRead(form_rows, non_blocking=True) - - timer_running = True - i = 0 - while True: - i += 1 * (timer_running is True) - button, values = form.ReadNonBlocking() - if values is None or button is 'Quit': # if user closed the window using X or clicked Quit button - break - elif button is 'Start/Stop': - timer_running = not timer_running - text_element.Update('{:02d}:{:02d}.{:02d}'.format((i//100)//60, (i//100)%60, i%100)) - - time.sleep(.01) - # if the loop finished then need to close the form for the user - form.CloseNonBlockingForm() - del(form) - -def DebugTest(): - # SG.Print('How about we print a bunch of random numbers?', , size=(90,40)) - for i in range (1,300): - sg.Print('Here are 300 random numbers', i, randint(1, 1000), sep='-') - -# Change the colors and set borders to 0 for a flat look -def ChangeLookAndFeel(colors): - sg.SetOptions(background_color=colors['BACKGROUND'], - text_element_background_color=colors['BACKGROUND'], - element_background_color=colors['BACKGROUND'], - text_color=colors['TEXT'], - input_elements_background_color=colors['INPUT'], - button_color=colors['BUTTON'], - progress_meter_color=colors['PROGRESS'], - border_width=0, - slider_border_width=0, - progress_meter_border_depth=0, - scrollbar_color=(colors['INPUT']), - element_text_color=colors['TEXT']) - -def OneLineGUI(): - return sg.FlexForm('Get filename example').LayoutAndRead( - [[sg.Text('Filename')], [sg.Input(), sg.FileBrowse()], [sg.OK(), sg.Cancel()]]) - -#=---------------------------------- main ------------------------------ -def main(): - # button, (filename,) = OneLineGUI() - # DebugTe`st() - sg.Popup('Hello') - ChatBot() - Everything() - SourceDestFolders() - NonBlockingPeriodicUpdateForm_ContextManager() - NonBlockingPeriodicUpdateForm() - ChatBot() - Everything() - sg.ChangeLookAndFeel('GreenTan') - Everything() - # ChatBot() - - SourceDestFolders() - MachineLearningGUI() - NonBlockingPeriodicUpdateForm() - ProgressMeter() - DebugTest() - sg.ChangeLookAndFeel('Purple') - Everything_NoContextManager() - NonBlockingPeriodicUpdateForm_ContextManager() - - sg.Popup('Done with all recipes') - -if __name__ == '__main__': - main() - exit(69) diff --git a/Demo_Script_Launcher.py b/Demo_Script_Launcher.py index 5c72c8c1..4058bd0d 100644 --- a/Demo_Script_Launcher.py +++ b/Demo_Script_Launcher.py @@ -33,7 +33,7 @@ def execute_command_nonblocking(command, *args): def Launcher2(): sg.ChangeLookAndFeel('GreenTan') - form = sg.FlexForm('Script launcher') + window = sg.Window('Script launcher') filelist = glob.glob(LOCATION_OF_YOUR_SCRIPTS+'*.py') namesonly = [] @@ -43,14 +43,14 @@ def Launcher2(): layout = [ [sg.Listbox(values=namesonly, size=(30, 19), select_mode=sg.SELECT_MODE_EXTENDED, key='demolist'), sg.Output(size=(88, 20), font='Courier 10')], [sg.Checkbox('Wait for program to complete', default=False, key='wait')], - [sg.ReadFormButton('Run'), sg.ReadFormButton('Shortcut 1'), sg.ReadFormButton('Fav Program'), sg.SimpleButton('EXIT')], + [sg.ReadButton('Run'), sg.ReadButton('Shortcut 1'), sg.ReadButton('Fav Program'), sg.Button('EXIT')], ] - form.Layout(layout) + window.Layout(layout) # ---===--- Loop taking in user input and using it to query HowDoI --- # while True: - (button, value) = form.Read() + (button, value) = window.Read() if button in ('EXIT', None): break # exit button clicked if button in ('Shortcut 1', 'Fav Program'): @@ -60,7 +60,7 @@ def Launcher2(): elif button is 'Run': for index, file in enumerate(value['demolist']): print('Launching %s'%file) - form.Refresh() # make the print appear immediately + window.Refresh() # make the print appear immediately if value['wait']: execute_command_blocking(LOCATION_OF_YOUR_SCRIPTS + file) else: diff --git a/Demo_Script_Parameters.py b/Demo_Script_Parameters.py index 65c9c9c1..7409e126 100644 --- a/Demo_Script_Parameters.py +++ b/Demo_Script_Parameters.py @@ -14,7 +14,7 @@ stores the result in the variable fname, just like the command line parsing did. ''' if len(sys.argv) == 1: - button, (fname,) = sg.FlexForm('My Script').LayoutAndRead([[sg.T('Document to open')], + button, (fname,) = sg.Window('My Script').LayoutAndRead([[sg.T('Document to open')], [sg.In(), sg.FileBrowse()], [sg.Open(), sg.Cancel()]]) else: diff --git a/Demo_Spinner_Compound_Element.py b/Demo_Spinner_Compound_Element.py index 49ef2cc3..575beec5 100644 --- a/Demo_Spinner_Compound_Element.py +++ b/Demo_Spinner_Compound_Element.py @@ -7,9 +7,9 @@ import PySimpleGUI as sg sg.SetOptions(element_padding=(0,0)) # sg.ChangeLookAndFeel('Dark') # --- Define our "Big-Button-Spinner" compound element. Has 2 buttons and an input field --- # -NewSpinner = [sg.ReadFormButton('-', size=(2,1), font='Any 12'), +NewSpinner = [sg.ReadButton('-', size=(2,1), font='Any 12'), sg.In('0', size=(2,1), font='Any 14', justification='r', key='spin'), - sg.ReadFormButton('+', size=(2,1), font='Any 12')] + sg.ReadButton('+', size=(2,1), font='Any 12')] # --- Define Window --- # layout = [ [sg.Text('Spinner simulation')], @@ -18,17 +18,16 @@ layout = [ [sg.Ok()] ] -form = sg.FlexForm('Spinner simulation') -form.Layout(layout) +window = sg.Window('Spinner simulation').Layout(layout) # --- Event Loop --- # counter = 0 while True: - button, value = form.Read() + button, value = window.Read() if button == 'Ok' or button is None: # be nice to your user, always have an exit from your form break # --- do spinner stuff --- # counter += 1 if button =='+' else -1 if button == '-' else 0 - form.FindElement('spin').Update(counter) + window.FindElement('spin').Update(counter) diff --git a/Demo_Super_Simple_Form.py b/Demo_Super_Simple_Form.py index 80c229a4..068455c9 100644 --- a/Demo_Super_Simple_Form.py +++ b/Demo_Super_Simple_Form.py @@ -1,14 +1,18 @@ import PySimpleGUI as sg -form = sg.FlexForm('Simple data entry form') +""" + Simple Form showing how to use keys on your input fields +""" + layout = [ [sg.Text('Please enter your Name, Address, Phone')], [sg.Text('Name', size=(15, 1)), sg.InputText('1', key='name')], [sg.Text('Address', size=(15, 1)), sg.InputText('2', key='address')], [sg.Text('Phone', size=(15, 1)), sg.InputText('3', key='phone')], [sg.Submit(), sg.Cancel()] -] + ] -button, values = form.LayoutAndRead(layout) +window = sg.Window('Simple Data Entry Window').Layout(layout) +button, values = window.Read() sg.Popup(button, values, values['name'], values['address'], values['phone']) \ No newline at end of file diff --git a/Demo_Tabbed_Form.py b/Demo_Tabbed_Form.py index 21b640e1..60de7de6 100644 --- a/Demo_Tabbed_Form.py +++ b/Demo_Tabbed_Form.py @@ -33,9 +33,9 @@ german_categories =('Use Default with no change', # the form layout -form = sg.FlexForm('EBay Super Searcher', auto_size_text=True) +window = sg.Window('EBay Super Searcher', auto_size_text=True) -form2 = sg.FlexForm('EBay Super Searcher', auto_size_text=False) +form2 = sg.Window('EBay Super Searcher', auto_size_text=False) layout_tab_1 = [[sg.Text('eBay Super Searcher!', size=(60,1), font=('helvetica', 15))], [sg.Text('Choose base configuration to run')], diff --git a/Demo_Table_CSV.py b/Demo_Table_CSV.py index 16205381..f8b30a22 100644 --- a/Demo_Table_CSV.py +++ b/Demo_Table_CSV.py @@ -1,11 +1,12 @@ import csv import PySimpleGUI as sg +import sys def table_example(): filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files","*.csv"),)) # --- populate table with file contents --- # if filename == '': - exit(69) + sys.exit(69) data = [] header_list = [] button = sg.PopupYesNo('Does this file have column names already?') @@ -20,7 +21,7 @@ def table_example(): header_list = ['column' + str(x) for x in range(len(data[0]))] except: sg.PopupError('Error reading file') - exit(69) + sys.exit(69) sg.SetOptions(element_padding=(0, 0)) col_layout = [[sg.Table(values=data, headings=header_list, max_col_width=25, @@ -29,18 +30,9 @@ def table_example(): canvas_size = (13*10*len(header_list), 600) # estimate canvas size - 13 pixels per char * 10 char per column * num columns layout = [[sg.Column(col_layout, size=canvas_size, scrollable=True)],] - form = sg.FlexForm('Table', grab_anywhere=False) - b, v = form.LayoutAndRead(layout) + window = sg.Window('Table', grab_anywhere=False).Layout(layout) + b, v = window.Read() - exit(69) + sys.exit(69) table_example() - - - - - - - - - diff --git a/Demo_Table_Element.py b/Demo_Table_Element.py index 85ddef33..b0d44dd5 100644 --- a/Demo_Table_Element.py +++ b/Demo_Table_Element.py @@ -1,5 +1,6 @@ import csv import PySimpleGUI as sg +import sys filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files","*.csv"),)) # --- populate table with file contents --- # @@ -11,7 +12,7 @@ if filename is not None: data = list(reader) # read everything else into a list of rows except: sg.PopupError('Error reading file') - exit(69) + sys.exit(69) sg.SetOptions(element_padding=(0, 0)) @@ -19,11 +20,8 @@ col_layout = [[sg.Table(values=data[1:][:], headings=[data[0][x] for x in range( auto_size_columns=True, display_row_numbers=True, justification='right', size=(None, len(data)))]] layout = [[sg.Column(col_layout, size=(1200,600), scrollable=True)],] -form = sg.FlexForm('Table', grab_anywhere=False) -form.Layout(layout) +window = sg.Window('Table', grab_anywhere=False).Layout(layout) -form.Finalize() +b, v = window.Read() -b, v = form.Read() - -exit(69) +sys.exit(69) diff --git a/Demo_Table_Pandas.py b/Demo_Table_Pandas.py index f5088d53..1a519ea1 100644 --- a/Demo_Table_Pandas.py +++ b/Demo_Table_Pandas.py @@ -1,12 +1,13 @@ import pandas as pd import PySimpleGUI as sg +import sys def table_example(): sg.SetOptions(auto_size_buttons=True) filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files", "*.csv"),)) # --- populate table with file contents --- # if filename == '': - exit(69) + sys.exit(69) data = [] header_list = [] button = sg.PopupYesNo('Does this file have column names already?') @@ -21,7 +22,7 @@ def table_example(): header_list = ['column' + str(x) for x in range(len(data[0]))] # Creates columns names for each column ('column0', 'column1', etc) except: sg.PopupError('Error reading file') - exit(69) + sys.exit(69) # sg.SetOptions(element_padding=(0, 0)) col_layout = [[sg.Table(values=data, headings=header_list, display_row_numbers=True, @@ -30,9 +31,9 @@ def table_example(): canvas_size = (13*10*len(header_list), 600) # estimate canvas size - 13 pixels per char * 10 per column * num columns layout = [[sg.Column(col_layout, size=canvas_size, scrollable=True)]] - form = sg.FlexForm('Table', grab_anywhere=False) - b, v = form.LayoutAndRead(layout) + window = sg.Window('Table', grab_anywhere=False) + b, v = window.LayoutAndRead(layout) - exit(69) + sys.exit(69) table_example() diff --git a/Demo_Table_Simulation.py b/Demo_Table_Simulation.py index 14860b3b..a714de6a 100644 --- a/Demo_Table_Simulation.py +++ b/Demo_Table_Simulation.py @@ -6,6 +6,7 @@ def TableSimulation(): Display data in a table format """ sg.SetOptions(element_padding=(0,0)) + sg.PopupNoWait('Give it a few seconds to load please...', auto_close=True) menu_def = [['File', ['Open', 'Save', 'Exit']], ['Edit', ['Paste', ['Special', 'Normal',], 'Undo'],], @@ -21,17 +22,16 @@ def TableSimulation(): layout = [ [sg.Menu(menu_def)], [sg.T('Table Using Combos and Input Elements', font='Any 18')], - [sg.T('Type in a row, column and value. The form will update the values in realtime as you type'), + [sg.T('Type in a row, column and value. The form will update the values in realtime as you type'), sg.In(key='inputrow', justification='right', size=(8,1), pad=(1,1), do_not_clear=True), sg.In(key='inputcol', size=(8,1), pad=(1,1), justification='right', do_not_clear=True), sg.In(key='value', size=(8,1), pad=(1,1), justification='right', do_not_clear=True)], - [sg.Column(columm_layout, size=(800,600), scrollable=True)]] + [sg.Column(columm_layout, size=(800,600), scrollable=True)] ] - form = sg.FlexForm('Table', return_keyboard_events=True, grab_anywhere=False) - form.Layout(layout) + window = sg.Window('Table', return_keyboard_events=True, grab_anywhere=False).Layout(layout) while True: - button, values = form.Read() + button, values = window.Read() # --- Process buttons --- # if button is None or button == 'Exit': break @@ -49,13 +49,13 @@ def TableSimulation(): sg.PopupError('Error reading file') continue # clear the table - [form.FindElement((i,j)).Update('') for j in range(MAX_COL) for i in range(MAX_ROWS)] + [window.FindElement((i,j)).Update('') for j in range(MAX_COL) for i in range(MAX_ROWS)] for i, row in enumerate(data): for j, item in enumerate(row): location = (i,j) try: # try the best we can at reading and filling the table - target_element = form.FindElement(location) + target_element = window.FindElement(location) new_value = item if target_element is not None and new_value != '': target_element.Update(new_value) @@ -65,7 +65,7 @@ def TableSimulation(): # if a valid table location entered, change that location's value try: location = (int(values['inputrow']), int(values['inputcol'])) - target_element = form.FindElement(location) + target_element = window.FindElement(location) new_value = values['value'] if target_element is not None and new_value != '': target_element.Update(new_value) diff --git a/Demo_Tabs.py b/Demo_Tabs.py index a90fbff3..fbeec147 100644 --- a/Demo_Tabs.py +++ b/Demo_Tabs.py @@ -1,23 +1,19 @@ import PySimpleGUI as sg -tab1_layout = [[sg.T('This is inside tab 1')]] -tab2_layout = [[sg.T('This is inside tab 2'), sg.In(key='in')]] +tab1_layout = [ + [sg.T('This is inside tab 1')], + ] -tab3_layout = [[sg.T('This is inside tab 3')]] -tab4_layout = [[sg.T('This is inside tab 4')]] +tab2_layout = [ + [sg.T('This is inside tab 2'), sg.In(key='in')], + ] -tab5_layout = [[sg.T('This is inside tab 5')]] -tab6_layout = [[sg.T('This is inside tab 6')], - [sg.T('How about a second row of stuff in tab 6?')]] +layout = [ + [sg.TabGroup([[sg.Tab('Tab 1', tab1_layout), sg.Tab('Tab 2', tab2_layout)]])], + [sg.RButton('Read')] + ] -layout = [[sg.T('My Window!')], - [sg.TabGroup([[sg.Tab('Tab 1', tab1_layout), sg.Tab('Tab 2', tab2_layout)]]), sg.TabGroup([[sg.Tab('Tab 3', tab3_layout), sg.Tab('Tab 4', tab4_layout)]])], - [sg.T('Text in the middle of the mess')], - [sg.TabGroup([[sg.Tab('Tab 5', tab5_layout), sg.Tab('Tab 6', tab6_layout)]])], - [sg.RButton('Read')], - ] - -window = sg.Window('My window with tabs').Layout(layout) +window = sg.Window('My window with tabs', default_element_size=(12,1)).Layout(layout) while True: b, v = window.Read() diff --git a/Demo_Tabs_Nested.py b/Demo_Tabs_Nested.py new file mode 100644 index 00000000..2c0291f7 --- /dev/null +++ b/Demo_Tabs_Nested.py @@ -0,0 +1,29 @@ +import PySimpleGUI as sg + +tab1_layout = [[sg.T('This is inside tab 1')], + [sg.T('Tabs can be anywhere now!')] + ] + +tab2_layout = [[sg.T('This is inside tab 2'), sg.In(key='in')]] + +tab3_layout = [[sg.T('This is inside tab 3')]] +tab4_layout = [[sg.T('This is inside tab 4')]] + +tab5_layout = [[sg.T('This is inside tab 5')]] +tab6_layout = [[sg.T('This is inside tab 6')], + [sg.T('How about a second row of stuff in tab 6?')]] + +layout = [[sg.T('My Window!')], [sg.Frame('A Frame', layout= + [[sg.TabGroup([[sg.Tab('Tab 1', tab1_layout), sg.Tab('Tab 2', tab2_layout)]]), sg.TabGroup([[sg.Tab('Inside of a frame?', tab3_layout), sg.Tab('Tab 4', tab4_layout)]])]])], + [sg.T('This text is on a row with a column'),sg.Column(layout=[[sg.T('In a column')], + [sg.TabGroup([[sg.Tab('Tab 5', tab5_layout), sg.Tab('Tab 6', tab6_layout)]])], + [sg.RButton('Read')]])], + ] + +window = sg.Window('My window with tabs', default_element_size=(12,1)).Layout(layout) + +while True: + b, v = window.Read() + print(b,v) + if b is None: # always, always give a way out! + break \ No newline at end of file diff --git a/Demo_Youtube-dl_Frontend.py b/Demo_Youtube-dl_Frontend.py index e4aa2edb..83fd77e3 100644 --- a/Demo_Youtube-dl_Frontend.py +++ b/Demo_Youtube-dl_Frontend.py @@ -16,23 +16,22 @@ def DownloadSubtitlesGUI(): [sg.Text('Subtitle Grabber', size=(40, 1), font=('Any 15'))], [sg.T('YouTube Link'),sg.In(default_text='',size=(60,1), key='link', do_not_clear=True) ], [sg.Output(size=(90,20), font='Courier 12')], - [sg.ReadFormButton('Get List')], - [sg.T('Language Code'), combobox, sg.ReadFormButton('Download')], - [sg.SimpleButton('Exit', button_color=('white', 'firebrick3'))] + [sg.ReadButton('Get List')], + [sg.T('Language Code'), combobox, sg.ReadButton('Download')], + [sg.Button('Exit', button_color=('white', 'firebrick3'))] ] - form = sg.FlexForm('Subtitle Grabber launcher', text_justification='r', default_element_size=(15,1), font=('Any 14')) - form.Layout(layout) + window = sg.Window('Subtitle Grabber launcher', text_justification='r', default_element_size=(15,1), font=('Any 14')).Layout(layout) # ---===--- Loop taking in user input and using it to query HowDoI --- # while True: - (button, gui) = form.Read() + (button, gui) = window.Read() if button in ('EXIT', None): break # exit button clicked link = gui['link'] if button is 'Get List': print('Getting list of subtitles....') - form.Refresh() + window.Refresh() command = [f'C:/Python/PycharmProjects/GooeyGUI/youtube-dl --list-subs {link}',] output = ExecuteCommandSubprocess(command, wait=True, quiet=True) lang_list = [o[:5].rstrip() for o in output.split('\n') if 'vtt' in o] @@ -45,7 +44,7 @@ def DownloadSubtitlesGUI(): if lang is '': lang = 'en' print(f'Downloading subtitle for {lang}...') - form.Refresh() + window.Refresh() command = (f'C:/Python/PycharmProjects/GooeyGUI/youtube-dl --sub-lang {lang} --write-sub {link}',) ExecuteCommandSubprocess(command, wait=True) print('Done')