diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 5b08788d..1b0a4ad0 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -459,6 +459,15 @@ class Element(): if self.ParentForm.CurrentlyRunningMainloop: self.ParentForm.TKroot.quit() + def ClickHandler(self, event): + if self.Key is not None: + self.ParentForm.LastButtonClicked = self.Key + else: + self.ParentForm.LastButtonClicked = '' + self.ParentForm.FormRemainedOpen = True + if self.ParentForm.CurrentlyRunningMainloop: + self.ParentForm.TKroot.quit() + def __del__(self): try: @@ -1627,7 +1636,7 @@ class ProgressBar(Element): # ---------------------------------------------------------------------- # class Image(Element): def __init__(self, filename=None, data=None, background_color=None, size=(None, None), pad=None, key=None, - tooltip=None, visible=True): + tooltip=None, visible=True, enable_events=False): ''' Image Element :param filename: @@ -1644,6 +1653,8 @@ class Image(Element): self.BackgroundColor = background_color if data is None and filename is None: print('* Warning... no image specified in Image Element! *') + self.EnableEvents = enable_events + super().__init__(ELEM_TYPE_IMAGE, size=size, background_color=background_color, pad=pad, key=key, tooltip=tooltip, visible=visible) return @@ -2203,8 +2214,7 @@ class TabGroup(Element): # Slider # # ---------------------------------------------------------------------- # class Slider(Element): - def __init__(self, range=(None, None), default_value=None, resolution=None, tick_interval=None, orientation=None, - border_width=None, relief=None, change_submits=False, enable_events=False, disabled=False, size=(None, None), font=None, background_color=None, text_color=None, key=None, pad=None, tooltip=None, visible=True): + def __init__(self, range=(None, None), default_value=None, resolution=None, tick_interval=None, orientation=None, disable_number_display=False, border_width=None, relief=None, change_submits=False, enable_events=False, disabled=False, size=(None, None), font=None, background_color=None, text_color=None, key=None, pad=None, tooltip=None, visible=True): ''' Slider Element :param range: @@ -2233,6 +2243,7 @@ class Slider(Element): self.ChangeSubmits = change_submits or enable_events self.Disabled = disabled self.TickInterval = tick_interval + self.DisableNumericDisplay = disable_number_display temp_size = size if temp_size == (None, None): temp_size = (20, 20) if self.Orientation.startswith('h') else (8, 20) @@ -4726,6 +4737,9 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): if element.Tooltip is not None: element.TooltipObject = ToolTip(element.tktext_label, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME) + if element.EnableEvents: + element.tktext_label.bind('', element.ClickHandler) + # ------------------------- Canvas element ------------------------- # elif element_type == ELEM_TYPE_CANVAS: width, height = element_size @@ -4914,6 +4928,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): tkscale.configure(background=element.BackgroundColor) if DEFAULT_SCROLLBAR_COLOR != COLOR_SYSTEM_DEFAULT: tkscale.config(troughcolor=DEFAULT_SCROLLBAR_COLOR) + if element.DisableNumericDisplay: + tkscale.config(showvalue=0) if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT: tkscale.configure(fg=text_color) tkscale.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1]) diff --git a/docs/cookbook.md b/docs/cookbook.md index beca3b23..b8478913 100644 --- a/docs/cookbook.md +++ b/docs/cookbook.md @@ -718,7 +718,73 @@ This simple program keep a window open, taking input values until the user termi break ``` - + ## One Element Updating Another + +You can easily build "compound elements" in a single like of code. This recipe shows you how to add a numeric value onto a slider. + +```python +import PySimpleGUI as sg + +layout = [[sg.Text('Slider Demonstration'), sg.Text('', key='_OUTPUT_')], + [sg.T('0',key='_LEFT_'), + sg.Slider((1,100), key='_SLIDER_', orientation='h', enable_events=True, disable_number_display=True), + sg.T('0', key='_RIGHT_')], + [sg.Button('Show'), sg.Button('Exit')]] + +window = sg.Window('Window Title').Layout(layout) + +while True: # Event Loop + event, values = window.Read() + print(event, values) + if event is None or event == 'Exit': + break + window.Element('_LEFT_').Update(values['_SLIDER_']) + window.Element('_RIGHT_').Update(values['_SLIDER_']) + +window.Close() +``` + +## Multiple Windows + +This recipe is a design pattern for multiple windows where the first window is not active while the second window is showing. The first window is hidden to discourage continued interaction. + + +```Python +""" + PySimpleGUI The Complete Course Lesson 7 - Multiple Windows""" +import PySimpleGUI as sg + +# Design pattern 1 - First window does not remain active + +layout = [[ sg.Text('Window 1'),], + [sg.Input(do_not_clear=True)], + [sg.Text('', key='_OUTPUT_')], + [sg.Button('Launch 2')]] + +win1 = sg.Window('Window 1').Layout(layout) +win2_active=False +while True: + ev1, vals1 = win1.Read(timeout=100) + if ev1 is None: + break + win1.FindElement('_OUTPUT_').Update(vals1[0]) + + if ev1 == 'Launch 2' and not win2_active: + win2_active = True + win1.Hide() + layout2 = [[sg.Text('Window 2')], # note must create a layout from scratch every time. No reuse + [sg.Button('Exit')]] + + win2 = sg.Window('Window 2').Layout(layout2) + while True: + ev2, vals2 = win2.Read() + if ev2 is None or ev2 == 'Exit': + win2.Close() + win2_active = False + win1.UnHide() + break +``` + ## 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: