Fixes, listbox scroll bars, more button lazy funcs,
Fixed output element scrollbar length Added scroll bar to listbox New FileSaveAs, SaveAs, Save, Exit button functions Fixed button width bug Fixed button outline around images on Raspberry Pi Set border width = 0 for sliders
This commit is contained in:
parent
cf9b11e75c
commit
6ef5af6746
108
PySimpleGUI.py
108
PySimpleGUI.py
|
@ -100,6 +100,14 @@ class MyWindows():
|
|||
self.NumOpenWindows = 0
|
||||
self.user_defined_icon = None
|
||||
|
||||
def Decrement(self):
|
||||
self.NumOpenWindows -= 1 * (self.NumOpenWindows != 0) # decrement if not 0
|
||||
print('---- DECREMENTING Num Open Windows = {} ---'.format(self.NumOpenWindows))
|
||||
|
||||
def Increment(self):
|
||||
self.NumOpenWindows += 1
|
||||
print('++++ INCREMENTING Num Open Windows = {} ++++'.format(self.NumOpenWindows))
|
||||
|
||||
_my_windows = MyWindows() # terrible hack using globals... means need a class for collecing windows
|
||||
|
||||
# ====================================================================== #
|
||||
|
@ -116,6 +124,7 @@ def RGB(red,green,blue): return '#%02x%02x%02x' % (red,green,blue)
|
|||
# class ButtonType(Enum):
|
||||
BUTTON_TYPE_BROWSE_FOLDER = 1
|
||||
BUTTON_TYPE_BROWSE_FILE = 2
|
||||
BUTTON_TYPE_SAVEAS_FILE = 3
|
||||
BUTTON_TYPE_CLOSES_WIN = 5
|
||||
BUTTON_TYPE_READ_FORM = 7
|
||||
BUTTON_TYPE_REALTIME = 9
|
||||
|
@ -261,7 +270,7 @@ class InputCombo(Element):
|
|||
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Combo #
|
||||
# Listbox #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class Listbox(Element):
|
||||
|
||||
|
@ -514,16 +523,18 @@ class TKProgressBar():
|
|||
# ---------------------------------------------------------------------- #
|
||||
class TKOutput(tk.Frame):
|
||||
def __init__(self, parent, width, height, bd, background_color=None, text_color=None):
|
||||
tk.Frame.__init__(self, parent)
|
||||
self.output = tk.Text(parent, width=width, height=height, bd=bd)
|
||||
frame = tk.Frame(parent, width=width, height=height)
|
||||
tk.Frame.__init__(self, frame)
|
||||
self.output = tk.Text(frame, width=width, height=height, bd=bd)
|
||||
if background_color and background_color != COLOR_SYSTEM_DEFAULT:
|
||||
self.output.configure(background=background_color)
|
||||
if text_color and text_color != COLOR_SYSTEM_DEFAULT:
|
||||
self.output.configure(fg=text_color)
|
||||
self.vsb = tk.Scrollbar(parent, orient="vertical", command=self.output.yview)
|
||||
self.vsb = tk.Scrollbar(frame, orient="vertical", command=self.output.yview)
|
||||
self.output.configure(yscrollcommand=self.vsb.set)
|
||||
self.output.pack(side="left", fill="both", expand=True)
|
||||
self.output.pack(side="left", fill="both")
|
||||
self.vsb.pack(side="left", fill="y")
|
||||
frame.pack(side="left")
|
||||
self.previous_stdout = sys.stdout
|
||||
self.previous_stderr = sys.stderr
|
||||
|
||||
|
@ -650,6 +661,9 @@ class Button(Element):
|
|||
elif self.BType == BUTTON_TYPE_BROWSE_FILE:
|
||||
file_name = tk.filedialog.askopenfilename(filetypes=filetypes) # show the 'get file' dialog box
|
||||
strvar.set(file_name)
|
||||
elif self.BType == BUTTON_TYPE_SAVEAS_FILE:
|
||||
file_name = tk.filedialog.asksaveasfilename(filetypes=filetypes) # show the 'get file' dialog box
|
||||
strvar.set(file_name)
|
||||
elif self.BType == BUTTON_TYPE_CLOSES_WIN: # this is a return type button so GET RESULTS and destroy window
|
||||
# first, get the results table built
|
||||
# modify the Results table in the parent FlexForm object
|
||||
|
@ -664,7 +678,7 @@ class Button(Element):
|
|||
self.ParentForm.TKroot.quit()
|
||||
if self.ParentForm.NonBlocking:
|
||||
self.ParentForm.TKroot.destroy()
|
||||
# _my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
_my_windows.Decrement()
|
||||
elif self.BType == BUTTON_TYPE_READ_FORM: # LEAVE THE WINDOW OPEN!! DO NOT CLOSE
|
||||
# first, get the results table built
|
||||
# modify the Results table in the parent FlexForm object
|
||||
|
@ -718,7 +732,7 @@ class ProgressBar(Element):
|
|||
try:
|
||||
self.ParentForm.TKroot.update()
|
||||
except:
|
||||
# _my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
# _my_windows.Decrement()
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -968,7 +982,7 @@ class FlexForm:
|
|||
self.TKroot.mainloop()
|
||||
if self.RootNeedsDestroying:
|
||||
self.TKroot.destroy()
|
||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
_my_windows.Decrement()
|
||||
return BuildResults(self, False, self)
|
||||
|
||||
def ReadNonBlocking(self, Message=''):
|
||||
|
@ -982,7 +996,7 @@ class FlexForm:
|
|||
rc = self.TKroot.update()
|
||||
except:
|
||||
self.TKrootDestroyed = True
|
||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
_my_windows.Decrement()
|
||||
return BuildResults(self, False, self)
|
||||
|
||||
|
||||
|
@ -999,10 +1013,12 @@ class FlexForm:
|
|||
return None
|
||||
|
||||
def CloseNonBlockingForm(self):
|
||||
if self.TKrootDestroyed:
|
||||
return
|
||||
try:
|
||||
self.TKroot.destroy()
|
||||
_my_windows.Decrement()
|
||||
except: pass
|
||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
|
||||
def OnClosingCallback(self):
|
||||
return
|
||||
|
@ -1049,7 +1065,7 @@ class UberForm():
|
|||
if not self.TKrootDestroyed:
|
||||
self.TKrootDestroyed = True
|
||||
self.TKroot.destroy()
|
||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
_my_windows.Decrement()
|
||||
|
||||
def __del__(self):
|
||||
return
|
||||
|
@ -1082,24 +1098,36 @@ 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_button=None, button_color=None):
|
||||
def FolderBrowse(target=(ThisRow, -1), button_text='Browse', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
return Button(BUTTON_TYPE_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_button=None, button_color=None):
|
||||
return Button(BUTTON_TYPE_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)
|
||||
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, font=None):
|
||||
return Button(BUTTON_TYPE_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, font=font)
|
||||
|
||||
# ------------------------- FILE BROWSE Element lazy function ------------------------- #
|
||||
def FileSaveAs(target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), button_text='Save As...', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
return Button(BUTTON_TYPE_SAVEAS_FILE, target, button_text=button_text, file_types=file_types, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font)
|
||||
|
||||
# ------------------------- SAVE AS Element lazy function ------------------------- #
|
||||
def SaveAs(target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), button_text='Save As...', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
return Button(BUTTON_TYPE_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, font=font)
|
||||
|
||||
# ------------------------- SAVE BUTTON Element lazy function ------------------------- #
|
||||
def Save(button_text='Save', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True,font=None, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color,font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- SUBMIT BUTTON Element lazy function ------------------------- #
|
||||
def Submit(button_text='Submit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, bind_return_key=bind_return_key, focus=focus)
|
||||
def Submit(button_text='Submit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True,font=None, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color,font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- OK BUTTON Element lazy function ------------------------- #
|
||||
def OK(button_text='OK', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, bind_return_key=bind_return_key, focus=focus)
|
||||
def OK(button_text='OK', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True, font=None,focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color,font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- YES BUTTON Element lazy function ------------------------- #
|
||||
def Ok(button_text='Ok', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, bind_return_key=bind_return_key, focus=focus)
|
||||
def Ok(button_text='Ok', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True, font=None,focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- CANCEL BUTTON Element lazy function ------------------------- #
|
||||
def Cancel(button_text='Cancel', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None, bind_return_key=False, focus=False):
|
||||
|
@ -1109,13 +1137,17 @@ def Cancel(button_text='Cancel', scale=(None, None), size=(None, None), auto_siz
|
|||
def Quit(button_text='Quit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None, bind_return_key=False, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- Exit BUTTON Element lazy function ------------------------- #
|
||||
def Exit(button_text='Exit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None, bind_return_key=False, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- YES BUTTON Element lazy function ------------------------- #
|
||||
def Yes(button_text='Yes', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=True, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, bind_return_key=bind_return_key, focus=focus)
|
||||
def Yes(button_text='Yes', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None,font=None, bind_return_key=True, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- NO BUTTON Element lazy function ------------------------- #
|
||||
def No(button_text='No', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, bind_return_key=False, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, bind_return_key=bind_return_key, focus=focus)
|
||||
def No(button_text='No', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None,font=None, bind_return_key=False, focus=False):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font, bind_return_key=bind_return_key, focus=focus)
|
||||
|
||||
# ------------------------- GENERIC BUTTON Element lazy function ------------------------- #
|
||||
# this is the only button that REQUIRES button text field
|
||||
|
@ -1378,6 +1410,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKButton = tkbutton # not used yet but save the TK button in case
|
||||
wraplen = tkbutton.winfo_reqwidth() # width of widget in Pixels
|
||||
if element.ImageFilename: # if button has an image on it
|
||||
tkbutton.config(highlightthickness=0)
|
||||
photo = tk.PhotoImage(file=element.ImageFilename)
|
||||
if element.ImageSize != (None, None):
|
||||
width, height = element.ImageSize
|
||||
|
@ -1387,7 +1420,10 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
width, height = photo.width(), photo.height()
|
||||
tkbutton.config(image=photo, width=width, height=height)
|
||||
tkbutton.image = photo
|
||||
if width != 0:
|
||||
tkbutton.configure(wraplength=wraplen+10, font=font) # set wrap to width of widget
|
||||
else:
|
||||
tkbutton.configure(font=font) # only set the font, not wraplength
|
||||
tkbutton.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
|
||||
if element.Focus is True or (toplevel_form.UseDefaultFocus and not focus_set):
|
||||
focus_set = True
|
||||
|
@ -1452,9 +1488,9 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
max_line_len = max([len(str(l)) for l in element.Values])
|
||||
if auto_size_text is False: width=element_size[0]
|
||||
else: width = max_line_len
|
||||
|
||||
listbox_frame = tk.Frame(tk_row_frame)
|
||||
element.TKStringVar = tk.StringVar()
|
||||
element.TKListbox= tk.Listbox(tk_row_frame, height=element_size[1], width=width, selectmode=element.SelectMode, font=font)
|
||||
element.TKListbox= tk.Listbox(listbox_frame, height=element_size[1], width=width, selectmode=element.SelectMode, font=font)
|
||||
for item in element.Values:
|
||||
element.TKListbox.insert(tk.END, item)
|
||||
element.TKListbox.selection_set(0,0)
|
||||
|
@ -1462,10 +1498,11 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKListbox.configure(background=element.BackgroundColor)
|
||||
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||
element.TKListbox.configure(fg=text_color)
|
||||
# vsb = tk.Scrollbar(tk_row_frame, orient="vertical", command=element.TKListbox.yview)
|
||||
# element.TKListbox.configure(yscrollcommand=vsb.set)
|
||||
element.TKListbox.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||
# vsb.pack(side=tk.LEFT, fill='y')
|
||||
vsb = tk.Scrollbar(listbox_frame, orient="vertical", command=element.TKListbox.yview)
|
||||
element.TKListbox.configure(yscrollcommand=vsb.set)
|
||||
element.TKListbox.pack(side=tk.LEFT)
|
||||
vsb.pack(side=tk.LEFT, fill='y')
|
||||
listbox_frame.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||
# ------------------------- INPUT MULTI LINE element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_MULTILINE:
|
||||
default_text = element.DefaultText
|
||||
|
@ -1563,7 +1600,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
tktext_label = tk.Label(tk_row_frame, image=photo, width=width, height=height, bd=border_depth)
|
||||
tktext_label.image = photo
|
||||
# tktext_label.configure(anchor=tk.NW, image=photo)
|
||||
tktext_label.pack(side=tk.LEFT)
|
||||
tktext_label.pack(side=tk.LEFT, padx=element.Pad[0],pady=element.Pad[1])
|
||||
# ------------------------- SLIDER Box element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_SLIDER:
|
||||
slider_length = element_size[0] * CharWidthInPixels()
|
||||
|
@ -1579,12 +1616,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
range_to = element.Range[1]
|
||||
tkscale = tk.Scale(tk_row_frame, orient=element.Orientation, variable=element.TKIntVar, from_=range_from, to_=range_to, length=slider_length, width=slider_width , bd=element.BorderWidth, relief=element.Relief, font=font)
|
||||
# tktext_label.configure(anchor=tk.NW, image=photo)
|
||||
tkscale.config(highlightthickness=0)
|
||||
if element.BackgroundColor is not None:
|
||||
tkscale.configure(background=element.BackgroundColor)
|
||||
tkscale.config(troughcolor=DEFAULT_SCROLLBAR_COLOR)
|
||||
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||
tkscale.configure(fg=text_color)
|
||||
tkscale.pack(side=tk.LEFT)
|
||||
tkscale.pack(side=tk.LEFT, padx=element.Pad[0],pady=element.Pad[1])
|
||||
#............................DONE WITH ROW pack the row of widgets ..........................#
|
||||
# done with row, pack the row of widgets
|
||||
tk_row_frame.grid(row=row_num+2, sticky=tk.NW, padx=DEFAULT_MARGINS[0])
|
||||
|
@ -1698,7 +1736,7 @@ def StartupTK(my_flex_form):
|
|||
root = tk.Tk() if not ow else tk.Toplevel()
|
||||
if my_flex_form.BackgroundColor is not None:
|
||||
root.configure(background=my_flex_form.BackgroundColor)
|
||||
_my_windows.NumOpenWindows += 1
|
||||
_my_windows.Increment()
|
||||
|
||||
my_flex_form.TKroot = root
|
||||
# root.protocol("WM_DELETE_WINDOW", MyFlexForm.DestroyedCallback())
|
||||
|
@ -1716,7 +1754,7 @@ def StartupTK(my_flex_form):
|
|||
my_flex_form.TKroot.mainloop()
|
||||
# print('..... BACK from MainLoop')
|
||||
if not my_flex_form.FormRemainedOpen:
|
||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
_my_windows.Decrement()
|
||||
if my_flex_form.RootNeedsDestroying:
|
||||
my_flex_form.TKroot.destroy()
|
||||
my_flex_form.RootNeedsDestroying = False
|
||||
|
@ -1992,8 +2030,8 @@ def _ProgressMeterUpdate(bar, value, text_elem, *args):
|
|||
bar.ParentForm._Close()
|
||||
if bar.ParentForm.RootNeedsDestroying:
|
||||
try:
|
||||
_my_windows.NumOpenWindows -= 1 * (_my_windows.NumOpenWindows != 0) # decrement if not 0
|
||||
bar.ParentForm.TKroot.destroy()
|
||||
_my_windows.Decrement()
|
||||
except: pass
|
||||
bar.ParentForm.RootNeedsDestroying = False
|
||||
bar.ParentForm.__del__()
|
||||
|
|
Loading…
Reference in New Issue