Merge pull request #1364 from PySimpleGUI/Dev-latest

Dev latest
This commit is contained in:
MikeTheWatchGuy 2019-05-02 14:28:10 -04:00 committed by GitHub
commit 7513e21fa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 113 deletions

View File

@ -101,7 +101,7 @@ DEFAULT_DEBUG_WINDOW_SIZE = (80, 20)
DEFAULT_WINDOW_LOCATION = (None, None) DEFAULT_WINDOW_LOCATION = (None, None)
MAX_SCROLLED_TEXT_BOX_HEIGHT = 50 MAX_SCROLLED_TEXT_BOX_HEIGHT = 50
DEFAULT_TOOLTIP_TIME = 400 DEFAULT_TOOLTIP_TIME = 400
DEFAULT_TOOLTIP_OFFSET = (20,-20) DEFAULT_TOOLTIP_OFFSET = (0,-20)
#################### COLOR STUFF #################### #################### COLOR STUFF ####################
BLUES = ("#082567", "#0A37A3", "#00345B") BLUES = ("#082567", "#0A37A3", "#00345B")
PURPLES = ("#480656", "#4F2398", "#380474") PURPLES = ("#480656", "#4F2398", "#380474")
@ -303,6 +303,8 @@ class ToolTip:
self.widget.bind("<ButtonPress>", self.leave) self.widget.bind("<ButtonPress>", self.leave)
def enter(self, event=None): def enter(self, event=None):
self.x = event.x
self.y = event.y
self.schedule() self.schedule()
def leave(self, event=None): def leave(self, event=None):
@ -321,8 +323,8 @@ class ToolTip:
def showtip(self): def showtip(self):
if self.tipwindow: if self.tipwindow:
return return
x = self.widget.winfo_rootx() + DEFAULT_TOOLTIP_OFFSET[0] x = self.widget.winfo_rootx() + self.x + DEFAULT_TOOLTIP_OFFSET[0]
y = self.widget.winfo_rooty() + self.widget.winfo_height() + DEFAULT_TOOLTIP_OFFSET[1] y = self.widget.winfo_rooty() + self.y + DEFAULT_TOOLTIP_OFFSET[1]
self.tipwindow = tk.Toplevel(self.widget) self.tipwindow = tk.Toplevel(self.widget)
self.tipwindow.wm_overrideredirect(True) self.tipwindow.wm_overrideredirect(True)
self.tipwindow.wm_geometry("+%d+%d" % (x, y)) self.tipwindow.wm_geometry("+%d+%d" % (x, y))
@ -5196,6 +5198,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
# ------------------------- INPUT element ------------------------- # # ------------------------- INPUT element ------------------------- #
elif element_type == ELEM_TYPE_INPUT_TEXT: elif element_type == ELEM_TYPE_INPUT_TEXT:
element = element # type: InputText
default_text = element.DefaultText default_text = element.DefaultText
element.TKStringVar = tk.StringVar() element.TKStringVar = tk.StringVar()
element.TKStringVar.set(default_text) element.TKStringVar.set(default_text)
@ -7674,7 +7677,7 @@ def main():
frame3 = [ frame3 = [
[Checkbox('Checkbox1', True), Checkbox('Checkbox1')], [Checkbox('Checkbox1', True), Checkbox('Checkbox1')],
[Radio('Radio Button1', 1), Radio('Radio Button2', 1, default=True)], [Radio('Radio Button1', 1), Radio('Radio Button2', 1, default=True, tooltip='Radio 2')],
[T('', size=(1, 4))], [T('', size=(1, 4))],
] ]
@ -7699,12 +7702,12 @@ def main():
[graph_elem], [graph_elem],
] ]
tab1 = Tab('Graph Number 1', frame6) tab1 = Tab('Graph Number 1', frame6, tooltip='tab 1')
tab2 = Tab('Graph Number 2', [[]]) tab2 = Tab('Graph Number 2', [[]])
layout1 = [ layout1 = [
[Menu(menu_def)], [Menu(menu_def)],
[Text('You are running the PySimpleGUI.py file itself', font='ANY 15')], [Text('You are running the PySimpleGUI.py file itself', font='ANY 15', tooltip='My tooltip')],
[Text('You should be importing it rather than running it', font='ANY 15')], [Text('You should be importing it rather than running it', font='ANY 15')],
[Frame('Input Text Group', frame1, title_color='red'), [Frame('Input Text Group', frame1, title_color='red'),
Image(data=DEFAULT_BASE64_LOADING_GIF, key='_IMAGE_')], Image(data=DEFAULT_BASE64_LOADING_GIF, key='_IMAGE_')],
@ -7714,15 +7717,15 @@ def main():
[Frame('Structured Data Group', frame5, title_color='red'), ], [Frame('Structured Data Group', frame5, title_color='red'), ],
# [Frame('Graphing Group', frame6)], # [Frame('Graphing Group', frame6)],
[TabGroup([[tab1, tab2]])], [TabGroup([[tab1, tab2]])],
[ProgressBar(max_value=800, size=(60, 25), key='+PROGRESS+'), Button('Button'), Button('Exit')], [ProgressBar(max_value=800, size=(60, 25), key='+PROGRESS+'), Button('Button'), Button('Exit', tooltip='Exit button')],
] ]
layout=[[Column(layout1)]] layout=[[Column(layout1)]]
window = Window('Window Title', window = Window('Window Title', layout,
font=('Helvetica', 13), font=('Helvetica', 13),
right_click_menu=['&Right', ['Right', '!&Click', '&Menu', 'E&xit', 'Properties']], right_click_menu=['&Right', ['Right', '!&Click', '&Menu', 'E&xit', 'Properties']],
).Layout(layout).Finalize() ).Finalize()
graph_elem.DrawCircle((200, 200), 50, 'blue') graph_elem.DrawCircle((200, 200), 50, 'blue')
i = 0 i = 0
while True: # Event Loop while True: # Event Loop

