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:
MikeTheWatchGuy 2018-08-18 16:55:21 -04:00
parent cf9b11e75c
commit 6ef5af6746
1 changed files with 74 additions and 36 deletions

View File

@ -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
tkbutton.configure(wraplength=wraplen+10, font=font) # set wrap to width of widget
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__()