From 1889a706f864f99a588a54b56aeda53d0bdf5d81 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Tue, 21 Aug 2018 20:21:03 -0400 Subject: [PATCH 1/8] Fix mouse up bug --- PySimpleGUI.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 4dae3cb9..5b8202ac 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -867,7 +867,6 @@ 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=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, return_keyboard_events=False, use_default_focus=True, text_justification=None): 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 @@ -1035,7 +1034,6 @@ class FlexForm: return BuildResults(self, False, self) def KeyboardCallback(self, event ): - self.LastButtonClicked = None self.FormRemainedOpen = True if event.char != '': @@ -1049,13 +1047,12 @@ class FlexForm: def MouseWheelCallback(self, event ): self.LastButtonClicked = None self.FormRemainedOpen = True - self.LastKeyboardEvent = 'MouseWheel:' + 'Down' if event.delta < 0 else 'Up' + self.LastKeyboardEvent = 'MouseWheel:Down' if event.delta < 0 else 'MouseWheel:Up' if not self.NonBlocking: BuildResults(self, False, self) self.TKroot.quit() - def _Close(self): try: self.TKroot.update() @@ -1817,7 +1814,6 @@ def StartupTK(my_flex_form): # root.bind('', MyFlexForm.DestroyedCallback()) ConvertFlexToTK(my_flex_form) my_flex_form.SetIcon(my_flex_form.WindowIcon) - if my_flex_form.ReturnKeyboardEvents and not my_flex_form.NonBlocking: root.bind("", my_flex_form.KeyboardCallback) root.bind("", my_flex_form.MouseWheelCallback) From 150779ba1c745f84106799e922367691d75dd1c2 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 11:37:51 -0400 Subject: [PATCH 2/8] New "get" methods. Get+Update for Checkboxes, Get for TextInput, Get for Multiline, New shortcut funcs --- PySimpleGUI.py | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 5b8202ac..ef4e8e77 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -239,6 +239,9 @@ class InputText(Element): def Update(self, new_value): self.TKStringVar.set(new_value) + def Get(self): + return self.TKStringVar.get() + def __del__(self): super().__del__() @@ -359,15 +362,22 @@ class Checkbox(Element): self.Text = text self.InitialState = default self.Value = None - self.TKCheckbox = None + self.TKCheckbutton = None super().__init__(ELEM_TYPE_INPUT_CHECKBOX, scale=scale, size=size, auto_size_text=auto_size_text, font=font, background_color=background_color, text_color=text_color, key=key) + def Get(self): + return self.TKIntVar.get() + + def Update(self, value): + if value is None: + self.TKCheckbutton.configure(state='disabled') + else: + self.TKCheckbutton.configure(state='normal') + self.TKIntVar.set(value) + + def __del__(self): - try: - self.TKCheckbox.__del__() - except: - pass super().__del__() # ---------------------------------------------------------------------- # @@ -431,6 +441,10 @@ class Multiline(Element): def Update(self, NewValue): self.TKText.insert(1.0, NewValue) + def Get(self): + return self.TKText.get(1.0, tk.END) + + def __del__(self): super().__del__() @@ -521,7 +535,7 @@ class TKProgressBar(): # 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 +# Scroll bar will span the length of the frame # # ---------------------------------------------------------------------- # class TKOutput(tk.Frame): def __init__(self, parent, width, height, bd, background_color=None, text_color=None): @@ -1134,6 +1148,11 @@ def In(default_text ='', scale=(None, None), size=(None, None), auto_size_text=N def Input(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, do_not_clear=False, key=None, focus=False): return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, password_char=password_char, background_color=background_color, text_color=text_color, do_not_clear=do_not_clear, focus=focus, key=key) +# ------------------------- CHECKBOX Element lazy functions ------------------------- # +CB = Checkbox +CBox = Checkbox +Check = Checkbox + # ------------------------- INPUT COMBO Element lazy functions ------------------------- # 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) From b975c4f18872712481d7efc88ac2a64d3c0ec496 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 13:58:04 -0400 Subject: [PATCH 3/8] Image.Update now resizes TK Label that contains it, removed wraplen setting in text label configure Having trouble with text wrapping. Ended up removing the wraplen from call to tktext_label.configure. --- PySimpleGUI.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index ef4e8e77..f2d112ff 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -788,7 +788,8 @@ class Image(Element): else: image = data else: return - self.tktext_label.configure(image=image) + width, height = image.width(), image.height() + self.tktext_label.configure(image=image, width=width, height=height) self.tktext_label.image = image def __del__(self): @@ -1454,7 +1455,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, text=display_text, width=width, height=height, justify=tk.LEFT, bd=border_depth) # Set wrap-length for text (in PIXELS) == PAIN IN THE ASS wraplen = tktext_label.winfo_reqwidth() # width of widget in Pixels - tktext_label.configure(anchor=anchor, font=font, wraplen=wraplen*2 ) # set wrap to width of widget + tktext_label.configure(anchor=anchor, font=font) # set wrap to width of widget if element.BackgroundColor is not None: tktext_label.configure(background=element.BackgroundColor) if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None: From 945625b388a0226e9c5f475c55ff82a4afd7560e Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 14:35:33 -0400 Subject: [PATCH 4/8] More Wraplength changes for Text Elements Struggling to get wrapping to work --- PySimpleGUI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index f2d112ff..c3fb2e94 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1455,7 +1455,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, text=display_text, width=width, height=height, justify=tk.LEFT, bd=border_depth) # Set wrap-length for text (in PIXELS) == PAIN IN THE ASS wraplen = tktext_label.winfo_reqwidth() # width of widget in Pixels - tktext_label.configure(anchor=anchor, font=font) # set wrap to width of widget + tktext_label.configure(anchor=anchor, font=font, wraplen=wraplen+10) # set wrap to width of widget if element.BackgroundColor is not None: tktext_label.configure(background=element.BackgroundColor) if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None: From 3f64564ad212e9408516b4f8b03c9e1db671b362 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 15:48:28 -0400 Subject: [PATCH 5/8] Fix for column crash due to keyboard feature, struggling with message box sizes and wrapping --- PySimpleGUI.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index c3fb2e94..b9c9b24a 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1351,9 +1351,12 @@ def BuildResultsForSubform(form, initialize_only, top_level_form): AddToReturnList(form, value) AddToReturnDictionary(top_level_form, element, value) - if form.ReturnKeyboardEvents and form.LastKeyboardEvent is not None: - button_pressed_text = form.LastKeyboardEvent - form.LastKeyboardEvent = None + # if this is a column, then will fail so need to wrap with tr + try: + if form.ReturnKeyboardEvents and form.LastKeyboardEvent is not None: + button_pressed_text = form.LastKeyboardEvent + form.LastKeyboardEvent = None + except: pass try: form.ReturnValuesDictionary.pop(None, None) # clean up dictionary include None was included @@ -1455,12 +1458,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, text=display_text, width=width, height=height, justify=tk.LEFT, bd=border_depth) # Set wrap-length for text (in PIXELS) == PAIN IN THE ASS wraplen = tktext_label.winfo_reqwidth() # width of widget in Pixels - tktext_label.configure(anchor=anchor, font=font, wraplen=wraplen+10) # set wrap to width of widget + tktext_label.configure(anchor=anchor, font=font, wraplen=0) # set wrap to width of widget if element.BackgroundColor is not None: tktext_label.configure(background=element.BackgroundColor) if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None: tktext_label.configure(fg=element.TextColor) tktext_label.pack(side=tk.LEFT) + # print(f'Text element placed w = {width}, h = {height}, wrap = {wraplen}') # ------------------------- BUTTON element ------------------------- # elif element_type == ELEM_TYPE_BUTTON: element.Location = (row_num, col_num) @@ -1921,7 +1925,7 @@ def MsgBox(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, a max_line_total = max(max_line_total, width_used) # height = _GetNumLinesNeeded(message, width_used) height = message_wrapped_lines - form.AddRow(Text(message_wrapped, auto_size_text=True)) + form.AddRow(Text(message_wrapped, auto_size_text=True, size=(width_used, height))) total_lines += height pad = max_line_total-15 if max_line_total > 15 else 1 @@ -2665,7 +2669,7 @@ def ObjToString(obj, extra=' '): def main(): with FlexForm('Demo form..') 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('You should be importing it rather than running it', size=(50,2))], [Text('Here is your sample input form....')], [Text('Source Folder', size=(15, 1), justification='right'), InputText('Source', focus=True),FolderBrowse()], [Text('Destination Folder', size=(15, 1), justification='right'), InputText('Dest'), FolderBrowse()], From 6547a1b689ab2534ef0cc1ef1fe19101c5b3a9ed Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 17:01:30 -0400 Subject: [PATCH 6/8] Demo of PNG file viewer --- Demo_PNG_Viewer.py | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 Demo_PNG_Viewer.py diff --git a/Demo_PNG_Viewer.py b/Demo_PNG_Viewer.py new file mode 100644 index 00000000..463f3a8c --- /dev/null +++ b/Demo_PNG_Viewer.py @@ -0,0 +1,56 @@ +import PySimpleGUI as sg +import os + +# Simple Image Browser based on PySimpleGUI + +# sg.ChangeLookAndFeel('GreenTan') + +# Get the folder containing the images from the user +rc, folder = sg.GetPathBox('Image Browser', 'Image folder to open', default_path='A:/TEMP/PDFs') +if rc is False or folder is '': + sg.MsgBoxCancel('Cancelling') + exit(0) + +# get list of PNG files in folder +png_files = [folder + '\\' + f for f in os.listdir(folder) if '.png' in f] + +if len(png_files) == 0: + sg.MsgBox('No PNG images in folder') + exit(0) + +# create the form +form = sg.FlexForm('Image Browser', return_keyboard_events=True) + +# make these 2 elements outside the layout because want to "update" them later +image_elem = sg.Image(filename=png_files[0]) +text_elem = sg.Text(png_files[0], size=(80,3)) + +# define layout, show and read the form +layout = [[text_elem], + [image_elem], + [sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2))]] + +form.LayoutAndRead(layout) + +# loop reading the user input and display each image and the filename +i=0 +while True: + f = png_files[i] + # update window with new image + image_elem.Update(filename=f) + # update window with filename + text_elem.Update(f) + # read the form + button, values = form.Read() + + # perform button operations + if button is None: + break + elif button in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34') and i < len(png_files): + i += 1 + elif button in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33') and i > 0: + i -= 1 + # else: + # print(button) + + From b1829438a952e72f641e6e36f82eed0e1ebb5c83 Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 17:14:58 -0400 Subject: [PATCH 7/8] Adjusted wraplength, Updated demo program that displays PNG files --- Demo_PNG_Viewer.py | 25 +++++++++++++------------ PySimpleGUI.py | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Demo_PNG_Viewer.py b/Demo_PNG_Viewer.py index 463f3a8c..4729d9c3 100644 --- a/Demo_PNG_Viewer.py +++ b/Demo_PNG_Viewer.py @@ -3,8 +3,6 @@ import os # Simple Image Browser based on PySimpleGUI -# sg.ChangeLookAndFeel('GreenTan') - # Get the folder containing the images from the user rc, folder = sg.GetPathBox('Image Browser', 'Image folder to open', default_path='A:/TEMP/PDFs') if rc is False or folder is '': @@ -18,39 +16,42 @@ if len(png_files) == 0: sg.MsgBox('No PNG images in folder') exit(0) -# create the form +# create the form that also returns keyboard events form = sg.FlexForm('Image Browser', return_keyboard_events=True) # make these 2 elements outside the layout because want to "update" them later +# initialize to the first PNG file in the list image_elem = sg.Image(filename=png_files[0]) -text_elem = sg.Text(png_files[0], size=(80,3)) +filename_display_elem = sg.Text(png_files[0], size=(80, 3)) +file_num_display_elem = sg.Text('File 1 of {}'.format(len(png_files)), size=(10,1)) # define layout, show and read the form -layout = [[text_elem], +layout = [[filename_display_elem], [image_elem], - [sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2))]] + [sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2)), file_num_display_elem]] -form.LayoutAndRead(layout) +form.LayoutAndRead(layout) # Shows form on screen -# loop reading the user input and display each image and the filename +# loop reading the user input and displaying image, filename i=0 while True: f = png_files[i] # update window with new image image_elem.Update(filename=f) # update window with filename - text_elem.Update(f) + filename_display_elem.Update(f) + # update page display + file_num_display_elem.Update('File {} of {}'.format(i+1, len(png_files))) # read the form button, values = form.Read() - # perform button operations + # perform button and keyboard operations if button is None: break elif button in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34') and i < len(png_files): i += 1 elif button in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33') and i > 0: i -= 1 - # else: - # print(button) + diff --git a/PySimpleGUI.py b/PySimpleGUI.py index b9c9b24a..0233c23d 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1458,7 +1458,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # tktext_label = tk.Label(tk_row_frame,anchor=tk.NW, text=display_text, width=width, height=height, justify=tk.LEFT, bd=border_depth) # Set wrap-length for text (in PIXELS) == PAIN IN THE ASS wraplen = tktext_label.winfo_reqwidth() # width of widget in Pixels - tktext_label.configure(anchor=anchor, font=font, wraplen=0) # set wrap to width of widget + tktext_label.configure(anchor=anchor, font=font, wraplen=wraplen+40) # set wrap to width of widget if element.BackgroundColor is not None: tktext_label.configure(background=element.BackgroundColor) if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None: From 8f4e0e182a7e70bc6fac42edceaa105b38c7a8be Mon Sep 17 00:00:00 2001 From: MikeTheWatchGuy Date: Wed, 22 Aug 2018 17:47:32 -0400 Subject: [PATCH 8/8] New GetScreenDimension method for FlexForms --- PySimpleGUI.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 0233c23d..9fa1ca91 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1048,6 +1048,14 @@ class FlexForm: _my_windows.Decrement() return BuildResults(self, False, self) + def GetScreenDimensions(self): + if self.TKrootDestroyed: + return None, None + screen_width = self.TKroot.winfo_screenwidth() # get window info to move to middle of screen + screen_height = self.TKroot.winfo_screenheight() + return screen_width, screen_height + + def KeyboardCallback(self, event ): self.LastButtonClicked = None self.FormRemainedOpen = True