View File

@ -120,7 +120,7 @@ while True: # Event Loop
break break
if event == 'Show': if event == 'Show':
# change the "output" element to be the value of "input" element # change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_']) window.Element('_OUTPUT_').Update(values['_IN_'])
window.Close() window.Close()
``` ```
@ -343,7 +343,7 @@ while True:
break break
elif event == 'Start/Stop': elif event == 'Start/Stop':
timer_running = not timer_running timer_running = not timer_running
window.FindElement('_OUTPUT_').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100)) window.Element('_OUTPUT_').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
``` ```
<iframe height="800px" width="100%" src="https://repl.it/@PySimpleGUI/Cookbook-Timer?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe> <iframe height="800px" width="100%" src="https://repl.it/@PySimpleGUI/Cookbook-Timer?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>
@ -517,7 +517,7 @@ def MediaPlayerGUI():
break break
# If a button was pressed, display it on the GUI by updating the text element # If a button was pressed, display it on the GUI by updating the text element
if event != sg.TIMEOUT_KEY: if event != sg.TIMEOUT_KEY:
window.FindElement('output').Update(event) window.Element('output').Update(event)
MediaPlayerGUI() MediaPlayerGUI()
``` ```
@ -660,7 +660,7 @@ for i in range(1000):
if event == 'Cancel' or event is None: if event == 'Cancel' or event is None:
break break
# update bar with loop value +1 so that bar eventually reaches the maximum # update bar with loop value +1 so that bar eventually reaches the maximum
window.FindElement('progbar').UpdateBar(i + 1) window.Element('progbar').UpdateBar(i + 1)
# done with loop... need to destroy the window as it's still open # done with loop... need to destroy the window as it's still open
window.Close() window.Close()
``` ```
@ -762,7 +762,7 @@ This simple program keep a window open, taking input values until the user termi
except: except:
calc = 'Invalid' calc = 'Invalid'
window.FindElement('output').Update(calc) window.Element('output').Update(calc)
else: else:
break break
``` ```
@ -820,7 +820,7 @@ while True:
ev1, vals1 = win1.Read(timeout=100) ev1, vals1 = win1.Read(timeout=100)
if ev1 is None: if ev1 is None:
break break
win1.FindElement('_OUTPUT_').Update(vals1[0]) win1.Element('_OUTPUT_').Update(vals1[0])
if ev1 == 'Launch 2' and not win2_active: if ev1 == 'Launch 2' and not win2_active:
win2_active = True win2_active = True
@ -863,7 +863,7 @@ While it's fun to scribble on a Canvas Widget, try Graph Element makes it a down
window = sg.Window('Canvas test', layout) window = sg.Window('Canvas test', layout)
window.Finalize() window.Finalize()
canvas = window.FindElement('canvas') canvas = window.Element('canvas')
cir = canvas.TKCanvas.create_oval(50, 50, 100, 100) cir = canvas.TKCanvas.create_oval(50, 50, 100, 100)
while True: while True:
@ -893,7 +893,7 @@ Just like you can draw on a tkinter widget, you can also draw on a Graph Element
window = sg.Window('Graph test', layout) window = sg.Window('Graph test', layout)
window.Finalize() window.Finalize()
graph = window.FindElement('graph') graph = window.Element('graph')
circle = graph.DrawCircle((75,75), 25, fill_color='black',line_color='white') circle = graph.DrawCircle((75,75), 25, fill_color='black',line_color='white')
point = graph.DrawPoint((75,75), 10, color='green') point = graph.DrawPoint((75,75), 10, color='green')
oval = graph.DrawOval((25,300), (100,280), fill_color='purple', line_color='purple' ) oval = graph.DrawOval((25,300), (100,280), fill_color='purple', line_color='purple' )
@ -965,9 +965,9 @@ There are a number of features used in this Recipe including:
keys_entered += event # add the new digit keys_entered += event # add the new digit
elif event == 'Submit': elif event == 'Submit':
keys_entered = values['input'] keys_entered = values['input']
window.FindElement('out').Update(keys_entered) # output the final string window.Element('out').Update(keys_entered) # output the final string
window.FindElement('input').Update(keys_entered) # change the window to reflect current key string window.Element('input').Update(keys_entered) # change the window to reflect current key string
``` ```
<iframe height="800px" width="100%" src="https://repl.it/@PySimpleGUI/Cookbook-Keypad-Touchscreen-Entry?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe> <iframe height="800px" width="100%" src="https://repl.it/@PySimpleGUI/Cookbook-Keypad-Touchscreen-Entry?lite=true" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>
@ -1006,7 +1006,7 @@ layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center',
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout) window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout)
window.Finalize() # needed to access the canvas element prior to reading the window window.Finalize() # needed to access the canvas element prior to reading the window
canvas_elem = window.FindElement('canvas') canvas_elem = window.Element('canvas')
graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas) graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas)
canvas = canvas_elem.TKCanvas canvas = canvas_elem.TKCanvas
@ -1070,9 +1070,9 @@ In other GUI frameworks this program would be most likely "event driven" with ca
window = sg.Window("Time Tracker", layout, default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False, window = sg.Window("Time Tracker", layout, default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False,
default_button_element_size=(12,1)) default_button_element_size=(12,1))
window.Finalize() window.Finalize()
window.FindElement('Stop').Update(disabled=True) window.Element('Stop').Update(disabled=True)
window.FindElement('Reset').Update(disabled=True) window.Element('Reset').Update(disabled=True)
window.FindElement('Submit').Update(disabled=True) window.Element('Submit').Update(disabled=True)
recording = have_data = False recording = have_data = False
while True: while True:
event, values = window.Read() event, values = window.Read()
@ -1080,29 +1080,29 @@ In other GUI frameworks this program would be most likely "event driven" with ca
if event is None: if event is None:
exit(69) exit(69)
if event is 'Start': if event is 'Start':
window.FindElement('Start').Update(disabled=True) window.Element('Start').Update(disabled=True)
window.FindElement('Stop').Update(disabled=False) window.Element('Stop').Update(disabled=False)
window.FindElement('Reset').Update(disabled=False) window.Element('Reset').Update(disabled=False)
window.FindElement('Submit').Update(disabled=True) window.Element('Submit').Update(disabled=True)
recording = True recording = True
elif event is 'Stop' and recording: elif event is 'Stop' and recording:
window.FindElement('Stop').Update(disabled=True) window.Element('Stop').Update(disabled=True)
window.FindElement('Start').Update(disabled=False) window.Element('Start').Update(disabled=False)
window.FindElement('Submit').Update(disabled=False) window.Element('Submit').Update(disabled=False)
recording = False recording = False
have_data = True have_data = True
elif event is 'Reset': elif event is 'Reset':
window.FindElement('Stop').Update(disabled=True) window.Element('Stop').Update(disabled=True)
window.FindElement('Start').Update(disabled=False) window.Element('Start').Update(disabled=False)
window.FindElement('Submit').Update(disabled=True) window.Element('Submit').Update(disabled=True)
window.FindElement('Reset').Update(disabled=False) window.Element('Reset').Update(disabled=False)
recording = False recording = False
have_data = False have_data = False
elif event is 'Submit' and have_data: elif event is 'Submit' and have_data:
window.FindElement('Stop').Update(disabled=True) window.Element('Stop').Update(disabled=True)
window.FindElement('Start').Update(disabled=False) window.Element('Start').Update(disabled=False)
window.FindElement('Submit').Update(disabled=True) window.Element('Submit').Update(disabled=True)
window.FindElement('Reset').Update(disabled=False) window.Element('Reset').Update(disabled=False)
recording = False recording = False
``` ```
@ -1151,7 +1151,7 @@ Use the upper half to generate your hash code. Then paste it into the code in t
sha1hash = hashlib.sha1() sha1hash = hashlib.sha1()
sha1hash.update(password_utf) sha1hash.update(password_utf)
password_hash = sha1hash.hexdigest() password_hash = sha1hash.hexdigest()
window.FindElement('hash').Update(password_hash) window.Element('hash').Update(password_hash)
except: except:
pass pass
@ -1218,7 +1218,7 @@ You can easily change colors to match your background by changing a couple of pa
def Launcher(): def Launcher():
def print(line): def print(line):
window.FindElement('output').Update(line) window.Element('output').Update(line)
sg.ChangeLookAndFeel('Dark') sg.ChangeLookAndFeel('Dark')
@ -1331,7 +1331,7 @@ while (True):
else: else:
event, values = window.Read() event, values = window.Read()
if event == 'button': if event == 'button':
event = window.FindElement(event).GetText() event = window.Element(event).GetText()
# --------- Do Button Operations -------- # --------- Do Button Operations --------
if event is None or event == 'Exit': # ALWAYS give a way out of program if event is None or event == 'Exit': # ALWAYS give a way out of program
break break
@ -1342,16 +1342,16 @@ while (True):
elif event == 'Pause': elif event == 'Pause':
paused = True paused = True
paused_time = int(round(time.time() * 100)) paused_time = int(round(time.time() * 100))
element = window.FindElement('button') element = window.Element('button')
element.Update(text='Run') element.Update(text='Run')
elif event == 'Run': elif event == 'Run':
paused = False paused = False
start_time = start_time + int(round(time.time() * 100)) - paused_time start_time = start_time + int(round(time.time() * 100)) - paused_time
element = window.FindElement('button') element = window.Element('button')
element.Update(text='Pause') element.Update(text='Pause')
# --------- Display timer in window -------- # --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60, window.Element('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60, (current_time // 100) % 60,
current_time % 100)) current_time % 100))
``` ```
@ -1399,7 +1399,7 @@ while (True):
# --------- Display timer in window -------- # --------- Display timer in window --------
window.FindElement('text').Update(f'CPU {cpu_percent:02.0f}%') window.Element('text').Update(f'CPU {cpu_percent:02.0f}%')
# Broke out of main loop. Close the window. # Broke out of main loop. Close the window.
window.Close() window.Close()
@ -1468,7 +1468,7 @@ import PySimpleGUI as sg
layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-105,-105), graph_top_right=(105,105), background_color='white', key='graph', tooltip='This is a cool graph!')],] layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-105,-105), graph_top_right=(105,105), background_color='white', key='graph', tooltip='This is a cool graph!')],]
window = sg.Window('Graph of Sine Function', layout, grab_anywhere=True).Finalize() window = sg.Window('Graph of Sine Function', layout, grab_anywhere=True).Finalize()
graph = window.FindElement('graph') graph = window.Element('graph')
# Draw axis # Draw axis
graph.DrawLine((-100,0), (100,0)) graph.DrawLine((-100,0), (100,0))

