From 4895ab61f2107f1bc8c892859ba640db584378d0 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Fri, 27 Jul 2018 15:45:38 -0400 Subject: [PATCH] RELEASE 2.6 New setting for Button Element sizing. System-wide DEFAULT_AUTO_SIZE_BUTTONS. Can also be set at the form level. This will greatly compact code. --- Demo_HowDoI.py | 3 +- Demo_Recipes.py | 150 +++++++++++++++++++++++++++++++++--------------- PySimpleGUI.py | 106 ++++++++++++++++++++++------------ 3 files changed, 174 insertions(+), 85 deletions(-) diff --git a/Demo_HowDoI.py b/Demo_HowDoI.py index e7385bfd..257a0656 100644 --- a/Demo_HowDoI.py +++ b/Demo_HowDoI.py @@ -17,7 +17,8 @@ def HowDoI(): :return: never returns ''' # ------- Make a new FlexForm ------- # - SG.SetOptions(border_width=1) + # Set system-wide options that will affect all future forms. Give our form a spiffy look and feel + SG.SetOptions(background_color='#9FB8AD', text_element_background_color='#9FB8AD', element_background_color='#9FB8AD', scrollbar_color=None, input_elements_background_color='#F7F3EC', button_color=('white','#475841')) form = SG.FlexForm('How Do I ??', auto_size_text=True, default_element_size=(30, 2), icon=DEFAULT_ICON) form.AddRow(SG.Text('Ask and your answer will appear here....', size=(40, 1))) form.AddRow(SG.Output(size=(90, 20))) diff --git a/Demo_Recipes.py b/Demo_Recipes.py index 8b8e9293..68bc72a1 100644 --- a/Demo_Recipes.py +++ b/Demo_Recipes.py @@ -4,10 +4,10 @@ import PySimpleGUI as sg # A simple blocking form. Your best starter-form def SourceDestFolders(): - with sg.FlexForm('Demo Source / Destination Folders', auto_size_text=True) as form: + 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), auto_size_text=False, justification='right'), sg.InputText('Source')], - [sg.Text('Destination Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Dest'), sg.FolderBrowse()], + [sg.Text('Source Folder', size=(15, 1), justification='right'), sg.InputText('Source'), sg.FolderBrowse()], + [sg.Text('Destination Folder', size=(15, 1), justification='right'), sg.InputText('Dest'), sg.FolderBrowse()], [sg.Submit(), sg.Cancel()]] button, (source, dest) = form.LayoutAndRead(form_rows) @@ -16,6 +16,35 @@ def SourceDestFolders(): else: sg.MsgBoxError('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', 13))], + [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', 13))], + [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.LayoutAndShow(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 @@ -23,65 +52,70 @@ def SourceDestFolders(): # 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), text_color='blue')], + [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 shoulsd you decide not to type anything', - scale=(2, 10))], - [sg.InputCombo(['Combobox 1', 'Combobox 2'], size=(20, 3)), - sg.Slider(range=(1, 100), orientation='h', size=(35, 20), default_value=85)], - [sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6)), - sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=25), - sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=75), - sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=10), + [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('_' * 100, size=(70, 1))], - [sg.Text('Choose Source and Destination Folders', size=(35, 1))], - [sg.Text('Source Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Source'), sg.FolderBrowse()], - [sg.Text('Destination Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Dest'), - sg.FolderBrowse()], - [sg.Submit(), sg.Cancel(), sg.SimpleButton('Customized', button_color=('white', 'green'))] + [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(), sg.SimpleButton('Customized', button_color=('black', '#EDE5B7'))] ] button, values = form.LayoutAndRead(layout) - sg.MsgBox('Title', 'Typical message box', 'The results of the form are a lot of data! Get ready... ', 'The button clicked was "{}"'.format(button), 'The values are', values) + sg.MsgBox('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', auto_size_text=True, default_element_size=(40, 1)) - layout = [[sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25), text_color='blue')], - [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 shoulsd you decide not to type anything', scale=(2, 10))], - [sg.InputCombo(['Combobox 1', 'Combobox 2'], size=(20, 3)), sg.Slider(range=(1, 100), orientation='h', size=(35, 20), default_value=85)], - [sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6)), - sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=25), - sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=75), - sg.Slider(range=(1, 100), orientation='v', size=(10, 20), default_value=10)], - [sg.Text('_' * 100, size=(70, 1))], - [sg.Text('Choose Source and Destination Folders', size=(35, 1), text_color='red')], - [sg.Text('Source Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Source'), sg.FolderBrowse()], - [sg.Text('Destination Folder', size=(15, 1), auto_size_text=False, justification='right'), sg.InputText('Dest'), sg.FolderBrowse()], - [sg.Submit(), sg.Cancel(), sg.SimpleButton('Customized', button_color=('white', 'green'))]] + 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(), sg.SimpleButton('Customized', button_color=('white', '#7E6C92'))] + ] button, values = form.LayoutAndRead(layout) del(form) - sg.MsgBox('Title', 'Typical message box', 'Here are the restults! There is one entry per input field ', 'The button clicked was "{}"'.format(button), 'The values are', values) + sg.MsgBox('Title', 'The results of the form.', 'The button clicked was "{}"'.format(button), 'The values are', values) + def ProgressMeter(): - for i in range(1,10000): - if not sg.EasyProgressMeter('My Meter', i + 1, 10000): break - # SG.Print(i) + for i in range(1,100): + if not sg.EasyProgressMeter('My Meter', i + 1, 100, orientation='v'): break + time.sleep(.01) # Blocking form that doesn't close def ChatBot(): @@ -149,18 +183,40 @@ def DebugTest(): for i in range (1,300): sg.Print(i, randint(1, 1000), end='', sep='-') - +#=---------------------------------- main ------------------------------ def main(): - # SG.SetOptions(border_width=1, font=("Helvetica", 10), button_color=('white', SG.BLUES[0]), slider_border_width=1) - NonBlockingPeriodicUpdateForm_ContextManager() - NonBlockingPeriodicUpdateForm() - Everything_NoContextManager() - Everything() - ChatBot() - ProgressMeter() + + # sg.MsgBox('Changing look and feel.', 'Done by calling SetOptions') SourceDestFolders() + + sg.SetOptions(background_color='#9FB8AD', text_element_background_color='#9FB8AD', element_background_color='#9FB8AD', scrollbar_color=None, input_elements_background_color='#F7F3EC', button_color=('white','#475841'), border_width=0, slider_border_width=0, progress_meter_border_depth=0) + + MachineLearningGUI() + Everything_NoContextManager() + + # sg.SetOptions(background_color='#B89FB6', text_element_background_color='#B89FB6', element_background_color='#B89FB6', button_color=('white','#7E6C92'), text_color='#3F403F',border_width=0, slider_border_width=0, progress_meter_border_depth=0) + + sg.SetOptions(background_color='#A5CADD', input_elements_background_color='#E0F5FF', text_element_background_color='#A5CADD', element_background_color='#A5CADD', button_color=('white','#303952'), text_color='#822E45',border_width=0, progress_meter_color=('#3D8255','white'), slider_border_width=0, progress_meter_border_depth=0) + + Everything_NoContextManager() + + Everything() + + ProgressMeter() + + # Set system-wide options that will affect all future forms + + + NonBlockingPeriodicUpdateForm_ContextManager() + + + NonBlockingPeriodicUpdateForm() + + ChatBot() + DebugTest() + sg.MsgBox('Done with all recipes') if __name__ == '__main__': diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 006a04dc..e18b401e 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -15,6 +15,7 @@ DEFAULT_ELEMENT_SIZE = (45,1) # In CHARACTERS DEFAULT_MARGINS = (10,5) # Margins for each LEFT/RIGHT margin is first term DEFAULT_ELEMENT_PADDING = (5,3) # Padding between elements (row, col) in pixels DEFAULT_AUTOSIZE_TEXT = False +DEFAULT_AUTOSIZE_BUTTONS = True DEFAULT_FONT = ("Helvetica", 10) DEFAULT_TEXT_JUSTIFICATION = 'left' DEFAULT_BORDER_WIDTH = 1 @@ -62,7 +63,7 @@ RELIEF_GROOVE= 'groove' RELIEF_SOLID = 'solid' DEFAULT_PROGRESS_BAR_COLOR = (GREENS[0], '#D0D0D0') # a nice green progress bar -DEFAULT_PROGRESS_BAR_SIZE = (35,20) # Size of Progress Bar (characters for length, pixels for width) +DEFAULT_PROGRESS_BAR_SIZE = (25,20) # Size of Progress Bar (characters for length, pixels for width) DEFAULT_PROGRESS_BAR_BORDER_WIDTH=1 DEFAULT_PROGRESS_BAR_RELIEF = RELIEF_GROOVE PROGRESS_BAR_STYLES = ('default','winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative') @@ -382,7 +383,7 @@ class Text(Element): # ---------------------------------------------------------------------- # class TKProgressBar(): - def __init__(self, root, max, length=400, width=DEFAULT_PROGRESS_BAR_SIZE[1], style=DEFAULT_PROGRESS_BAR_STYLE, relief=DEFAULT_PROGRESS_BAR_RELIEF, border_width=DEFAULT_PROGRESS_BAR_BORDER_WIDTH, orientation='horizontal', BarColor=DEFAULT_PROGRESS_BAR_COLOR): + def __init__(self, root, max, length=400, width=DEFAULT_PROGRESS_BAR_SIZE[1], style=DEFAULT_PROGRESS_BAR_STYLE, relief=DEFAULT_PROGRESS_BAR_RELIEF, border_width=DEFAULT_PROGRESS_BAR_BORDER_WIDTH, orientation='horizontal', BarColor=(None,None)): self.Length = length self.Width = width self.Max = max @@ -423,8 +424,10 @@ class TKProgressBar(): pass # ---------------------------------------------------------------------- # -# Output # -# New Type of Widget that's a Text Widget in disguise # +# TKOutput # +# New Type of TK Widget that's a Text Widget in disguise # +# Note that it's inherited from the TKFrame class so that the # +# Scroll bar will span the length of the frame # ---------------------------------------------------------------------- # class TKOutput(tk.Frame): def __init__(self, parent, width, height, bd, background_color=None): @@ -462,6 +465,10 @@ class TKOutput(tk.Frame): sys.stdout = self.previous_stdout sys.stderr = self.previous_stderr +# ---------------------------------------------------------------------- # +# Output # +# Routes stdout, stderr to a scrolled window # +# ---------------------------------------------------------------------- # class Output(Element): def __init__(self, scale=(None, None), size=(None, None), background_color=None): self.TKOut = None @@ -479,7 +486,8 @@ class Output(Element): # Button Class # # ---------------------------------------------------------------------- # class Button(Element): - def __init__(self, button_type=CLOSES_WIN, target=(None, None), button_text='', file_types=(("ALL Files", "*.*"),), image_filename=None, image_size=(None,None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_text=None, button_color=None, font=None): + def __init__(self, button_type=CLOSES_WIN, target=(None, None), button_text='', file_types=(("ALL Files", "*.*"),), image_filename=None, image_size=(None,None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None): + self.AutoSizeButton = auto_size_button self.BType = button_type self.FileTypes = file_types self.TKButton = None @@ -491,7 +499,7 @@ class Button(Element): self.ImageSubsample = image_subsample self.UserData = None self.BorderWidth = border_width if border_width is not None else DEFAULT_BORDER_WIDTH - super().__init__(ELEM_TYPE_BUTTON, scale, size, auto_size_text, font=font) + super().__init__(ELEM_TYPE_BUTTON, scale, size, font=font) return # ------- Button Callback ------- # @@ -667,8 +675,9 @@ class FlexForm: ''' Display a user defined for and return the filled in data ''' - def __init__(self, title, default_element_size=(DEFAULT_ELEMENT_SIZE[0], DEFAULT_ELEMENT_SIZE[1]), auto_size_text=DEFAULT_AUTOSIZE_TEXT, scale=(None, None), location=(None, None), button_color=None, font=None, progress_bar_color=(None, None), background_color=None, is_tabbed_form=False, border_depth=None, auto_close=False, auto_close_duration=DEFAULT_AUTOCLOSE_TIME, icon=DEFAULT_WINDOW_ICON): - self.AutoSizeText = auto_size_text + def __init__(self, title, default_element_size=(DEFAULT_ELEMENT_SIZE[0], DEFAULT_ELEMENT_SIZE[1]), auto_size_text=None, auto_size_buttons=None, scale=(None, None), location=(None, None), button_color=None, font=None, progress_bar_color=(None, None), background_color=None, is_tabbed_form=False, border_depth=None, auto_close=False, auto_close_duration=DEFAULT_AUTOCLOSE_TIME, icon=DEFAULT_WINDOW_ICON): + self.AutoSizeText = auto_size_text if auto_size_text is not None else DEFAULT_AUTOSIZE_TEXT + self.AutoSizeButtons = auto_size_buttons if auto_size_buttons is not None else DEFAULT_AUTOSIZE_BUTTONS self.Title = title self.Rows = [] # a list of ELEMENTS for this row self.DefaultElementSize = default_element_size @@ -901,50 +910,50 @@ def T(display_text, scale=(None, None), size=(None, None), auto_size_text=None, return Text(display_text, scale=scale, size=size, auto_size_text=auto_size_text, font=font, text_color=text_color, justification=justification) # ------------------------- FOLDER BROWSE Element lazy function ------------------------- # -def FolderBrowse(target=(ThisRow, -1), button_text='Browse', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(BROWSE_FOLDER, target=target, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def FolderBrowse(target=(ThisRow, -1), button_text='Browse', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(BROWSE_FOLDER, target=target, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- FILE BROWSE Element lazy function ------------------------- # -def FileBrowse(target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), button_text='Browse', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(BROWSE_FILE, target, button_text=button_text, file_types=file_types, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def FileBrowse(target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), button_text='Browse', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(BROWSE_FILE, target, button_text=button_text, file_types=file_types, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- SUBMIT BUTTON Element lazy function ------------------------- # -def Submit(button_text='Submit', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def Submit(button_text='Submit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- OK BUTTON Element lazy function ------------------------- # -def OK(button_text='OK', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def OK(button_text='OK', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- YES BUTTON Element lazy function ------------------------- # -def Ok(button_text='Ok', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def Ok(button_text='Ok', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- CANCEL BUTTON Element lazy function ------------------------- # -def Cancel(button_text='Cancel', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None, font=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color, font=font) +def Cancel(button_text='Cancel', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font) # ------------------------- QUIT BUTTON Element lazy function ------------------------- # -def Quit(button_text='Quit', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None, font=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color, font=font) +def Quit(button_text='Quit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font) # ------------------------- YES BUTTON Element lazy function ------------------------- # -def Yes(button_text='Yes', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def Yes(button_text='Yes', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- NO BUTTON Element lazy function ------------------------- # -def No(button_text='No', scale=(None, None), size=(None, None), auto_size_text=None, button_color=None): - return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color) +def No(button_text='No', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None): + return Button(CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color) # ------------------------- GENERIC BUTTON Element lazy function ------------------------- # # this is the only button that REQUIRES button text field -def SimpleButton(button_text, image_filename=None, image_size=(None, None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_text=None, button_color=None, font=None): - return Button(CLOSES_WIN, image_filename=image_filename, image_size=image_size,image_subsample=image_subsample, button_text=button_text,border_width=border_width, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color, font=font) +def SimpleButton(button_text, image_filename=None, image_size=(None, None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None): + return Button(CLOSES_WIN, image_filename=image_filename, image_size=image_size,image_subsample=image_subsample, button_text=button_text,border_width=border_width, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font) # ------------------------- GENERIC BUTTON Element lazy function ------------------------- # # this is the only button that REQUIRES button text field -def ReadFormButton(button_text, image_filename=None, image_size=(None, None),image_subsample=None,border_width=None,scale=(None, None), size=(None, None), auto_size_text=None, button_color=None, font=None): - return Button(READ_FORM, image_filename=image_filename, image_size=image_size,image_subsample=image_subsample,border_width=border_width, button_text=button_text, scale=scale, size=size, auto_size_text=auto_size_text, button_color=button_color, font=font) +def ReadFormButton(button_text, image_filename=None, image_size=(None, None),image_subsample=None,border_width=None,scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None): + return Button(READ_FORM, image_filename=image_filename, image_size=image_size,image_subsample=image_subsample,border_width=border_width, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font) #------------------------------------------------------------------------------------------------------# # ------- FUNCTION InitializeResults. Sets up form results matrix ------- # @@ -1164,7 +1173,10 @@ def ConvertFlexToTK(MyFlexForm): element.Location = (row_num, col_num) btext = element.ButtonText btype = element.BType - if auto_size_text is False: width=element_size[0] + if element.AutoSizeButton is not None: + auto_size = element.AutoSizeButton + else: auto_size = MyFlexForm.AutoSizeButtons + if auto_size is False: width=element_size[0] else: width = 0 height=element_size[1] lines = btext.split('\n') @@ -1334,7 +1346,7 @@ def ConvertFlexToTK(MyFlexForm): elif element_type == ELEM_TYPE_OUTPUT: width, height = element_size element.TKOut = TKOutput(tk_row_frame, width=width, height=height, bd=border_depth, background_color=element.BackgroundColor) - element.TKOut.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1]) + element.TKOut.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1], fill=tk.X) # ------------------------- IMAGE Box element ------------------------- # elif element_type == ELEM_TYPE_IMAGE: photo = tk.PhotoImage(file=element.Filename) @@ -1687,7 +1699,7 @@ def ConvertArgsToSingleString(*args): # ============================== ProgressMeter =====# # ===================================================# -def ProgressMeter(title, max_value, *args, orientation=None, bar_color=DEFAULT_PROGRESS_BAR_COLOR, button_color=None, size=DEFAULT_PROGRESS_BAR_SIZE, scale=(None, None), border_width=None): +def ProgressMeter(title, max_value, *args, orientation=None, bar_color=(None,None), button_color=None, size=DEFAULT_PROGRESS_BAR_SIZE, scale=(None, None), border_width=None): ''' Create and show a form on tbe caller's behalf. :param title: @@ -1801,7 +1813,7 @@ class EasyProgressMeterDataClass(): # ============================== EasyProgressMeter =====# -def EasyProgressMeter(title, current_value, max_value, *args, orientation=None, bar_color=DEFAULT_PROGRESS_BAR_COLOR, button_color=None, size=DEFAULT_PROGRESS_BAR_SIZE, scale=(None, None), border_width=None): +def EasyProgressMeter(title, current_value, max_value, *args, orientation=None, bar_color=(None,None), button_color=None, size=DEFAULT_PROGRESS_BAR_SIZE, scale=(None, None), border_width=None): ''' A ONE-LINE progress meter. Add to your code where ever you need a meter. No need for a second function call before your loop. You've got enough code to write! @@ -2063,7 +2075,7 @@ def SetGlobalIcon(icon): # Sets the icon to be used by default # # ===================================================# def SetOptions(icon=None, button_color=(None,None), element_size=(None,None), margins=(None,None), - element_padding=(None,None),auto_size_text=None, font=None, border_width=None, + element_padding=(None,None),auto_size_text=None, auto_size_buttons=None, font=None, border_width=None, slider_border_width=None, slider_relief=None, slider_orientation=None, autoclose_time=None, message_box_line_width=None, progress_meter_border_depth=None, progress_meter_style=None, @@ -2076,6 +2088,7 @@ def SetOptions(icon=None, button_color=(None,None), element_size=(None,None), ma global DEFAULT_MARGINS # Margins for each LEFT/RIGHT margin is first term global DEFAULT_ELEMENT_PADDING # Padding between elements (row, col) in pixels global DEFAULT_AUTOSIZE_TEXT + global DEFAULT_AUTOSIZE_BUTTONS global DEFAULT_FONT global DEFAULT_BORDER_WIDTH global DEFAULT_AUTOCLOSE_TIME @@ -2119,9 +2132,12 @@ def SetOptions(icon=None, button_color=(None,None), element_size=(None,None), ma if element_padding != (None,None): DEFAULT_ELEMENT_PADDING = element_padding - if auto_size_text: + if auto_size_text != None: DEFAULT_AUTOSIZE_TEXT = auto_size_text + if auto_size_buttons != None: + DEFAULT_AUTOSIZE_BUTTONS = auto_size_buttons + if font !=None: DEFAULT_FONT = font @@ -2201,4 +2217,20 @@ def ObjToString(obj, extra=' '): (extra + (str(item) + ' = ' + (ObjToString(obj.__dict__[item], extra + ' ') if hasattr(obj.__dict__[item], '__dict__') else str( obj.__dict__[item]))) - for item in sorted(obj.__dict__))) \ No newline at end of file + for item in sorted(obj.__dict__))) + + +def main(): + with FlexForm('Demo form..', auto_size_text=True) as form: + form_rows = [[Text('You are running the PySimpleGUI.py file itself')], + [Text('You should be importing it rather than running it\n')], + [Text('Here is your sample input form....')], + [Text('Source Folder', size=(15, 1), auto_size_text=False, justification='right'), InputText('Source'),FolderBrowse()], + [Text('Destination Folder', size=(15, 1), auto_size_text=False, justification='right'), InputText('Dest'), FolderBrowse()], + [Submit(), Cancel()]] + + button, (source, dest) = form.LayoutAndRead(form_rows) + +if __name__ == '__main__': + main() + exit(69)