Merge pull request #322 from MikeTheWatchGuy/Dev-latest
Replaced form with window
This commit is contained in:
commit
fd553e64b1
279
docs/cookbook.md
279
docs/cookbook.md
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
# The PySimpleGUI Cookbook
|
# The PySimpleGUI Cookbook
|
||||||
|
|
||||||
You will find all of these Recipes in a single Python file ([Demo_Cookbook.py](https://github.com/MikeTheWatchGuy/PySimpleGUI/blob/master/Demo_Cookbook.py)) located on the project's GitHub page. This program will allow you to view the source code and the window that it produces. You can also download over 50 demo programs that are ready to run.
|
|
||||||
|
|
||||||
You'll find that starting with a Recipe will give you a big jump-start on creating your custom GUI. Copy and paste one of these Recipes and modify it to match your requirements.
|
You'll find that starting with a Recipe will give you a big jump-start on creating your custom GUI. Copy and paste one of these Recipes and modify it to match your requirements. Study them to get an idea of what design patterns to follow.
|
||||||
|
|
||||||
## Simple Data Entry - Return Values As List
|
## Simple Data Entry - Return Values As List
|
||||||
Same GUI screen except the return values are in a list instead of a dictionary and doesn't have initial values.
|
Same GUI screen except the return values are in a list instead of a dictionary and doesn't have initial values.
|
||||||
|
@ -12,8 +12,8 @@ Same GUI screen except the return values are in a list instead of a dictionary a
|
||||||
|
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
# Very basic form. Return values as a list
|
# Very basic window. Return values as a list
|
||||||
form = sg.Window('Simple data entry form') # begin with a blank form
|
window = sg.Window('Simple data entry window')
|
||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
[sg.Text('Please enter your Name, Address, Phone')],
|
[sg.Text('Please enter your Name, Address, Phone')],
|
||||||
|
@ -23,19 +23,18 @@ Same GUI screen except the return values are in a list instead of a dictionary a
|
||||||
[sg.Submit(), sg.Cancel()]
|
[sg.Submit(), sg.Cancel()]
|
||||||
]
|
]
|
||||||
|
|
||||||
button, values = form.LayoutAndRead(layout)
|
button, values = window.LayoutAndRead(layout)
|
||||||
|
|
||||||
print(button, values[0], values[1], values[2])
|
print(button, values[0], values[1], values[2])
|
||||||
|
|
||||||
## Simple data entry - Return Values As Dictionary
|
## Simple data entry - Return Values As Dictionary
|
||||||
A simple form with default values. Results returned in a dictionary.
|
A simple GUI with default values. Results returned in a dictionary.
|
||||||
|
|
||||||
![super simple 2](https://user-images.githubusercontent.com/13696193/43934091-8100e29a-9c1b-11e8-8d0a-9bd2d13e6d8e.jpg)
|
![super simple 2](https://user-images.githubusercontent.com/13696193/43934091-8100e29a-9c1b-11e8-8d0a-9bd2d13e6d8e.jpg)
|
||||||
|
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
# Very basic form. Return values as a dictionary
|
# Very basic window. Return values as a dictionary
|
||||||
form = sg.Window('Simple data entry form') # begin with a blank form
|
|
||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
[sg.Text('Please enter your Name, Address, Phone')],
|
[sg.Text('Please enter your Name, Address, Phone')],
|
||||||
|
@ -45,7 +44,9 @@ A simple form with default values. Results returned in a dictionary.
|
||||||
[sg.Submit(), sg.Cancel()]
|
[sg.Submit(), sg.Cancel()]
|
||||||
]
|
]
|
||||||
|
|
||||||
button, values = form.LayoutAndRead(layout)
|
window = sg.Window('Simple data entry GUI') # begin with a blank Window
|
||||||
|
|
||||||
|
button, values = window.LayoutAndRead(layout)
|
||||||
|
|
||||||
print(button, values['name'], values['address'], values['phone'])
|
print(button, values['name'], values['address'], values['phone'])
|
||||||
|
|
||||||
|
@ -62,11 +63,11 @@ Browse for a filename that is populated into the input field.
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
|
|
||||||
form_rows = [[sg.Text('SHA-1 and SHA-256 Hashes for the file')],
|
GUI_rows = [[sg.Text('SHA-1 and SHA-256 Hashes for the file')],
|
||||||
[sg.InputText(), sg.FileBrowse()],
|
[sg.InputText(), sg.FileBrowse()],
|
||||||
[sg.Submit(), sg.Cancel()]]
|
[sg.Submit(), sg.Cancel()]]
|
||||||
|
|
||||||
(button, (source_filename,)) = sg.Window('SHA-1 & 256 Hash').LayoutAndRead(form_rows)
|
(button, (source_filename,)) = sg.Window('SHA-1 & 256 Hash').LayoutAndRead(GUI_rows)
|
||||||
|
|
||||||
print(button, source_filename)
|
print(button, source_filename)
|
||||||
|
|
||||||
|
@ -104,21 +105,21 @@ Browse to get 2 file names that can be then compared.
|
||||||
|
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
form_rows = [[sg.Text('Enter 2 files to comare')],
|
gui_rows = [[sg.Text('Enter 2 files to comare')],
|
||||||
[sg.Text('File 1', size=(8, 1)), sg.InputText(), sg.FileBrowse()],
|
[sg.Text('File 1', size=(8, 1)), sg.InputText(), sg.FileBrowse()],
|
||||||
[sg.Text('File 2', size=(8, 1)), sg.InputText(), sg.FileBrowse()],
|
[sg.Text('File 2', size=(8, 1)), sg.InputText(), sg.FileBrowse()],
|
||||||
[sg.Submit(), sg.Cancel()]]
|
[sg.Submit(), sg.Cancel()]]
|
||||||
|
|
||||||
|
|
||||||
form = sg.Window('File Compare')
|
window = sg.Window('File Compare')
|
||||||
|
|
||||||
button, values = form.LayoutAndRead(form_rows)
|
button, values = window.LayoutAndRead(gui_rows)
|
||||||
|
|
||||||
print(button, values)
|
print(button, values)
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
## Nearly All Widgets with Green Color Theme
|
## Nearly All Widgets with Green Color Theme
|
||||||
Example of nearly all of the widgets in a single form. Uses a customized color scheme.
|
Example of nearly all of the widgets in a single window. Uses a customized color scheme.
|
||||||
|
|
||||||
![latest everything bagel](https://user-images.githubusercontent.com/13696193/45920376-22d89000-be71-11e8-8ac4-640f011f84d0.jpg)
|
![latest everything bagel](https://user-images.githubusercontent.com/13696193/45920376-22d89000-be71-11e8-8ac4-640f011f84d0.jpg)
|
||||||
|
|
||||||
|
@ -142,7 +143,7 @@ Example of nearly all of the widgets in a single form. Uses a customized color
|
||||||
|
|
||||||
layout = [
|
layout = [
|
||||||
[sg.Menu(menu_def, tearoff=True)],
|
[sg.Menu(menu_def, tearoff=True)],
|
||||||
[sg.Text('All graphic widgets in one form!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
|
[sg.Text('All graphic widgets in one window!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
|
||||||
[sg.Text('Here is some text.... and a place to enter text')],
|
[sg.Text('Here is some text.... and a place to enter text')],
|
||||||
[sg.InputText('This is my text')],
|
[sg.InputText('This is my text')],
|
||||||
[sg.Frame(layout=[
|
[sg.Frame(layout=[
|
||||||
|
@ -163,16 +164,16 @@ Example of nearly all of the widgets in a single form. Uses a customized color
|
||||||
[sg.Text('Choose A Folder', size=(35, 1))],
|
[sg.Text('Choose A Folder', size=(35, 1))],
|
||||||
[sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
|
[sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
|
||||||
sg.InputText('Default Folder'), sg.FolderBrowse()],
|
sg.InputText('Default Folder'), sg.FolderBrowse()],
|
||||||
[sg.Submit(tooltip='Click to submit this form'), sg.Cancel()]
|
[sg.Submit(tooltip='Click to submit this window'), sg.Cancel()]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
form = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout)
|
window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout)
|
||||||
|
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
|
|
||||||
sg.Popup('Title',
|
sg.Popup('Title',
|
||||||
'The results of the form.',
|
'The results of the window.',
|
||||||
'The button clicked was "{}"'.format(button),
|
'The button clicked was "{}"'.format(button),
|
||||||
'The values are', values)
|
'The values are', values)
|
||||||
|
|
||||||
|
@ -181,8 +182,8 @@ Example of nearly all of the widgets in a single form. Uses a customized color
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Non-Blocking Form With Periodic Update
|
## Non-Blocking Window With Periodic Update
|
||||||
An async form that has a button read loop. A Text Element is updated periodically with a running timer. Note that `value` is checked for None which indicates the window was closed using X.
|
An async Window that has a button read loop. A Text Element is updated periodically with a running timer. Note that `value` is checked for None which indicates the window was closed using X.
|
||||||
|
|
||||||
![non-blocking](https://user-images.githubusercontent.com/13696193/43955295-70f6ac48-9c6d-11e8-8ea2-e6729ba9330c.jpg)
|
![non-blocking](https://user-images.githubusercontent.com/13696193/43955295-70f6ac48-9c6d-11e8-8ea2-e6729ba9330c.jpg)
|
||||||
|
|
||||||
|
@ -190,25 +191,25 @@ An async form that has a button read loop. A Text Element is updated periodical
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
import time
|
import time
|
||||||
|
|
||||||
form_rows = [[sg.Text('Stopwatch', size=(20, 2), justification='center')],
|
gui_rows = [[sg.Text('Stopwatch', size=(20, 2), justification='center')],
|
||||||
[sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center', key='output')],
|
[sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center', key='output')],
|
||||||
[sg.T(' ' * 5), sg.ReadButton('Start/Stop', focus=True), sg.Quit()]]
|
[sg.T(' ' * 5), sg.ReadButton('Start/Stop', focus=True), sg.Quit()]]
|
||||||
|
|
||||||
form = sg.Window('Running Timer').Layout(form_rows)
|
window = sg.Window('Running Timer').Layout(gui_rows)
|
||||||
|
|
||||||
timer_running = True
|
timer_running = True
|
||||||
i = 0
|
i = 0
|
||||||
# Event Loop
|
# Event Loop
|
||||||
while True:
|
while True:
|
||||||
i += 1 * (timer_running is True)
|
i += 1 * (timer_running is True)
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
|
|
||||||
if values is None or button == 'Quit': # if user closed the window using X or clicked Quit button
|
if values is None or button == 'Quit': # if user closed the window using X or clicked Quit button
|
||||||
break
|
break
|
||||||
elif button == 'Start/Stop':
|
elif button == 'Start/Stop':
|
||||||
timer_running = not timer_running
|
timer_running = not timer_running
|
||||||
|
|
||||||
form.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
|
window.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
|
||||||
time.sleep(.01)
|
time.sleep(.01)
|
||||||
|
|
||||||
--------
|
--------
|
||||||
|
@ -237,13 +238,13 @@ The architecture of some programs works better with button callbacks instead of
|
||||||
layout = [[sg.Text('Please click a button', auto_size_text=True)],
|
layout = [[sg.Text('Please click a button', auto_size_text=True)],
|
||||||
[sg.ReadFormButton('1'), sg.ReadFormButton('2'), sg.Quit()]]
|
[sg.ReadFormButton('1'), sg.ReadFormButton('2'), sg.Quit()]]
|
||||||
|
|
||||||
# Show the form to the user
|
# Show the Window to the user
|
||||||
form = sg.Window('Button callback example').Layout(layout)
|
window = sg.Window('Button callback example').Layout(layout)
|
||||||
|
|
||||||
# Event loop. Read buttons, make callbacks
|
# Event loop. Read buttons, make callbacks
|
||||||
while True:
|
while True:
|
||||||
# Read the form
|
# Read the Window
|
||||||
button, value = form.Read()
|
button, value = window.Read()
|
||||||
# Take appropriate action based on button
|
# Take appropriate action based on button
|
||||||
if button == '1':
|
if button == '1':
|
||||||
button1()
|
button1()
|
||||||
|
@ -257,14 +258,14 @@ The architecture of some programs works better with button callbacks instead of
|
||||||
|
|
||||||
-----
|
-----
|
||||||
## Realtime Buttons (Good For Raspberry Pi)
|
## Realtime Buttons (Good For Raspberry Pi)
|
||||||
This recipe implements a remote control interface for a robot. There are 4 directions, forward, reverse, left, right. When a button is clicked, PySimpleGUI immediately returns button events for as long as the buttons is held down. When released, the button events stop. This is an async/non-blocking form.
|
This recipe implements a remote control interface for a robot. There are 4 directions, forward, reverse, left, right. When a button is clicked, PySimpleGUI immediately returns button events for as long as the buttons is held down. When released, the button events stop. This is an async/non-blocking window.
|
||||||
|
|
||||||
![robot control](https://user-images.githubusercontent.com/13696193/44006710-d227f23e-9e56-11e8-89a3-2be5b2726199.jpg)
|
![robot control](https://user-images.githubusercontent.com/13696193/44006710-d227f23e-9e56-11e8-89a3-2be5b2726199.jpg)
|
||||||
|
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
|
|
||||||
form_rows = [[sg.Text('Robotics Remote Control')],
|
gui_rows = [[sg.Text('Robotics Remote Control')],
|
||||||
[sg.T(' ' * 10), sg.RealtimeButton('Forward')],
|
[sg.T(' ' * 10), sg.RealtimeButton('Forward')],
|
||||||
[sg.RealtimeButton('Left'), sg.T(' ' * 15), sg.RealtimeButton('Right')],
|
[sg.RealtimeButton('Left'), sg.T(' ' * 15), sg.RealtimeButton('Right')],
|
||||||
[sg.T(' ' * 10), sg.RealtimeButton('Reverse')],
|
[sg.T(' ' * 10), sg.RealtimeButton('Reverse')],
|
||||||
|
@ -272,23 +273,23 @@ This recipe implements a remote control interface for a robot. There are 4 dire
|
||||||
[sg.Quit(button_color=('black', 'orange'))]
|
[sg.Quit(button_color=('black', 'orange'))]
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window('Robotics Remote Control', auto_size_text=True).Layout(form_rows)
|
window = sg.Window('Robotics Remote Control', auto_size_text=True).Layout(gui_rows)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Some place later in your code...
|
# Some place later in your code...
|
||||||
# You need to perform a ReadNonBlocking on your form every now and then or
|
# You need to perform a ReadNonBlocking on your window every now and then or
|
||||||
# else it won't refresh.
|
# else it won't refresh.
|
||||||
#
|
#
|
||||||
# your program's main loop
|
# your program's main loop
|
||||||
while (True):
|
while (True):
|
||||||
# This is the code that reads and updates your window
|
# This is the code that reads and updates your window
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
if button is not None:
|
if button is not None:
|
||||||
print(button)
|
print(button)
|
||||||
if button == 'Quit' or values is None:
|
if button == 'Quit' or values is None:
|
||||||
break
|
break
|
||||||
|
|
||||||
form.CloseNonBlockingForm() # Don't forget to close your window!
|
window.CloseNonBlockingForm() # Don't forget to close your window!
|
||||||
|
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -307,7 +308,7 @@ This recipe shows just how easy it is to add a progress meter to your code.
|
||||||
|
|
||||||
-----
|
-----
|
||||||
## Tabbed Form
|
## Tabbed Form
|
||||||
Tabbed forms are **easy** to make and use in PySimpleGUI. You simple may your layouts for each tab and then instead of `LayoutAndRead` you call `ShowTabbedForm`. Results are returned as a list of form results. Each tab acts like a single form.
|
Tabbed forms are **easy** to make and use in PySimpleGUI. You simple may your layouts for each tab and then instead of `LayoutAndRead` you call `ShowTabbedForm`. Results are returned as a list of form results. Each tab acts like a single window.
|
||||||
|
|
||||||
|
|
||||||
![tabbed form](https://user-images.githubusercontent.com/13696193/43956352-cffa6564-9c71-11e8-971b-2b395a668bf3.jpg)
|
![tabbed form](https://user-images.githubusercontent.com/13696193/43956352-cffa6564-9c71-11e8-971b-2b395a668bf3.jpg)
|
||||||
|
@ -321,7 +322,7 @@ Tabbed forms are **easy** to make and use in PySimpleGUI. You simple may your l
|
||||||
[sg.InputText(), sg.Text('Enter some info')],
|
[sg.InputText(), sg.Text('Enter some info')],
|
||||||
[sg.Submit(button_color=('red', 'yellow')), sg.Cancel(button_color=('white', 'blue'))]]
|
[sg.Submit(button_color=('red', 'yellow')), sg.Cancel(button_color=('white', 'blue'))]]
|
||||||
|
|
||||||
form = sg.Window('')
|
window = sg.Window('')
|
||||||
form2 = sg.Window('')
|
form2 = sg.Window('')
|
||||||
|
|
||||||
results = sg.ShowTabbedForm('Tabbed form example', (form, layout_tab_1, 'First Tab'),
|
results = sg.ShowTabbedForm('Tabbed form example', (form, layout_tab_1, 'First Tab'),
|
||||||
|
@ -377,21 +378,21 @@ Buttons can have PNG of GIF images on them. This Media Player recipe requires 4
|
||||||
sg.Text('Volume', font=("Helvetica", 15), size=(7, 1))]
|
sg.Text('Volume', font=("Helvetica", 15), size=(7, 1))]
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window('Media File Player', auto_size_text=True, default_element_size=(20, 1),
|
window = sg.Window('Media File Player', auto_size_text=True, default_element_size=(20, 1),
|
||||||
font=("Helvetica", 25)).Layout(layout)
|
font=("Helvetica", 25)).Layout(layout)
|
||||||
# Our event loop
|
# Our event loop
|
||||||
while (True):
|
while (True):
|
||||||
# Read the form (this call will not block)
|
# Read the window (this call will not block)
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
if button == 'Exit' or values is None:
|
if button == 'Exit' or values is None:
|
||||||
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 button:
|
if button:
|
||||||
form.FindElement('output').Update(button)
|
window.FindElement('output').Update(button)
|
||||||
|
|
||||||
----
|
----
|
||||||
## Script Launcher - Persistent Form
|
## Script Launcher - Persistent Window
|
||||||
This form doesn't close after button clicks. To achieve this the buttons are specified as `sg.ReadButton` instead of `sg.Button`. The exception to this is the EXIT button. Clicking it will close the form. This program will run commands and display the output in the scrollable window.
|
This Window doesn't close after button clicks. To achieve this the buttons are specified as `sg.ReadButton` instead of `sg.Button`. The exception to this is the EXIT button. Clicking it will close the window. This program will run commands and display the output in the scrollable window.
|
||||||
|
|
||||||
![launcher 2](https://user-images.githubusercontent.com/13696193/43958519-b30af218-9c79-11e8-88da-fadc69da818c.jpg)
|
![launcher 2](https://user-images.githubusercontent.com/13696193/43958519-b30af218-9c79-11e8-88da-fadc69da818c.jpg)
|
||||||
|
|
||||||
|
@ -419,12 +420,12 @@ This form doesn't close after button clicks. To achieve this the buttons are sp
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
form = sg.Window('Script launcher').Layout(layout)
|
window = sg.Window('Script launcher').Layout(layout)
|
||||||
|
|
||||||
# ---===--- Loop taking in user input and using it to call scripts --- #
|
# ---===--- Loop taking in user input and using it to call scripts --- #
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
(button, value) = form.Read()
|
(button, value) = window.Read()
|
||||||
if button == 'EXIT' or button is None:
|
if button == 'EXIT' or button is None:
|
||||||
break # exit button clicked
|
break # exit button clicked
|
||||||
if button == 'script1':
|
if button == 'script1':
|
||||||
|
@ -469,9 +470,9 @@ A standard non-blocking GUI with lots of inputs.
|
||||||
[sg.Radio('MSE(L2)', 'loss', size=(12, 1)), sg.Radio('MB(L0)', 'loss', size=(12, 1))],
|
[sg.Radio('MSE(L2)', 'loss', size=(12, 1)), sg.Radio('MB(L0)', 'loss', size=(12, 1))],
|
||||||
[sg.Submit(), sg.Cancel()]]
|
[sg.Submit(), sg.Cancel()]]
|
||||||
|
|
||||||
form = sg.Window('Machine Learning Front End', font=("Helvetica", 12)).Layout(layout)
|
window = sg.Window('Machine Learning Front End', font=("Helvetica", 12)).Layout(layout)
|
||||||
|
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
|
|
||||||
-------
|
-------
|
||||||
## Custom Progress Meter / Progress Bar
|
## Custom Progress Meter / Progress Bar
|
||||||
|
@ -482,23 +483,23 @@ Perhaps you don't want all the statistics that the EasyProgressMeter provides an
|
||||||
|
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
# layout the form
|
# layout the Window
|
||||||
layout = [[sg.Text('A custom progress meter')],
|
layout = [[sg.Text('A custom progress meter')],
|
||||||
[sg.ProgressBar(10000, orientation='h', size=(20, 20), key='progbar')],
|
[sg.ProgressBar(10000, orientation='h', size=(20, 20), key='progbar')],
|
||||||
[sg.Cancel()]]
|
[sg.Cancel()]]
|
||||||
|
|
||||||
# create the form
|
# create the Window
|
||||||
form = sg.Window('Custom Progress Meter').Layout(layout)
|
window = sg.Window('Custom Progress Meter').Layout(layout)
|
||||||
# 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
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
if button == 'Cancel' or values == None:
|
if button == 'Cancel' or values == 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
|
||||||
form.FindElement('progbar').UpdateBar(i + 1)
|
window.FindElement('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
|
||||||
form.CloseNonBlockingForm()
|
window.CloseNonBlockingForm()
|
||||||
|
|
||||||
|
|
||||||
----
|
----
|
||||||
|
@ -543,9 +544,9 @@ To make it easier to see the Column in the window, the Column background has bee
|
||||||
import PySimpleGUI as sg
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
# Demo of how columns work
|
# Demo of how columns work
|
||||||
# Form has on row 1 a vertical slider followed by a COLUMN with 7 rows
|
# GUI has on row 1 a vertical slider followed by a COLUMN with 7 rows
|
||||||
# Prior to the Column element, this layout was not possible
|
# Prior to the Column element, this layout was not possible
|
||||||
# Columns layouts look identical to form layouts, they are a list of lists of elements.
|
# Columns layouts look identical to GUI layouts, they are a list of lists of elements.
|
||||||
|
|
||||||
sg.ChangeLookAndFeel('BlueMono')
|
sg.ChangeLookAndFeel('BlueMono')
|
||||||
|
|
||||||
|
@ -558,16 +559,16 @@ To make it easier to see the Column in the window, the Column background has bee
|
||||||
[sg.Input('Last input')],
|
[sg.Input('Last input')],
|
||||||
[sg.OK()]]
|
[sg.OK()]]
|
||||||
|
|
||||||
# Display the form and get values
|
# Display the Window and get values
|
||||||
|
|
||||||
button, values = sg.Window('Compact 1-line form with column').LayoutAndRead(layout)
|
button, values = sg.Window('Compact 1-line Window with column').LayoutAndRead(layout)
|
||||||
|
|
||||||
sg.Popup(button, values, line_width=200)
|
sg.Popup(button, values, line_width=200)
|
||||||
|
|
||||||
|
|
||||||
## Persistent Form With Text Element Updates
|
## Persistent Window With Text Element Updates
|
||||||
|
|
||||||
This simple program keep a form open, taking input values until the user terminates the program using the "X" button.
|
This simple program keep a window open, taking input values until the user terminates the program using the "X" button.
|
||||||
|
|
||||||
![math game](https://user-images.githubusercontent.com/13696193/44537842-c9444080-a6cd-11e8-94bc-6cdf1b765dd8.jpg)
|
![math game](https://user-images.githubusercontent.com/13696193/44537842-c9444080-a6cd-11e8-94bc-6cdf1b765dd8.jpg)
|
||||||
|
|
||||||
|
@ -582,10 +583,10 @@ This simple program keep a form open, taking input values until the user termina
|
||||||
[sg.Txt('', size=(8,1), key='output') ],
|
[sg.Txt('', size=(8,1), key='output') ],
|
||||||
[sg.ReadButton('Calculate', bind_return_key=True)]]
|
[sg.ReadButton('Calculate', bind_return_key=True)]]
|
||||||
|
|
||||||
form = sg.Window('Math').Layout(layout)
|
window = sg.Window('Math').Layout(layout)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
|
|
||||||
if button is not None:
|
if button is not None:
|
||||||
try:
|
try:
|
||||||
|
@ -595,7 +596,7 @@ This simple program keep a form open, taking input values until the user termina
|
||||||
except:
|
except:
|
||||||
calc = 'Invalid'
|
calc = 'Invalid'
|
||||||
|
|
||||||
form.FindElement('output').Update(calc)
|
window.FindElement('output').Update(calc)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -622,15 +623,15 @@ While it's fun to scribble on a Canvas Widget, try Graph Element makes it a down
|
||||||
[sg.T('Change circle color to:'), sg.ReadButton('Red'), sg.ReadButton('Blue')]
|
[sg.T('Change circle color to:'), sg.ReadButton('Red'), sg.ReadButton('Blue')]
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window('Canvas test')
|
window = sg.Window('Canvas test')
|
||||||
form.Layout(layout)
|
window.Layout(layout)
|
||||||
form.Finalize()
|
window.Finalize()
|
||||||
|
|
||||||
canvas = form.FindElement('canvas')
|
canvas = window.FindElement('canvas')
|
||||||
cir = canvas.TKCanvas.create_oval(50, 50, 100, 100)
|
cir = canvas.TKCanvas.create_oval(50, 50, 100, 100)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
if button is None:
|
if button is None:
|
||||||
break
|
break
|
||||||
if button == 'Blue':
|
if button == 'Blue':
|
||||||
|
@ -652,11 +653,11 @@ Just like you can draw on a tkinter widget, you can also draw on a Graph Element
|
||||||
[sg.T('Change circle color to:'), sg.ReadFormButton('Red'), sg.ReadFormButton('Blue'), sg.ReadFormButton('Move')]
|
[sg.T('Change circle color to:'), sg.ReadFormButton('Red'), sg.ReadFormButton('Blue'), sg.ReadFormButton('Move')]
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window('Graph test')
|
window = sg.Window('Graph test')
|
||||||
form.Layout(layout)
|
window.Layout(layout)
|
||||||
form.Finalize()
|
window.Finalize()
|
||||||
|
|
||||||
graph = form.FindElement('graph')
|
graph = window.FindElement('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' )
|
||||||
|
@ -664,7 +665,7 @@ Just like you can draw on a tkinter widget, you can also draw on a Graph Element
|
||||||
line = graph.DrawLine((0,0), (100,100))
|
line = graph.DrawLine((0,0), (100,100))
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
if button is None:
|
if button is None:
|
||||||
break
|
break
|
||||||
if button is 'Blue':
|
if button is 'Blue':
|
||||||
|
@ -686,7 +687,7 @@ There are a number of features used in this Recipe including:
|
||||||
* auto_size_buttons
|
* auto_size_buttons
|
||||||
* ReadButton
|
* ReadButton
|
||||||
* Dictionary Return values
|
* Dictionary Return values
|
||||||
* Update of Elements in form (Input, Text)
|
* Update of Elements in window (Input, Text)
|
||||||
* do_not_clear of Input Elements
|
* do_not_clear of Input Elements
|
||||||
|
|
||||||
|
|
||||||
|
@ -701,7 +702,7 @@ There are a number of features used in this Recipe including:
|
||||||
# auto_size_buttons
|
# auto_size_buttons
|
||||||
# ReadButton
|
# ReadButton
|
||||||
# Dictionary return values
|
# Dictionary return values
|
||||||
# Update of elements in form (Text, Input)
|
# Update of elements in window (Text, Input)
|
||||||
# do_not_clear of Input elements
|
# do_not_clear of Input elements
|
||||||
|
|
||||||
layout = [[sg.Text('Enter Your Passcode')],
|
layout = [[sg.Text('Enter Your Passcode')],
|
||||||
|
@ -713,12 +714,12 @@ There are a number of features used in this Recipe including:
|
||||||
[sg.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='out')],
|
[sg.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='out')],
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False, grab_anywhere=False).Layout(layout)
|
window = sg.Window('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False, grab_anywhere=False).Layout(layout)
|
||||||
|
|
||||||
# Loop forever reading the form's values, updating the Input field
|
# Loop forever reading the window's values, updating the Input field
|
||||||
keys_entered = ''
|
keys_entered = ''
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read() # read the form
|
button, values = window.Read() # read the window
|
||||||
if button is None: # if the X button clicked, just exit
|
if button is None: # if the X button clicked, just exit
|
||||||
break
|
break
|
||||||
if button == 'Clear': # clear keys if clear button
|
if button == 'Clear': # clear keys if clear button
|
||||||
|
@ -728,9 +729,9 @@ There are a number of features used in this Recipe including:
|
||||||
keys_entered += button # add the new digit
|
keys_entered += button # add the new digit
|
||||||
elif button == 'Submit':
|
elif button == 'Submit':
|
||||||
keys_entered = values['input']
|
keys_entered = values['input']
|
||||||
form.FindElement('out').Update(keys_entered) # output the final string
|
window.FindElement('out').Update(keys_entered) # output the final string
|
||||||
|
|
||||||
form.FindElement('input').Update(keys_entered) # change the form to reflect current key string
|
window.FindElement('input').Update(keys_entered) # change the window to reflect current key string
|
||||||
|
|
||||||
## Animated Matplotlib Graph
|
## Animated Matplotlib Graph
|
||||||
|
|
||||||
|
@ -759,13 +760,13 @@ Use the Canvas Element to create an animated graph. The code is a bit tricky to
|
||||||
[g.Canvas(size=(640, 480), key='canvas')],
|
[g.Canvas(size=(640, 480), key='canvas')],
|
||||||
[g.ReadButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]]
|
[g.ReadButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]]
|
||||||
|
|
||||||
# create the form and show it without the plot
|
# create the window and show it without the plot
|
||||||
|
|
||||||
|
|
||||||
form = g.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout)
|
window = g.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout)
|
||||||
form.Finalize() # needed to access the canvas element prior to reading the form
|
window.Finalize() # needed to access the canvas element prior to reading the window
|
||||||
|
|
||||||
canvas_elem = form.FindElement('canvas')
|
canvas_elem = window.FindElement('canvas')
|
||||||
|
|
||||||
graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas)
|
graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas)
|
||||||
canvas = canvas_elem.TKCanvas
|
canvas = canvas_elem.TKCanvas
|
||||||
|
@ -773,7 +774,7 @@ Use the Canvas Element to create an animated graph. The code is a bit tricky to
|
||||||
dpts = [randint(0, 10) for x in range(10000)]
|
dpts = [randint(0, 10) for x in range(10000)]
|
||||||
# Our event loop
|
# Our event loop
|
||||||
for i in range(len(dpts)):
|
for i in range(len(dpts)):
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
if button == 'Exit' or values is None:
|
if button == 'Exit' or values is None:
|
||||||
exit(69)
|
exit(69)
|
||||||
|
|
||||||
|
@ -801,7 +802,7 @@ Saw this example layout written in tkinter and liked it so much I duplicated the
|
||||||
|
|
||||||
This Recipe also contains code that implements the button interactions so that you'll have a template to build from.
|
This Recipe also contains code that implements the button interactions so that you'll have a template to build from.
|
||||||
|
|
||||||
In other GUI frameworks this program would be most likely "event driven" with callback functions being used to communicate button events. The "event loop" would be handled by the GUI engine. If code already existed that used a call-back mechanism, the loop in the example code below could simply call these callback functions directly based on the button text it receives in the form.Read call.
|
In other GUI frameworks this program would be most likely "event driven" with callback functions being used to communicate button events. The "event loop" would be handled by the GUI engine. If code already existed that used a call-back mechanism, the loop in the example code below could simply call these callback functions directly based on the button text it receives in the window.Read call.
|
||||||
|
|
||||||
![timemanagement](https://user-images.githubusercontent.com/13696193/44996818-0f27c100-af78-11e8-8836-9ef6164efe3b.jpg)
|
![timemanagement](https://user-images.githubusercontent.com/13696193/44996818-0f27c100-af78-11e8-8836-9ef6164efe3b.jpg)
|
||||||
|
|
||||||
|
@ -825,43 +826,43 @@ In other GUI frameworks this program would be most likely "event driven" with ca
|
||||||
sg.ReadFormButton('Submit', button_color=('white', 'springgreen4'), key='Submit')]
|
sg.ReadFormButton('Submit', button_color=('white', 'springgreen4'), key='Submit')]
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window("Time Tracker", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False,
|
window = sg.Window("Time Tracker", 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))
|
||||||
form.Layout(layout)
|
window.Layout(layout)
|
||||||
form.Finalize()
|
window.Finalize()
|
||||||
form.FindElement('Stop').Update(disabled=True)
|
window.FindElement('Stop').Update(disabled=True)
|
||||||
form.FindElement('Reset').Update(disabled=True)
|
window.FindElement('Reset').Update(disabled=True)
|
||||||
form.FindElement('Submit').Update(disabled=True)
|
window.FindElement('Submit').Update(disabled=True)
|
||||||
recording = have_data = False
|
recording = have_data = False
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
print(button)
|
print(button)
|
||||||
if button is None:
|
if button is None:
|
||||||
exit(69)
|
exit(69)
|
||||||
if button is 'Start':
|
if button is 'Start':
|
||||||
form.FindElement('Start').Update(disabled=True)
|
window.FindElement('Start').Update(disabled=True)
|
||||||
form.FindElement('Stop').Update(disabled=False)
|
window.FindElement('Stop').Update(disabled=False)
|
||||||
form.FindElement('Reset').Update(disabled=False)
|
window.FindElement('Reset').Update(disabled=False)
|
||||||
form.FindElement('Submit').Update(disabled=True)
|
window.FindElement('Submit').Update(disabled=True)
|
||||||
recording = True
|
recording = True
|
||||||
elif button is 'Stop' and recording:
|
elif button is 'Stop' and recording:
|
||||||
form.FindElement('Stop').Update(disabled=True)
|
window.FindElement('Stop').Update(disabled=True)
|
||||||
form.FindElement('Start').Update(disabled=False)
|
window.FindElement('Start').Update(disabled=False)
|
||||||
form.FindElement('Submit').Update(disabled=False)
|
window.FindElement('Submit').Update(disabled=False)
|
||||||
recording = False
|
recording = False
|
||||||
have_data = True
|
have_data = True
|
||||||
elif button is 'Reset':
|
elif button is 'Reset':
|
||||||
form.FindElement('Stop').Update(disabled=True)
|
window.FindElement('Stop').Update(disabled=True)
|
||||||
form.FindElement('Start').Update(disabled=False)
|
window.FindElement('Start').Update(disabled=False)
|
||||||
form.FindElement('Submit').Update(disabled=True)
|
window.FindElement('Submit').Update(disabled=True)
|
||||||
form.FindElement('Reset').Update(disabled=False)
|
window.FindElement('Reset').Update(disabled=False)
|
||||||
recording = False
|
recording = False
|
||||||
have_data = False
|
have_data = False
|
||||||
elif button is 'Submit' and have_data:
|
elif button is 'Submit' and have_data:
|
||||||
form.FindElement('Stop').Update(disabled=True)
|
window.FindElement('Stop').Update(disabled=True)
|
||||||
form.FindElement('Start').Update(disabled=False)
|
window.FindElement('Start').Update(disabled=False)
|
||||||
form.FindElement('Submit').Update(disabled=True)
|
window.FindElement('Submit').Update(disabled=True)
|
||||||
form.FindElement('Reset').Update(disabled=False)
|
window.FindElement('Reset').Update(disabled=False)
|
||||||
recording = False
|
recording = False
|
||||||
|
|
||||||
## Password Protection For Scripts
|
## Password Protection For Scripts
|
||||||
|
@ -893,12 +894,12 @@ Use the upper half to generate your hash code. Then paste it into the code in t
|
||||||
[sg.T('SHA Hash'), sg.In('', size=(40,1), key='hash')],
|
[sg.T('SHA Hash'), sg.In('', size=(40,1), key='hash')],
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window('SHA Generator', auto_size_text=False, default_element_size=(10,1),
|
window = sg.Window('SHA Generator', auto_size_text=False, default_element_size=(10,1),
|
||||||
text_justification='r', return_keyboard_events=True, grab_anywhere=False).Layout(layout)
|
text_justification='r', return_keyboard_events=True, grab_anywhere=False).Layout(layout)
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
if button is None:
|
if button is None:
|
||||||
exit(69)
|
exit(69)
|
||||||
|
|
||||||
|
@ -908,7 +909,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()
|
||||||
form.FindElement('hash').Update(password_hash)
|
window.FindElement('hash').Update(password_hash)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -942,7 +943,7 @@ For this and the Time & CPU Widgets you may wish to consider using a tool or tec
|
||||||
|
|
||||||
[http://www.robvanderwoude.com/battech_hideconsole.php](http://www.robvanderwoude.com/battech_hideconsole.php)
|
[http://www.robvanderwoude.com/battech_hideconsole.php](http://www.robvanderwoude.com/battech_hideconsole.php)
|
||||||
|
|
||||||
At the moment I'm using the technique that involves wscript and a script named RunNHide.vbs. They are working beautifully. I'm using a hotkey program and launch by using this script with the command "python.exe insert_program_here.py". I guess the next widget should be one that shows all the programs launched this way so you can kill any bad ones. If you don't properly catch the exit button on your form then your while loop is going to keep on working while your window is no longer there so be careful in your code to always have exit explicitly handled.
|
At the moment I'm using the technique that involves wscript and a script named RunNHide.vbs. They are working beautifully. I'm using a hotkey program and launch by using this script with the command "python.exe insert_program_here.py". I guess the next widget should be one that shows all the programs launched this way so you can kill any bad ones. If you don't properly catch the exit button on your window then your while loop is going to keep on working while your window is no longer there so be careful in your code to always have exit explicitly handled.
|
||||||
|
|
||||||
|
|
||||||
### Floating toolbar
|
### Floating toolbar
|
||||||
|
@ -975,7 +976,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):
|
||||||
form.FindElement('output').Update(line)
|
window.FindElement('output').Update(line)
|
||||||
|
|
||||||
sg.ChangeLookAndFeel('Dark')
|
sg.ChangeLookAndFeel('Dark')
|
||||||
|
|
||||||
|
@ -990,11 +991,11 @@ You can easily change colors to match your background by changing a couple of pa
|
||||||
sg.Button('EXIT', button_color=('white','firebrick3'))],
|
sg.Button('EXIT', button_color=('white','firebrick3'))],
|
||||||
[sg.T('', text_color='white', size=(50,1), key='output')]]
|
[sg.T('', text_color='white', size=(50,1), key='output')]]
|
||||||
|
|
||||||
form = sg.Window('Floating Toolbar', no_titlebar=True, keep_on_top=True).Layout(layout)
|
window = sg.Window('Floating Toolbar', no_titlebar=True, keep_on_top=True).Layout(layout)
|
||||||
|
|
||||||
# ---===--- Loop taking in user input (buttons) --- #
|
# ---===--- Loop taking in user input (buttons) --- #
|
||||||
while True:
|
while True:
|
||||||
(button, value) = form.Read()
|
(button, value) = window.Read()
|
||||||
if button == 'EXIT' or button is None:
|
if button == 'EXIT' or button is None:
|
||||||
break # exit button clicked
|
break # exit button clicked
|
||||||
if button == 'Program 1':
|
if button == 'Program 1':
|
||||||
|
@ -1010,7 +1011,7 @@ You can easily change colors to match your background by changing a couple of pa
|
||||||
|
|
||||||
def ExecuteCommandSubprocess(command, *args, wait=False):
|
def ExecuteCommandSubprocess(command, *args, wait=False):
|
||||||
try:
|
try:
|
||||||
if sys.platform == 'linux':
|
if sys.platwindow == 'linux':
|
||||||
arg_string = ''
|
arg_string = ''
|
||||||
for arg in args:
|
for arg in args:
|
||||||
arg_string += ' ' + str(arg)
|
arg_string += ' ' + str(arg)
|
||||||
|
@ -1050,17 +1051,17 @@ Much of the code is handling the button states in a fancy way. It could be much
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# ---------------- Create Form ----------------
|
# ---------------- Create window ----------------
|
||||||
sg.ChangeLookAndFeel('Black')
|
sg.ChangeLookAndFeel('Black')
|
||||||
sg.SetOptions(element_padding=(0, 0))
|
sg.SetOptions(element_padding=(0, 0))
|
||||||
|
|
||||||
form_rows = [[sg.Text('')],
|
layout = [[sg.Text('')],
|
||||||
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
|
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
|
||||||
[sg.ReadButton('Pause', key='button', button_color=('white', '#001480')),
|
[sg.ReadButton('Pause', key='button', button_color=('white', '#001480')),
|
||||||
sg.ReadButton('Reset', button_color=('white', '#007339'), key='Reset'),
|
sg.ReadButton('Reset', button_color=('white', '#007339'), key='Reset'),
|
||||||
sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]
|
sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]
|
||||||
|
|
||||||
form = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout)
|
window = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout)
|
||||||
|
|
||||||
|
|
||||||
# ---------------- main loop ----------------
|
# ---------------- main loop ----------------
|
||||||
|
@ -1070,12 +1071,12 @@ Much of the code is handling the button states in a fancy way. It could be much
|
||||||
while (True):
|
while (True):
|
||||||
# --------- Read and update window --------
|
# --------- Read and update window --------
|
||||||
if not paused:
|
if not paused:
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
current_time = int(round(time.time() * 100)) - start_time
|
current_time = int(round(time.time() * 100)) - start_time
|
||||||
else:
|
else:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
if button == 'button':
|
if button == 'button':
|
||||||
button = form.FindElement(button).GetText()
|
button = window.FindElement(button).GetText()
|
||||||
# --------- Do Button Operations --------
|
# --------- Do Button Operations --------
|
||||||
if values is None or button == 'Exit':
|
if values is None or button == 'Exit':
|
||||||
break
|
break
|
||||||
|
@ -1086,16 +1087,16 @@ Much of the code is handling the button states in a fancy way. It could be much
|
||||||
elif button == 'Pause':
|
elif button == 'Pause':
|
||||||
paused = True
|
paused = True
|
||||||
paused_time = int(round(time.time() * 100))
|
paused_time = int(round(time.time() * 100))
|
||||||
element = form.FindElement('button')
|
element = window.FindElement('button')
|
||||||
element.Update(text='Run')
|
element.Update(text='Run')
|
||||||
elif button == 'Run':
|
elif button == '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 = form.FindElement('button')
|
element = window.FindElement('button')
|
||||||
element.Update(text='Pause')
|
element.Update(text='Pause')
|
||||||
|
|
||||||
# --------- Display timer in window --------
|
# --------- Display timer in window --------
|
||||||
form.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
|
window.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
|
||||||
(current_time // 100) % 60,
|
(current_time // 100) % 60,
|
||||||
current_time % 100))
|
current_time % 100))
|
||||||
time.sleep(.01)
|
time.sleep(.01)
|
||||||
|
@ -1103,7 +1104,7 @@ Much of the code is handling the button states in a fancy way. It could be much
|
||||||
# --------- After loop --------
|
# --------- After loop --------
|
||||||
|
|
||||||
# Broke out of main loop. Close the window.
|
# Broke out of main loop. Close the window.
|
||||||
form.CloseNonBlockingForm()
|
window.CloseNonBlockingForm()
|
||||||
|
|
||||||
## Desktop Floating Widget - CPU Utilization
|
## Desktop Floating Widget - CPU Utilization
|
||||||
|
|
||||||
|
@ -1120,17 +1121,17 @@ The spinner changes the number of seconds between reads. Note that you will get
|
||||||
|
|
||||||
# ---------------- Create Form ----------------
|
# ---------------- Create Form ----------------
|
||||||
sg.ChangeLookAndFeel('Black')
|
sg.ChangeLookAndFeel('Black')
|
||||||
form_rows = [[sg.Text('')],
|
layout = [[sg.Text('')],
|
||||||
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
|
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
|
||||||
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0)), sg.Spin([x+1 for x in range(10)], 1, key='spin')]]
|
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0)), sg.Spin([x+1 for x in range(10)], 1, key='spin')]]
|
||||||
# Layout the rows of the form and perform a read. Indicate the form is non-blocking!
|
# Layout the rows of the window and perform a read. Indicate the window is non-blocking!
|
||||||
form = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(form_rows)
|
window = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout)
|
||||||
|
|
||||||
|
|
||||||
# ---------------- main loop ----------------
|
# ---------------- main loop ----------------
|
||||||
while (True):
|
while (True):
|
||||||
# --------- Read and update window --------
|
# --------- Read and update window --------
|
||||||
button, values = form.ReadNonBlocking()
|
button, values = window.ReadNonBlocking()
|
||||||
|
|
||||||
# --------- Do Button Operations --------
|
# --------- Do Button Operations --------
|
||||||
if values is None or button == 'Exit':
|
if values is None or button == 'Exit':
|
||||||
|
@ -1144,16 +1145,16 @@ The spinner changes the number of seconds between reads. Note that you will get
|
||||||
|
|
||||||
# --------- Display timer in window --------
|
# --------- Display timer in window --------
|
||||||
|
|
||||||
form.FindElement('text').Update(f'CPU {cpu_percent:02.0f}%')
|
window.FindElement('text').Update(f'CPU {cpu_percent:02.0f}%')
|
||||||
|
|
||||||
# Broke out of main loop. Close the window.
|
# Broke out of main loop. Close the window.
|
||||||
form.CloseNonBlockingForm()
|
window.CloseNonBlockingForm()
|
||||||
|
|
||||||
## Menus
|
## Menus
|
||||||
|
|
||||||
Menus are nothing more than buttons that live in a menu-bar. When you click on a menu item, you get back a "button" with that menu item's text, just as you would had that text been on a button.
|
Menus are nothing more than buttons that live in a menu-bar. When you click on a menu item, you get back a "button" with that menu item's text, just as you would had that text been on a button.
|
||||||
|
|
||||||
Menu's are defined separately from the GUI form. To add one to your form, simply insert sg.Menu(menu_layout). The menu definition is a list of menu choices and submenus. They are a list of lists. Copy the Recipe and play with it. You'll eventually get when you're looking for.
|
Menu's are defined separately from the GUI window. To add one to your window, simply insert sg.Menu(menu_layout). The menu definition is a list of menu choices and submenus. They are a list of lists. Copy the Recipe and play with it. You'll eventually get when you're looking for.
|
||||||
|
|
||||||
If you double click the dashed line at the top of the list of choices, that menu will tear off and become a floating toolbar. How cool!
|
If you double click the dashed line at the top of the list of choices, that menu will tear off and become a floating toolbar. How cool!
|
||||||
|
|
||||||
|
@ -1178,12 +1179,12 @@ If you double click the dashed line at the top of the list of choices, that menu
|
||||||
[sg.Output(size=(60, 20))]
|
[sg.Output(size=(60, 20))]
|
||||||
]
|
]
|
||||||
|
|
||||||
form = sg.Window("Windows-like program", default_element_size=(12, 1), auto_size_text=False, auto_size_buttons=False,
|
window = sg.Window("Windows-like program", default_element_size=(12, 1), auto_size_text=False, auto_size_buttons=False,
|
||||||
default_button_element_size=(12, 1)).Layout(layout)
|
default_button_element_size=(12, 1)).Layout(layout)
|
||||||
|
|
||||||
# ------ Loop & Process button menu choices ------ #
|
# ------ Loop & Process button menu choices ------ #
|
||||||
while True:
|
while True:
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
if button == None or button == 'Exit':
|
if button == None or button == 'Exit':
|
||||||
break
|
break
|
||||||
print('Button = ', button)
|
print('Button = ', button)
|
||||||
|
@ -1209,9 +1210,9 @@ In this example we're defining our graph to be from -100, -100 to +100,+100. Th
|
||||||
|
|
||||||
layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-100,-100), graph_top_right=(100,100), background_color='white', key='graph')],]
|
layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(-100,-100), graph_top_right=(100,100), background_color='white', key='graph')],]
|
||||||
|
|
||||||
form = sg.Window('Graph of Sine Function').Layout(layout)
|
window = sg.Window('Graph of Sine Function').Layout(layout)
|
||||||
form.Finalize()
|
window.Finalize()
|
||||||
graph = form.FindElement('graph')
|
graph = window.FindElement('graph')
|
||||||
|
|
||||||
graph.DrawLine((-100,0), (100,0))
|
graph.DrawLine((-100,0), (100,0))
|
||||||
graph.DrawLine((0,-100), (0,100))
|
graph.DrawLine((0,-100), (0,100))
|
||||||
|
@ -1220,7 +1221,7 @@ In this example we're defining our graph to be from -100, -100 to +100,+100. Th
|
||||||
y = math.sin(x/20)*50
|
y = math.sin(x/20)*50
|
||||||
graph.DrawPoint((x,y), color='red')
|
graph.DrawPoint((x,y), color='red')
|
||||||
|
|
||||||
button, values = form.Read()
|
button, values = window.Read()
|
||||||
|
|
||||||
|
|
||||||
## Creating a Windows .EXE File
|
## Creating a Windows .EXE File
|
||||||
|
|
Loading…
Reference in New Issue