View File

@ -1048,7 +1048,7 @@ while True: # Event Loop
break break
if event == 'Show': if event == 'Show':
# change the "output" element to be the value of "input" element # change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_']) window.Element('_OUTPUT_').Update(values['_IN_'])
window.Close() window.Close()
``` ```
@ -1568,6 +1568,7 @@ There are a few methods (functions) that you will see in this document that act
window.Disable() - Use to disable the window inputwhen opening another window on top of the primnary Window window.Disable() - Use to disable the window inputwhen opening another window on top of the primnary Window
window.Enable() - Re-enable a Disabled window window.Enable() - Re-enable a Disabled window
window.FindElement(key, silent_on_error=False) - Returns the element that has a matching key value window.FindElement(key, silent_on_error=False) - Returns the element that has a matching key value
window.Element(key, silent_on_error=False) - EXACTLY the same as calling FindElement
window.Move(x,y) - Moves window to location x,y on screen' window.Move(x,y) - Moves window to location x,y on screen'
window.SetAlpha(alpha) - Changes window transparency window.SetAlpha(alpha) - Changes window transparency
window.BringToFront() - Brings the window to the top of other windows on the screen window.BringToFront() - Brings the window to the top of other windows on the screen
@ -1920,9 +1921,9 @@ Multiline( default_text='',
tooltip=None tooltip=None
right_click_menu=None, right_click_menu=None,
visible=True) visible=True)
'''
``` ```
default_text - Text to display in the text box default_text - Text to display in the text box
change_submits - Bool. If True, pressing Enter key submits window change_submits - Bool. If True, pressing Enter key submits window
anable_events - Bool. same as change_submits anable_events - Bool. same as change_submits
@ -2840,7 +2841,7 @@ Another way of using a Progress Meter with PySimpleGUI is to build a custom wind
# create the window` # create the window`
window = sg.Window('Custom Progress Meter', layout) window = sg.Window('Custom Progress Meter', layout)
progress_bar = window.FindElement('progressbar') progress_bar = window.Element('progressbar')
# loop that would normally do something useful # loop that would normally do something useful
for i in range(10000): for i in range(10000):
# check to see if the cancel button was clicked and exit loop if clicked # check to see if the cancel button was clicked and exit loop if clicked
@ -3052,7 +3053,7 @@ The order of operations to obtain a tkinter Canvas Widget is:
# add the plot to the window # add the plot to the window
fig_photo = draw_figure(window.FindElement('canvas').TKCanvas, fig) fig_photo = draw_figure(window.Element('canvas').TKCanvas, fig)
# show it all again and get buttons # show it all again and get buttons
event, values = window.Read() event, values = window.Read()
@ -3890,7 +3891,7 @@ See the sample code on the GitHub named Demo Media Player for another example of
event, values = window.Read(timeout=10) event, values = window.Read(timeout=10)
current_time = int(round(time.time() * 100)) - start_time current_time = int(round(time.time() * 100)) - start_time
# --------- Display timer in window -------- # --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60, window.Element('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60, (current_time // 100) % 60,
current_time % 100)) current_time % 100))
``` ```
@ -4000,9 +4001,9 @@ In some programs these updates happen in response to another Element. This prog
if sz != fontSize: if sz != fontSize:
fontSize = sz fontSize = sz
font = "Helvetica " + str(fontSize) font = "Helvetica " + str(fontSize)
window.FindElement('text').Update(font=font) window.Element('text').Update(font=font)
window.FindElement('slider').Update(sz) window.Element('slider').Update(sz)
window.FindElement('spin').Update(sz) window.Element('spin').Update(sz)
print("Done.") print("Done.")
@ -4012,15 +4013,15 @@ For example, `values['slider']` is the value of the Slider Element.
This program changes all 3 elements if either the Slider or the Spinner changes. This is done with these statements: This program changes all 3 elements if either the Slider or the Spinner changes. This is done with these statements:
window.FindElement('text').Update(font=font) window.Element('text').Update(font=font)
window.FindElement('slider').Update(sz) window.Element('slider').Update(sz)
window.FindElement('spin').Update(sz) window.Element('spin').Update(sz)
Remember this design pattern because you will use it OFTEN if you use persistent windows. Remember this design pattern because you will use it OFTEN if you use persistent windows.
It works as follows. The call to `window.FindElement` returns the Element object represented by they provided `key`. This element is then updated by calling it's `Update` method. This is another example of Python's "chaining" feature. We could write this code using the long-form: It works as follows. The call to `window.FindElement` returns the Element object represented by they provided `key`. This element is then updated by calling it's `Update` method. This is another example of Python's "chaining" feature. We could write this code using the long-form:
text_element = window.FindElement('text') text_element = window.Element('text')
text_element.Update(font=font) text_element.Update(font=font)
The takeaway from this exercise is that keys are key in PySimpleGUI's design. They are used to both read the values of the window and also to identify elements. As already mentioned, they are used as targets in Button calls. The takeaway from this exercise is that keys are key in PySimpleGUI's design. They are used to both read the values of the window and also to identify elements. As already mentioned, they are used as targets in Button calls.
@ -4215,7 +4216,7 @@ win1 = sg.Window('Window 1', layout)
win2_active = False win2_active = False
while True: while True:
ev1, vals1 = win1.Read(timeout=100) ev1, vals1 = win1.Read(timeout=100)
win1.FindElement('_OUTPUT_').Update(vals1[0]) win1.Element('_OUTPUT_').Update(vals1[0])
if ev1 is None or ev1 == 'Exit': if ev1 is None or ev1 == 'Exit':
break break
@ -4252,7 +4253,7 @@ while True:
ev1, vals1 = win1.Read(timeout=100) ev1, vals1 = win1.Read(timeout=100)
if ev1 is None: if ev1 is None:
break break
win1.FindElement('_OUTPUT_').Update(vals1[0]) win1.Element('_OUTPUT_').Update(vals1[0])
if ev1 == 'Launch 2' and not win2_active: if ev1 == 'Launch 2' and not win2_active:
win2_active = True win2_active = True
@ -4964,7 +4965,7 @@ It seemed quite natural to use Python's powerful list constructs when possible.
**Dictionaries** **Dictionaries**
Want to view your form's results as a dictionary instead of a list... no problem, just use the `key` keyword on your elements. For complex forms with a lot of values that need to be changed frequently, this is by far the best way of consuming the results. Want to view your form's results as a dictionary instead of a list... no problem, just use the `key` keyword on your elements. For complex forms with a lot of values that need to be changed frequently, this is by far the best way of consuming the results.
You can also look up elements using their keys. This is an excellent way to update elements in reaction to another element. Call `form.FindElement(key)` to get the Element. You can also look up elements using their keys. This is an excellent way to update elements in reaction to another element. Call `form.Element(key)` to get the Element.
**Named / Optional Parameters** **Named / Optional Parameters**
This is a language feature that is featured **heavily** in all of the API calls, both functions and classes. Elements are configured, in-place, by setting one or more optional parameters. For example, a Text element's color is chosen by setting the optional `text_color` parameter. This is a language feature that is featured **heavily** in all of the API calls, both functions and classes. Elements are configured, in-place, by setting one or more optional parameters. For example, a Text element's color is chosen by setting the optional `text_color` parameter.

View File

@ -1048,7 +1048,7 @@ while True: # Event Loop
break break
if event == 'Show': if event == 'Show':
# change the "output" element to be the value of "input" element # change the "output" element to be the value of "input" element
window.FindElement('_OUTPUT_').Update(values['_IN_']) window.Element('_OUTPUT_').Update(values['_IN_'])
window.Close() window.Close()
``` ```
@ -1568,6 +1568,7 @@ There are a few methods (functions) that you will see in this document that act
window.Disable() - Use to disable the window inputwhen opening another window on top of the primnary Window window.Disable() - Use to disable the window inputwhen opening another window on top of the primnary Window
window.Enable() - Re-enable a Disabled window window.Enable() - Re-enable a Disabled window
window.FindElement(key, silent_on_error=False) - Returns the element that has a matching key value window.FindElement(key, silent_on_error=False) - Returns the element that has a matching key value
window.Element(key, silent_on_error=False) - EXACTLY the same as calling FindElement
window.Move(x,y) - Moves window to location x,y on screen' window.Move(x,y) - Moves window to location x,y on screen'
window.SetAlpha(alpha) - Changes window transparency window.SetAlpha(alpha) - Changes window transparency
window.BringToFront() - Brings the window to the top of other windows on the screen window.BringToFront() - Brings the window to the top of other windows on the screen
@ -1920,9 +1921,9 @@ Multiline( default_text='',
tooltip=None tooltip=None
right_click_menu=None, right_click_menu=None,
visible=True) visible=True)
'''
``` ```
default_text - Text to display in the text box default_text - Text to display in the text box
change_submits - Bool. If True, pressing Enter key submits window change_submits - Bool. If True, pressing Enter key submits window
anable_events - Bool. same as change_submits anable_events - Bool. same as change_submits
@ -2840,7 +2841,7 @@ Another way of using a Progress Meter with PySimpleGUI is to build a custom wind
# create the window` # create the window`
window = sg.Window('Custom Progress Meter', layout) window = sg.Window('Custom Progress Meter', layout)
progress_bar = window.FindElement('progressbar') progress_bar = window.Element('progressbar')
# loop that would normally do something useful # loop that would normally do something useful
for i in range(10000): for i in range(10000):
# check to see if the cancel button was clicked and exit loop if clicked # check to see if the cancel button was clicked and exit loop if clicked
@ -3052,7 +3053,7 @@ The order of operations to obtain a tkinter Canvas Widget is:
# add the plot to the window # add the plot to the window
fig_photo = draw_figure(window.FindElement('canvas').TKCanvas, fig) fig_photo = draw_figure(window.Element('canvas').TKCanvas, fig)
# show it all again and get buttons # show it all again and get buttons
event, values = window.Read() event, values = window.Read()
@ -3890,7 +3891,7 @@ See the sample code on the GitHub named Demo Media Player for another example of
event, values = window.Read(timeout=10) event, values = window.Read(timeout=10)
current_time = int(round(time.time() * 100)) - start_time current_time = int(round(time.time() * 100)) - start_time
# --------- Display timer in window -------- # --------- Display timer in window --------
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60, window.Element('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
(current_time // 100) % 60, (current_time // 100) % 60,
current_time % 100)) current_time % 100))
``` ```
@ -4000,9 +4001,9 @@ In some programs these updates happen in response to another Element. This prog
if sz != fontSize: if sz != fontSize:
fontSize = sz fontSize = sz
font = "Helvetica " + str(fontSize) font = "Helvetica " + str(fontSize)
window.FindElement('text').Update(font=font) window.Element('text').Update(font=font)
window.FindElement('slider').Update(sz) window.Element('slider').Update(sz)
window.FindElement('spin').Update(sz) window.Element('spin').Update(sz)
print("Done.") print("Done.")
@ -4012,15 +4013,15 @@ For example, `values['slider']` is the value of the Slider Element.
This program changes all 3 elements if either the Slider or the Spinner changes. This is done with these statements: This program changes all 3 elements if either the Slider or the Spinner changes. This is done with these statements:
window.FindElement('text').Update(font=font) window.Element('text').Update(font=font)
window.FindElement('slider').Update(sz) window.Element('slider').Update(sz)
window.FindElement('spin').Update(sz) window.Element('spin').Update(sz)
Remember this design pattern because you will use it OFTEN if you use persistent windows. Remember this design pattern because you will use it OFTEN if you use persistent windows.
It works as follows. The call to `window.FindElement` returns the Element object represented by they provided `key`. This element is then updated by calling it's `Update` method. This is another example of Python's "chaining" feature. We could write this code using the long-form: It works as follows. The call to `window.FindElement` returns the Element object represented by they provided `key`. This element is then updated by calling it's `Update` method. This is another example of Python's "chaining" feature. We could write this code using the long-form:
text_element = window.FindElement('text') text_element = window.Element('text')
text_element.Update(font=font) text_element.Update(font=font)
The takeaway from this exercise is that keys are key in PySimpleGUI's design. They are used to both read the values of the window and also to identify elements. As already mentioned, they are used as targets in Button calls. The takeaway from this exercise is that keys are key in PySimpleGUI's design. They are used to both read the values of the window and also to identify elements. As already mentioned, they are used as targets in Button calls.
@ -4215,7 +4216,7 @@ win1 = sg.Window('Window 1', layout)
win2_active = False win2_active = False
while True: while True:
ev1, vals1 = win1.Read(timeout=100) ev1, vals1 = win1.Read(timeout=100)
win1.FindElement('_OUTPUT_').Update(vals1[0]) win1.Element('_OUTPUT_').Update(vals1[0])
if ev1 is None or ev1 == 'Exit': if ev1 is None or ev1 == 'Exit':
break break
@ -4252,7 +4253,7 @@ while True:
ev1, vals1 = win1.Read(timeout=100) ev1, vals1 = win1.Read(timeout=100)
if ev1 is None: if ev1 is None:
break break
win1.FindElement('_OUTPUT_').Update(vals1[0]) win1.Element('_OUTPUT_').Update(vals1[0])
if ev1 == 'Launch 2' and not win2_active: if ev1 == 'Launch 2' and not win2_active:
win2_active = True win2_active = True
@ -4964,7 +4965,7 @@ It seemed quite natural to use Python's powerful list constructs when possible.
**Dictionaries** **Dictionaries**
Want to view your form's results as a dictionary instead of a list... no problem, just use the `key` keyword on your elements. For complex forms with a lot of values that need to be changed frequently, this is by far the best way of consuming the results. Want to view your form's results as a dictionary instead of a list... no problem, just use the `key` keyword on your elements. For complex forms with a lot of values that need to be changed frequently, this is by far the best way of consuming the results.
You can also look up elements using their keys. This is an excellent way to update elements in reaction to another element. Call `form.FindElement(key)` to get the Element. You can also look up elements using their keys. This is an excellent way to update elements in reaction to another element. Call `form.Element(key)` to get the Element.
**Named / Optional Parameters** **Named / Optional Parameters**
This is a language feature that is featured **heavily** in all of the API calls, both functions and classes. Elements are configured, in-place, by setting one or more optional parameters. For example, a Text element's color is chosen by setting the optional `text_color` parameter. This is a language feature that is featured **heavily** in all of the API calls, both functions and classes. Elements are configured, in-place, by setting one or more optional parameters. For example, a Text element's color is chosen by setting the optional `text_color` parameter.