From 421e96e800bfd68756ab8fb8eac2c2a3825ddf27 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Sep 2018 10:51:19 -0400 Subject: [PATCH 1/3] Font sizer - fixed exit detection. Change Submits for Slider - don't setup unless change_submits flag is set --- Demo_Font_Sizer.py | 4 ++-- PySimpleGUI.py | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/Demo_Font_Sizer.py b/Demo_Font_Sizer.py index 7a5e0b8f..4874437c 100644 --- a/Demo_Font_Sizer.py +++ b/Demo_Font_Sizer.py @@ -8,7 +8,7 @@ form = sg.FlexForm("Font size selector") fontSize = 12 sampleText = sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontSize)) -slider = sg.Slider(range=(6,50), orientation='h', size=(10,20), change_submits=True, key='slider') +slider = sg.Slider(range=(6,50), orientation='h', size=(10,20), change_submits=False, key='slider') spin = sg.Spin([sz for sz in range(4,72)], font=('Helvetica 20'), initial_value=fontSize, change_submits=True, key='spin') layout = [ [sampleText, spin, slider], @@ -19,7 +19,7 @@ sz = fontSize form.Layout(layout) while True: button, values= form.Read() - if button is None: + if button in (None, 'OK', 'Cancel'): break sz_spin = int(values['spin']) sz_slider = int(values['slider']) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 02260b3a..419213c3 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -937,6 +937,37 @@ class Slider(Element): super().__del__() +# ---------------------------------------------------------------------- # +# TkScrollableFrame (Used by Column (SOON) # +# ---------------------------------------------------------------------- # +# TODO NOT YET WORKING! DO NOT USE. Will be used to make scrollable columns +class TkScrollableFrame(tk.Frame): + def __init__(self, master, **kwargs): + tk.Frame.__init__(self, master, **kwargs) + + # create a canvas object and a vertical scrollbar for scrolling it + self.vscrollbar = tk.Scrollbar(self, orient=tk.VERTICAL) + self.vscrollbar.pack(side='right', fill="y", expand="false") + self.canvas = tk.Canvas(self, yscrollcommand=self.vscrollbar.set) + self.canvas.pack(side="left") + self.vscrollbar.config(command=self.canvas.yview) + + # reset the view + self.canvas.xview_moveto(0) + self.canvas.yview_moveto(0) + + # create a frame inside the canvas which will be scrolled with it + # self.interior = tk.Frame(self.canvas, **kwargs) + # self.canvas.create_window(0, 0, window=self.interior, anchor="nw") + + # self.bind('', self.set_scrollregion) + + + def set_scrollregion(self, event=None): + """ Set the scroll region on the canvas""" + self.canvas.configure(scrollregion=self.canvas.bbox('all')) + + # ---------------------------------------------------------------------- # # Column # # ---------------------------------------------------------------------- # @@ -1576,6 +1607,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # ------------------------- COLUMN element ------------------------- # if element_type == ELEM_TYPE_COLUMN: col_frame = tk.Frame(tk_row_frame) + # col_frame = TkScrollableFrame(tk_row_frame) # do not use yet! not working PackFormIntoFrame(element, col_frame, toplevel_form) col_frame.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1]) if element.BackgroundColor != COLOR_SYSTEM_DEFAULT and element.BackgroundColor is not None: @@ -1886,10 +1918,10 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): else: range_from = element.Range[0] range_to = element.Range[1] - tkscale = tk.Scale(tk_row_frame, orient=element.Orientation, variable=element.TKIntVar, from_=range_from, to_=range_to, resolution = element.Resolution, length=slider_length, width=slider_width , bd=element.BorderWidth, relief=element.Relief, font=font, command=element.SliderChangedHandler) - # if element.ChangeSubmits: - # element.tkscale.bind('', element.SliderChangedHandler) - # tktext_label.configure(anchor=tk.NW, image=photo) + if element.ChangeSubmits: + tkscale = tk.Scale(tk_row_frame, orient=element.Orientation, variable=element.TKIntVar, from_=range_from, to_=range_to, resolution = element.Resolution, length=slider_length, width=slider_width , bd=element.BorderWidth, relief=element.Relief, font=font, command=element.SliderChangedHandler) + else: + tkscale = tk.Scale(tk_row_frame, orient=element.Orientation, variable=element.TKIntVar, from_=range_from, to_=range_to, resolution = element.Resolution, length=slider_length, width=slider_width , bd=element.BorderWidth, relief=element.Relief, font=font) tkscale.config(highlightthickness=0) if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT: tkscale.configure(background=element.BackgroundColor) From a19fb528d4a4a1f2cd01ede489f190345d8f1337 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Sep 2018 11:28:44 -0400 Subject: [PATCH 2/3] NEW ELEMENT - InputOptionMenu / OptionMenu. Acts like a ComboBox but looks better Never heard of this widget before, but after seeing it, had to add it to the list of Element choices! --- PySimpleGUI.py | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 419213c3..be351182 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -140,6 +140,7 @@ BUTTON_TYPE_REALTIME = 9 ELEM_TYPE_TEXT = 1 ELEM_TYPE_INPUT_TEXT = 20 ELEM_TYPE_INPUT_COMBO = 21 +ELEM_TYPE_INPUT_OPTION_MENU = 22 ELEM_TYPE_INPUT_RADIO = 5 ELEM_TYPE_INPUT_MULTILINE = 7 ELEM_TYPE_INPUT_CHECKBOX = 8 @@ -301,6 +302,34 @@ class InputCombo(Element): super().__del__() +# ---------------------------------------------------------------------- # +# Option Menu # +# ---------------------------------------------------------------------- # +class InputOptionMenu(Element): + + def __init__(self, values, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None, text_color=None, key=None, pad=None): + ''' + Input Combo Box Element (also called Dropdown box) + :param values: + :param scale: Adds multiplier to size (w,h) + :param size: Size of field in characters + :param auto_size_text: True if should shrink field to fit the default text + :param background_color: Color for Element. Text or RGB Hex + ''' + self.Values = values + self.TKOptionMenu = None + bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR + fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR + + super().__init__(ELEM_TYPE_INPUT_OPTION_MENU, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=fg, key=key, pad=pad) + + def __del__(self): + try: + self.TKOptionMenu.__del__() + except: + pass + super().__del__() + # ---------------------------------------------------------------------- # # Listbox # # ---------------------------------------------------------------------- # @@ -1326,6 +1355,13 @@ Combo = InputCombo DropDown = InputCombo Drop = InputCombo + +# ------------------------- OPTION MENU Element lazy functions ------------------------- # + +OptionMenu = InputOptionMenu + + + # def Combo(values, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None): # return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text, background_color=background_color) # @@ -1502,6 +1538,8 @@ def BuildResultsForSubform(form, initialize_only, top_level_form): top_level_form.LastButtonClicked = None elif element.Type == ELEM_TYPE_INPUT_COMBO: value=element.TKStringVar.get() + elif element.Type == ELEM_TYPE_INPUT_OPTION_MENU: + value=element.TKStringVar.get() elif element.Type == ELEM_TYPE_INPUT_LISTBOX: try: items=element.TKListbox.curselection() @@ -1758,6 +1796,19 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # element.TKCombo.configure(background=element.BackgroundColor) element.TKCombo.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1]) element.TKCombo.current(0) + # ------------------------- OPTION MENU (Like ComboBox but different) element ------------------------- # + elif element_type == ELEM_TYPE_INPUT_OPTION_MENU: + max_line_len = max([len(str(l)) for l in element.Values]) + element.TKStringVar = tk.StringVar() + element.TKStringVar.set(element.Values[0]) + element.TKOptionMenu = tk.OptionMenu(tk_row_frame, element.TKStringVar ,*element.Values ) + element.TKOptionMenu.config(highlightthickness=0) + element.TKOptionMenu.config(borderwidth=border_depth) + if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT: + element.TKOptionMenu.configure(background=element.BackgroundColor) + if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None: + element.TKOptionMenu.configure(fg=element.TextColor) + element.TKOptionMenu.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1]) # ------------------------- LISTBOX element ------------------------- # elif element_type == ELEM_TYPE_INPUT_LISTBOX: max_line_len = max([len(str(l)) for l in element.Values]) From 209e5ebf25de5deff6811f92b5e33e3dc167ae03 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Sat, 1 Sep 2018 11:37:36 -0400 Subject: [PATCH 3/3] bug fix --- Demo_Font_Sizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Demo_Font_Sizer.py b/Demo_Font_Sizer.py index 4874437c..9107ffef 100644 --- a/Demo_Font_Sizer.py +++ b/Demo_Font_Sizer.py @@ -8,7 +8,7 @@ form = sg.FlexForm("Font size selector") fontSize = 12 sampleText = sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontSize)) -slider = sg.Slider(range=(6,50), orientation='h', size=(10,20), change_submits=False, key='slider') +slider = sg.Slider(range=(6,50), orientation='h', size=(10,20), change_submits=True, key='slider') spin = sg.Spin([sz for sz in range(4,72)], font=('Helvetica 20'), initial_value=fontSize, change_submits=True, key='spin') layout = [ [sampleText, spin, slider],