Focus set and return key handling options
Exposed the ability to set where the initial forus is as well as which elements should be bound to the return key.
This commit is contained in:
parent
4962b02799
commit
49e89c7875
135
PySimpleGUI.py
135
PySimpleGUI.py
|
@ -174,6 +174,15 @@ class Element():
|
|||
self.TextColor = text_color if text_color is not None else DEFAULT_ELEMENT_TEXT_COLOR
|
||||
self.Key = key # dictionary key for return values
|
||||
|
||||
def ReturnKeyHandler(self, event):
|
||||
MyForm = self.ParentForm
|
||||
# search through this form and find the first button that will exit the form
|
||||
for row in MyForm.Rows:
|
||||
for element in row:
|
||||
if element.Type == ELEM_TYPE_BUTTON:
|
||||
if element.BindReturnKey:
|
||||
element.ButtonCallBack()
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
self.TKStringVar.__del__()
|
||||
|
@ -196,7 +205,7 @@ class Element():
|
|||
# Input Class #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class InputText(Element):
|
||||
def __init__(self, default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, key=None):
|
||||
def __init__(self, default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, key=None, focus=False):
|
||||
'''
|
||||
Input a line of text Element
|
||||
:param default_text: Default value to display
|
||||
|
@ -209,17 +218,10 @@ class InputText(Element):
|
|||
self.DefaultText = default_text
|
||||
self.PasswordCharacter = password_char
|
||||
bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR
|
||||
self.Focus = focus
|
||||
super().__init__(ELEM_TYPE_INPUT_TEXT, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=text_color, key=key)
|
||||
|
||||
def ReturnKeyHandler(self, event):
|
||||
MyForm = self.ParentForm
|
||||
# search through this form and find the first button that will exit the form
|
||||
for row in MyForm.Rows:
|
||||
for element in row:
|
||||
if element.Type == ELEM_TYPE_BUTTON:
|
||||
if element.BType == BUTTON_TYPE_CLOSES_WIN or element.BType == BUTTON_TYPE_READ_FORM:
|
||||
element.ButtonCallBack()
|
||||
return
|
||||
|
||||
|
||||
def __del__(self):
|
||||
super().__del__()
|
||||
|
@ -385,7 +387,7 @@ class Spin(Element):
|
|||
# Multiline #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class Multiline(Element):
|
||||
def __init__(self, default_text='', enter_submits = False, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None, text_color=None, key=None):
|
||||
def __init__(self, default_text='', enter_submits = False, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None, text_color=None, key=None, focus=False):
|
||||
'''
|
||||
Input Multi-line Element
|
||||
:param default_text:
|
||||
|
@ -398,18 +400,10 @@ class Multiline(Element):
|
|||
self.DefaultText = default_text
|
||||
self.EnterSubmits = enter_submits
|
||||
bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR
|
||||
self.Focus = focus
|
||||
super().__init__(ELEM_TYPE_INPUT_MULTILINE, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=text_color, key=key)
|
||||
return
|
||||
|
||||
def ReturnKeyHandler(self, event):
|
||||
MyForm = self.ParentForm
|
||||
# search through this form and find the first button that will exit the form
|
||||
for row in MyForm.Rows:
|
||||
for element in row:
|
||||
if element.Type == ELEM_TYPE_BUTTON:
|
||||
if element.BType == BUTTON_TYPE_CLOSES_WIN or element.BType == BUTTON_TYPE_READ_FORM:
|
||||
element.ButtonCallBack()
|
||||
return
|
||||
|
||||
def __del__(self):
|
||||
super().__del__()
|
||||
|
@ -568,7 +562,7 @@ class Output(Element):
|
|||
# Button Class #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class Button(Element):
|
||||
def __init__(self, button_type=BUTTON_TYPE_CLOSES_WIN, target=(None, None), button_text='', file_types=(("ALL Files", "*.*"),), image_filename=None, image_size=(None, None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
def __init__(self, button_type=BUTTON_TYPE_CLOSES_WIN, target=(None, None), button_text='', file_types=(("ALL Files", "*.*"),), image_filename=None, image_size=(None, None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None, bind_return_key=False, focus=False):
|
||||
'''
|
||||
Button Element - Specifies all types of buttons
|
||||
:param button_type:
|
||||
|
@ -597,6 +591,8 @@ class Button(Element):
|
|||
self.ImageSubsample = image_subsample
|
||||
self.UserData = None
|
||||
self.BorderWidth = border_width if border_width is not None else DEFAULT_BORDER_WIDTH
|
||||
self.BindReturnKey = bind_return_key
|
||||
self.Focus = focus
|
||||
super().__init__(ELEM_TYPE_BUTTON, scale, size, font=font)
|
||||
return
|
||||
|
||||
|
@ -659,16 +655,6 @@ class Button(Element):
|
|||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||
return
|
||||
|
||||
def ReturnKeyHandler(self, event):
|
||||
MyForm = self.ParentForm
|
||||
# search through this form and find the first button that will exit the form
|
||||
for row in MyForm.Rows:
|
||||
for element in row:
|
||||
if element.Type == ELEM_TYPE_BUTTON:
|
||||
if element.BType == BUTTON_TYPE_CLOSES_WIN or element.BType == BUTTON_TYPE_READ_FORM:
|
||||
element.ButtonCallBack()
|
||||
return
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
self.TKButton.__del__()
|
||||
|
@ -818,6 +804,7 @@ class FlexForm:
|
|||
self.ReturnValuesDictionary = None
|
||||
self.ResultsBuilt = False
|
||||
self.UseDictionary = use_dictionary
|
||||
self.UseDefaultFocus = False
|
||||
|
||||
# ------------------------- Add ONE Row to Form ------------------------- #
|
||||
def AddRow(self, *args):
|
||||
|
@ -858,6 +845,19 @@ class FlexForm:
|
|||
self.NumCols = max(len(row) for row in self.Rows)
|
||||
self.NonBlocking=non_blocking
|
||||
|
||||
# Search through entire form to see if any elements set the focus
|
||||
# if not, then will set the focus to the first input element
|
||||
found_focus = False
|
||||
for row in self.Rows:
|
||||
for element in row:
|
||||
try:
|
||||
if element.Focus:
|
||||
found_focus = True
|
||||
break
|
||||
except:
|
||||
pass
|
||||
if not found_focus:
|
||||
self.UseDefaultFocus = True
|
||||
# -=-=-=-=-=-=-=-=- RUN the GUI -=-=-=-=-=-=-=-=- ##
|
||||
StartupTK(self)
|
||||
return self.ReturnValues
|
||||
|
@ -1001,11 +1001,11 @@ class UberForm():
|
|||
# ====================================================================== #
|
||||
|
||||
# ------------------------- INPUT TEXT Element lazy functions ------------------------- #
|
||||
def In(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None):
|
||||
return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text)
|
||||
def In(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, focus=False):
|
||||
return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, focus=focus)
|
||||
|
||||
def Input(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None):
|
||||
return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text)
|
||||
def Input(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, focus=False):
|
||||
return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, focus=focus)
|
||||
|
||||
# ------------------------- INPUT COMBO Element lazy functions ------------------------- #
|
||||
def Combo(values, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None):
|
||||
|
@ -1032,45 +1032,44 @@ def FileBrowse(target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), button_
|
|||
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)
|
||||
|
||||
# ------------------------- SUBMIT BUTTON Element lazy function ------------------------- #
|
||||
def Submit(button_text='Submit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color)
|
||||
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)
|
||||
|
||||
# ------------------------- OK BUTTON Element lazy function ------------------------- #
|
||||
def OK(button_text='OK', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color)
|
||||
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)
|
||||
|
||||
# ------------------------- YES BUTTON Element lazy function ------------------------- #
|
||||
def Ok(button_text='Ok', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color)
|
||||
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)
|
||||
|
||||
# ------------------------- 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):
|
||||
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)
|
||||
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):
|
||||
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)
|
||||
|
||||
# ------------------------- QUIT BUTTON Element lazy function ------------------------- #
|
||||
def Quit(button_text='Quit', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
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)
|
||||
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)
|
||||
|
||||
# ------------------------- YES BUTTON Element lazy function ------------------------- #
|
||||
def Yes(button_text='Yes', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color)
|
||||
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)
|
||||
|
||||
# ------------------------- NO BUTTON Element lazy function ------------------------- #
|
||||
def No(button_text='No', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color)
|
||||
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)
|
||||
|
||||
# ------------------------- GENERIC BUTTON Element lazy function ------------------------- #
|
||||
# this is the only button that REQUIRES button text field
|
||||
def SimpleButton(button_text, image_filename=None, image_size=(None, None), image_subsample=None, border_width=None, scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
return Button(BUTTON_TYPE_CLOSES_WIN, image_filename=image_filename, image_size=image_size, image_subsample=image_subsample, button_text=button_text, border_width=border_width, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font)
|
||||
|
||||
def SimpleButton(button_text, image_filename=None, image_size=(None, None), image_subsample=None, border_width=None, 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, image_filename=image_filename, image_size=image_size, image_subsample=image_subsample, button_text=button_text, border_width=border_width, 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
|
||||
def ReadFormButton(button_text, image_filename=None, image_size=(None, None),image_subsample=None,border_width=None,scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
return Button(BUTTON_TYPE_READ_FORM, image_filename=image_filename, image_size=image_size, image_subsample=image_subsample, border_width=border_width, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font)
|
||||
def ReadFormButton(button_text, image_filename=None, image_size=(None, None),image_subsample=None,border_width=None,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_READ_FORM, image_filename=image_filename, image_size=image_size, image_subsample=image_subsample, border_width=border_width, 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)
|
||||
|
||||
def RealtimeButton(button_text, image_filename=None, image_size=(None, None),image_subsample=None,border_width=None,scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None):
|
||||
return Button(BUTTON_TYPE_REALTIME, image_filename=image_filename, image_size=image_size, image_subsample=image_subsample, border_width=border_width, button_text=button_text, scale=scale, size=size, auto_size_button=auto_size_button, button_color=button_color, font=font)
|
||||
def RealtimeButton(button_text, image_filename=None, image_size=(None, None),image_subsample=None,border_width=None,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_REALTIME, image_filename=image_filename, image_size=image_size, image_subsample=image_subsample, border_width=border_width, 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)
|
||||
|
||||
#------------------------------------------------------------------------------------------------------#
|
||||
# ------- FUNCTION InitializeResults. Sets up form results matrix ------- #
|
||||
|
@ -1152,6 +1151,8 @@ def BuildResults(form):
|
|||
value=element.TKStringVar.get()
|
||||
results[row_num][col_num] = value
|
||||
input_values.append(value)
|
||||
if not form.NonBlocking:
|
||||
element.TKStringVar.set('')
|
||||
try:
|
||||
input_values_dictionary[element.Key] = value
|
||||
except: pass
|
||||
|
@ -1364,7 +1365,7 @@ def ConvertFlexToTK(MyFlexForm):
|
|||
tkbutton.image = photo
|
||||
tkbutton.configure(wraplength=wraplen+10, font=font) # set wrap to width of widget
|
||||
tkbutton.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
|
||||
if not focus_set and btype == BUTTON_TYPE_CLOSES_WIN:
|
||||
if element.Focus is True or (MyFlexForm.UseDefaultFocus and not focus_set):
|
||||
focus_set = True
|
||||
element.TKButton.bind('<Return>', element.ReturnKeyHandler)
|
||||
element.TKButton.focus_set()
|
||||
|
@ -1382,7 +1383,7 @@ def ConvertFlexToTK(MyFlexForm):
|
|||
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||
element.TKEntry.configure(fg=text_color)
|
||||
element.TKEntry.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||
if not focus_set:
|
||||
if element.Focus is True or (MyFlexForm.UseDefaultFocus and not focus_set):
|
||||
focus_set = True
|
||||
element.TKEntry.focus_set()
|
||||
# ------------------------- COMBO BOX (Drop Down) element ------------------------- #
|
||||
|
@ -1453,7 +1454,7 @@ def ConvertFlexToTK(MyFlexForm):
|
|||
element.TKText.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
|
||||
if element.EnterSubmits:
|
||||
element.TKText.bind('<Return>', element.ReturnKeyHandler)
|
||||
if not focus_set:
|
||||
if element.Focus is True or (MyFlexForm.UseDefaultFocus and not focus_set):
|
||||
focus_set = True
|
||||
element.TKText.focus_set()
|
||||
if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
|
||||
|
@ -1748,19 +1749,19 @@ def MsgBox(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, a
|
|||
pad =1
|
||||
# show either an OK or Yes/No depending on paramater
|
||||
if button_type is MSG_BOX_YES_NO:
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), Yes(button_color=button_color), No(
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), Yes(button_color=button_color, focus=True, bind_return_key=True), No(
|
||||
button_color=button_color))
|
||||
(button_text, values) = form.Show()
|
||||
return button_text == 'Yes'
|
||||
elif button_type is MSG_BOX_CANCELLED:
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('Cancelled', button_color=button_color))
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('Cancelled', button_color=button_color, focus=True, bind_return_key=True))
|
||||
elif button_type is MSG_BOX_ERROR:
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('ERROR', size=(5, 1), button_color=button_color))
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('ERROR', size=(5, 1), button_color=button_color, focus=True, bind_return_key=True))
|
||||
elif button_type is MSG_BOX_OK_CANCEL:
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('OK', size=(5, 1), button_color=button_color),
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('OK', size=(5, 1), button_color=button_color, focus=True, bind_return_key=True),
|
||||
SimpleButton('Cancel', size=(5, 1), button_color=button_color))
|
||||
else:
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('OK', size=(5, 1), button_color=button_color))
|
||||
form.AddRow(Text('', size=(pad, 1), auto_size_text=False), SimpleButton('OK', size=(5, 1), button_color=button_color, focus=True, bind_return_key=True))
|
||||
|
||||
button, values = form.Show()
|
||||
return button
|
||||
|
@ -2169,7 +2170,7 @@ def ScrolledTextBox(*args, button_color=None, yes_no=False, auto_close=False, au
|
|||
height_computed = MAX_SCROLLED_TEXT_BOX_HEIGHT if height_computed > MAX_SCROLLED_TEXT_BOX_HEIGHT else height_computed
|
||||
if height:
|
||||
height_computed = height
|
||||
form.AddRow(Multiline(complete_output, size=(max_line_width, height_computed)), auto_size_text=True)
|
||||
form.AddRow(Multiline(complete_output, size=(max_line_width, height_computed)))
|
||||
pad = max_line_total-15 if max_line_total > 15 else 1
|
||||
# show either an OK or Yes/No depending on paramater
|
||||
if yes_no:
|
||||
|
@ -2415,9 +2416,9 @@ def main():
|
|||
form_rows = [[Text('You are running the PySimpleGUI.py file itself')],
|
||||
[Text('You should be importing it rather than running it\n')],
|
||||
[Text('Here is your sample input form....')],
|
||||
[Text('Source Folder', size=(15, 1), auto_size_text=False, justification='right'), InputText('Source'),FolderBrowse()],
|
||||
[Text('Source Folder', size=(15, 1), auto_size_text=False, justification='right'), InputText('Source', focus=True),FolderBrowse()],
|
||||
[Text('Destination Folder', size=(15, 1), auto_size_text=False, justification='right'), InputText('Dest'), FolderBrowse()],
|
||||
[Submit(), Cancel()]]
|
||||
[Submit(bind_return_key=True), Cancel()]]
|
||||
|
||||
button, (source, dest) = form.LayoutAndRead(form_rows)
|
||||
|
||||
|
|
Loading…
Reference in New Issue