Major update of all demo programs to use new PEP8 bindings, etc
This commit is contained in:
parent
3f7c87c562
commit
7f52778bcc
307 changed files with 19546 additions and 3297 deletions
Binary file not shown.
Before Width: | Height: | Size: 95 KiB |
Binary file not shown.
Before Width: | Height: | Size: 298 KiB |
|
@ -1,11 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
'''
|
||||
Example of (almost) all widgets, that you can use in PySimpleGUI.
|
||||
'''
|
||||
|
||||
sg.ChangeLookAndFeel('GreenTan')
|
||||
import PySimpleGUI as sg
|
||||
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
|
||||
# ------ Menu Definition ------ #
|
||||
menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
|
||||
|
@ -14,41 +14,49 @@ menu_def = [['&File', ['&Open', '&Save', 'E&xit', 'Properties']],
|
|||
|
||||
# ------ Column Definition ------ #
|
||||
column1 = [[sg.Text('Column 1', background_color='lightblue', justification='center', size=(10, 1))],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'),
|
||||
initial_value='Spin Box 1')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'),
|
||||
initial_value='Spin Box 2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3')]]
|
||||
|
||||
layout = [
|
||||
[sg.Menu(menu_def, tearoff=True)],
|
||||
[sg.Text('(Almost) All widgets in one Window!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
|
||||
[sg.Text('(Almost) All 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.InputText('This is my text')],
|
||||
[sg.Frame(layout=[
|
||||
[sg.Checkbox('Checkbox', size=(10,1)), sg.Checkbox('My second checkbox!', default=True)],
|
||||
[sg.Radio('My first Radio! ', "RADIO1", default=True, size=(10,1)), sg.Radio('My second Radio!', "RADIO1")]], title='Options',title_color='red', relief=sg.RELIEF_SUNKEN, tooltip='Use these to set flags')],
|
||||
[sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3)),
|
||||
sg.Multiline(default_text='A second multi-line', size=(35, 3))],
|
||||
[sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)),
|
||||
[sg.CBox('Checkbox', size=(10, 1)),
|
||||
sg.CBox('My second checkbox!', default=True)],
|
||||
[sg.Radio('My first Radio! ', "RADIO1", default=True, size=(10, 1)),
|
||||
sg.Radio('My second Radio!', "RADIO1")]], title='Options',
|
||||
title_color='red',
|
||||
relief=sg.RELIEF_SUNKEN,
|
||||
tooltip='Use these to set flags')],
|
||||
[sg.MLine(default_text='This is the default Text should you decide not to type anything', size=(35, 3)),
|
||||
sg.MLine(default_text='A second multi-line', size=(35, 3))],
|
||||
[sg.Combo(('Combobox 1', 'Combobox 2'), size=(20, 1)),
|
||||
sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)],
|
||||
[sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))],
|
||||
[sg.OptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))],
|
||||
[sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),
|
||||
sg.Frame('Labelled Group',[[
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25, tick_interval=25),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10),
|
||||
sg.Column(column1, background_color='lightblue')]])],
|
||||
sg.Frame('Labelled Group', [[
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25, tick_interval=25),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10),
|
||||
sg.Col(column1, background_color='lightblue')]])
|
||||
],
|
||||
[sg.Text('_' * 80)],
|
||||
[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), justification='right'),
|
||||
sg.InputText('Default Folder'), sg.FolderBrowse()],
|
||||
[sg.Submit(tooltip='Click to submit this form'), sg.Cancel()]]
|
||||
|
||||
window = sg.Window('Everything bagel', default_element_size=(40, 1), grab_anywhere=False).Layout(layout)
|
||||
event, values = window.Read()
|
||||
window = sg.Window('Everything bagel', layout,
|
||||
default_element_size=(40, 1), grab_anywhere=False)
|
||||
|
||||
sg.Popup('Title',
|
||||
event, values = window.read()
|
||||
sg.popup('Title',
|
||||
'The results of the window.',
|
||||
'The button clicked was "{}"'.format(event),
|
||||
'The values are', values)
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,24 @@
|
|||
import PySimpleGUI as sg
|
||||
import random
|
||||
|
||||
# Bars drawing in PySimpleGUI
|
||||
#
|
||||
# .--.
|
||||
# | |
|
||||
# .--.| |.--.
|
||||
# | || || |
|
||||
# | || || |
|
||||
# | || || |
|
||||
# .--.| || || |
|
||||
# .--.| || || || |.--.
|
||||
# | || || || || || |
|
||||
# | || || || || || |
|
||||
# .--.| || || || || || |.--.
|
||||
# | || || || || || || || |.--.
|
||||
# | || || || || || || || || |
|
||||
# '--''--''--''--''--''--''--''--''--'
|
||||
|
||||
|
||||
BAR_WIDTH = 50
|
||||
BAR_SPACING = 75
|
||||
EDGE_OFFSET = 3
|
||||
|
@ -9,21 +27,25 @@ DATA_SIZE = (500,500)
|
|||
|
||||
graph = sg.Graph(GRAPH_SIZE, (0,0), DATA_SIZE)
|
||||
|
||||
layout = [[sg.Text('Bar graphs using PySimpleGUI')],
|
||||
layout = [[sg.Text('Labelled Bar graphs using PySimpleGUI')],
|
||||
[graph],
|
||||
[sg.Button('OK')]]
|
||||
[sg.Button('OK'), sg.T('Click to display more data'), sg.Exit()]]
|
||||
|
||||
window = sg.Window('Window Title', layout)
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
graph.Erase()
|
||||
if event is None:
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
graph.erase()
|
||||
for i in range(7):
|
||||
graph_value = random.randint(0, 400)
|
||||
graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
|
||||
graph.draw_rectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
|
||||
bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
|
||||
graph.DrawText(text=graph_value, location=(i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))
|
||||
window.Close()
|
||||
graph.draw_text(text=graph_value, location=(i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))
|
||||
window.close()
|
||||
# del window
|
||||
|
||||
while True:
|
||||
pass
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
# Base64 Encoder - encodes a folder of PNG files and creates a .py file with definitions
|
||||
import PySimpleGUI as sg
|
||||
import os
|
||||
import base64
|
||||
|
||||
'''
|
||||
Base64 Encoder - encodes a folder of PNG files and creates a .py file with definitions
|
||||
Make base64 images
|
||||
input: folder with .png .ico .gif 's
|
||||
output: output.py file with variables
|
||||
'''
|
||||
|
||||
OUTPUT_FILENAME = 'output.py'
|
||||
|
||||
def main():
|
||||
# folder = r'C:\Python\PycharmProjects\GooeyGUI\Uno Cards'
|
||||
folder=''
|
||||
folder = sg.PopupGetFolder('Source folder for images\nImages will be encoded and results saved to %s'%OUTPUT_FILENAME,
|
||||
title='Base64 Encoder',
|
||||
default_path=folder, initial_folder=folder )
|
||||
OUTPUT_FILENAME = 'output.py'
|
||||
|
||||
if folder is None or folder == '':
|
||||
sg.PopupCancel('Cancelled - No valid folder entered')
|
||||
folder = sg.popup_get_folder('Source folder for images\nImages will be encoded and results saved to %s'%OUTPUT_FILENAME,
|
||||
title='Base64 Encoder')
|
||||
|
||||
if not folder:
|
||||
sg.popup_cancel('Cancelled - No valid folder entered')
|
||||
return
|
||||
try:
|
||||
namesonly = [f for f in os.listdir(folder) if f.endswith('.png') or f.endswith('.ico') or f.endswith('.gif')]
|
||||
except:
|
||||
sg.PopupCancel('Cancelled - No valid folder entered')
|
||||
sg.popup_cancel('Cancelled - No valid folder entered')
|
||||
return
|
||||
|
||||
outfile = open(os.path.join(folder, OUTPUT_FILENAME), 'w')
|
||||
|
@ -29,12 +29,11 @@ def main():
|
|||
for i, file in enumerate(namesonly):
|
||||
contents = open(os.path.join(folder, file), 'rb').read()
|
||||
encoded = base64.b64encode(contents)
|
||||
outfile.write('\n{} = {}\n\n'.format(file[:file.index(".")], encoded))
|
||||
sg.OneLineProgressMeter('Base64 Encoding', i+1, len(namesonly),key='_METER_')
|
||||
outfile.write('\n{} = {}'.format(file[:file.index(".")], encoded))
|
||||
sg.OneLineProgressMeter('Base64 Encoding', i+1, len(namesonly), key='-METER-')
|
||||
|
||||
outfile.close()
|
||||
sg.Popup('Completed!', 'Encoded %s files'%(i+1))
|
||||
|
||||
sg.popup('Completed!', 'Encoded %s files'%(i+1))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
|
@ -1,22 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
Turn off padding in order to get a really tight looking layout.
|
||||
"""
|
||||
# Turn off padding in order to get a really tight looking layout.
|
||||
|
||||
sg.ChangeLookAndFeel('Dark')
|
||||
sg.SetOptions(element_padding=(0, 0))
|
||||
sg.change_look_and_feel('Dark')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [[sg.T('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User 2'), size=(20, 1)),
|
||||
sg.T('0', size=(8, 1))],
|
||||
[sg.T('Customer:', pad=((3, 0), 0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20, 1)),
|
||||
sg.T('1', size=(8, 1))],
|
||||
[sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black')],
|
||||
layout = [[sg.Text('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User 2'), size=(20, 1)),
|
||||
sg.Text('0', size=(8, 1))],
|
||||
[sg.Text('Customer:', pad=((3, 0), 0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20, 1)),
|
||||
sg.Text('1', size=(8, 1))],
|
||||
[sg.Text('Notes:', pad=((3, 0), 0)),
|
||||
sg.Input(size=(44, 1), background_color='white', text_color='black')],
|
||||
[sg.Button('Start', button_color=('white', 'black')),
|
||||
sg.Button('Stop', button_color=('gray50', 'black')),
|
||||
sg.Button('Reset', button_color=('white', '#9B0023')),
|
||||
|
@ -24,6 +19,7 @@ layout = [[sg.T('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User
|
|||
sg.Button('Exit', button_color=('white', '#00406B'))]]
|
||||
|
||||
window = sg.Window("Borderless Window",
|
||||
layout,
|
||||
default_element_size=(12, 1),
|
||||
text_justification='r',
|
||||
auto_size_text=False,
|
||||
|
@ -32,11 +28,7 @@ window = sg.Window("Borderless Window",
|
|||
grab_anywhere=True,
|
||||
default_button_element_size=(12, 1))
|
||||
|
||||
window.Layout(layout)
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
if event is None or event == 'Exit':
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
import winsound
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
|
||||
if not sys.platform.startswith('win'):
|
||||
sg.PopupError('Sorry, you gotta be on Windows')
|
||||
sys.exit()
|
||||
import winsound
|
||||
sg.popup_error('Sorry, you gotta be on Windows')
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# sg.ChangeLookAndFeel('Dark')
|
||||
# sg.SetOptions(element_padding=(0,0))
|
||||
# sg.change_look_and_feel('Dark')
|
||||
# sg.set_options(element_padding=(0,0))
|
||||
|
||||
layout = [
|
||||
[sg.Button('Start', button_color=('white', 'black'), key='start'),
|
||||
sg.Button('Stop', button_color=('white', 'black'), key='stop'),
|
||||
sg.Button('Reset', button_color=('white', 'firebrick3'), key='reset'),
|
||||
sg.Button('Submit', button_color=('white', 'springgreen4'), key='submit')]
|
||||
]
|
||||
[sg.Button('Start', button_color=('white', 'black'), key='start'),
|
||||
sg.Button('Stop', button_color=('white', 'black'), key='stop'),
|
||||
sg.Button('Reset', button_color=('white', 'firebrick3'), key='reset'),
|
||||
sg.Button('Submit', button_color=('white', 'springgreen4'), key='submit')]
|
||||
]
|
||||
|
||||
window = sg.Window("Button Click", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False, default_button_element_size=(12,1), use_default_focus=False).Layout(layout).Finalize()
|
||||
window = sg.Window("Button Click", layout, finalize=True,
|
||||
default_element_size=(12, 1), text_justification='r',
|
||||
auto_size_text=False, auto_size_buttons=False,
|
||||
default_button_element_size=(12, 1), use_default_focus=False )
|
||||
|
||||
window.FindElement('submit').Update(disabled=True)
|
||||
window['submit'].update(disabled=True)
|
||||
|
||||
recording = have_data = False
|
||||
while True:
|
||||
event, values = window.Read(timeout=100)
|
||||
event, values = window.read(timeout=100)
|
||||
if event is None:
|
||||
sys.exit(69)
|
||||
winsound.PlaySound("ButtonClick.wav", 1) if event != sg.TIMEOUT_KEY else None
|
||||
break
|
||||
if event != sg.TIMEOUT_KEY:
|
||||
winsound.PlaySound("ButtonClick.wav", 1)
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
Demo Button Function Calls
|
||||
|
@ -18,21 +14,24 @@ It is quite easy to simulate these callbacks however. The way to do this is to
|
|||
to your Event Loop
|
||||
"""
|
||||
|
||||
|
||||
def callback_function1():
|
||||
sg.Popup('In Callback Function 1')
|
||||
sg.popup('In Callback Function 1')
|
||||
print('In the callback function 1')
|
||||
|
||||
|
||||
def callback_function2():
|
||||
sg.Popup('In Callback Function 2')
|
||||
sg.popup('In Callback Function 2')
|
||||
print('In the callback function 2')
|
||||
|
||||
layout = [ [sg.Text('Demo of Button Callbacks')],
|
||||
[sg.Button('Button 1'), sg.Button('Button 2')] ]
|
||||
|
||||
window = sg.Window('Button Callback Simulation').Layout(layout)
|
||||
layout = [[sg.Text('Demo of Button Callbacks')],
|
||||
[sg.Button('Button 1'), sg.Button('Button 2')]]
|
||||
|
||||
window = sg.Window('Button Callback Simulation', layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event is None:
|
||||
break
|
||||
elif event == 'Button 1':
|
||||
|
@ -40,4 +39,4 @@ while True: # Event Loop
|
|||
elif event == 'Button 2':
|
||||
callback_function2() # call the "Callback" function
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -1,51 +1,60 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
Demonstrates using a "tight" layout with a Dark theme.
|
||||
Shows how button states can be controlled by a user application. The program manages the disabled/enabled
|
||||
states for buttons and changes the text color to show greyed-out (disabled) buttons
|
||||
"""
|
||||
|
||||
sg.ChangeLookAndFeel('Dark')
|
||||
sg.SetOptions(element_padding=(0,0))
|
||||
sg.change_look_and_feel('Dark')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [[sg.T('User:', pad=((3,0),0)), sg.OptionMenu(values = ('User 1', 'User 2'), size=(20,1)), sg.T('0', size=(8,1))],
|
||||
[sg.T('Customer:', pad=((3,0),0)), sg.OptionMenu(values=('Customer 1', 'Customer 2'), size=(20,1)), sg.T('1', size=(8,1))],
|
||||
[sg.T('Notes:', pad=((3,0),0)), sg.In(size=(44,1), background_color='white', text_color='black')],
|
||||
[sg.Button('Start', button_color=('white', 'black'), key='_Start_'),
|
||||
sg.Button('Stop', button_color=('white', 'black'), key='_Stop_'),
|
||||
sg.Button('Reset', button_color=('white', 'firebrick3'), key='_Reset_'),
|
||||
sg.Button('Submit', button_color=('white', 'springgreen4'), key='_Submit_')]]
|
||||
layout = [[sg.Text('User:', pad=((3, 0), 0)), sg.OptionMenu(values=('User 1', 'User 2'), size=(20, 1)), sg.Text('0', size=(8, 1))],
|
||||
[sg.Text('Customer:', pad=((3, 0), 0)), sg.OptionMenu(
|
||||
values=('Customer 1', 'Customer 2'), size=(20, 1)), sg.Text('1', size=(8, 1))],
|
||||
[sg.Text('Notes:', pad=((3, 0), 0)), sg.Input(size=(44, 1),
|
||||
background_color='white', text_color='black')],
|
||||
[sg.Button('Start', button_color=('white', 'black'), key='-Start-'),
|
||||
sg.Button('Stop', button_color=('white', 'black'), key='-Stop-'),
|
||||
sg.Button('Reset', button_color=('white', 'firebrick3'), key='-Reset-'),
|
||||
sg.Button('Submit', button_color=('white', 'springgreen4'), key='-Submit-')]]
|
||||
|
||||
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)).Layout(layout).Finalize()
|
||||
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),
|
||||
finalize=True)
|
||||
|
||||
|
||||
for key, state in {'_Start_': False, '_Stop_': True, '_Reset_': True, '_Submit_': True}.items():
|
||||
window.FindElement(key).Update(disabled=state)
|
||||
for key, state in {'-Start-': False, '-Stop-': True, '-Reset-': True, '-Submit-': True}.items():
|
||||
window[key].update(disabled=state)
|
||||
|
||||
recording = have_data = False
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
print(event)
|
||||
if event is None:
|
||||
sys.exit(69)
|
||||
if event == '_Start_':
|
||||
for key, state in {'_Start_':True, '_Stop_':False, '_Reset_':False, '_Submit_':True}.items():
|
||||
window.FindElement(key).Update(disabled=state)
|
||||
break
|
||||
if event == '-Start-':
|
||||
for key, state in {'-Start-': True, '-Stop-': False, '-Reset-': False, '-Submit-': True}.items():
|
||||
window[key].update(disabled=state)
|
||||
recording = True
|
||||
elif event == '_Stop_' and recording:
|
||||
[window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':False, '_Submit_':False}.items()]
|
||||
elif event == '-Stop-' and recording:
|
||||
[window[key].update(disabled=value) for key, value in {
|
||||
'-Start-': False, '-Stop-': True, '-Reset-': False, '-Submit-': False}.items()]
|
||||
recording = False
|
||||
have_data = True
|
||||
elif event == '_Reset_':
|
||||
[window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':True, '_Submit_':True}.items()]
|
||||
elif event == '-Reset-':
|
||||
[window[key].update(disabled=value) for key, value in {
|
||||
'-Start-': False, '-Stop-': True, '-Reset-': True, '-Submit-': True}.items()]
|
||||
recording = False
|
||||
have_data = False
|
||||
elif event == '_Submit_' and have_data:
|
||||
[window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':True, '_Submit_':False}.items()]
|
||||
elif event == '-Submit-' and have_data:
|
||||
[window[key].update(disabled=value) for key, value in {
|
||||
'-Start-': False, '-Stop-': True, '-Reset-': True, '-Submit-': False}.items()]
|
||||
recording = False
|
||||
|
||||
window.close()
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,50 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import time
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
|
||||
def show_win():
|
||||
sg.SetOptions(border_width=0, margins=(0,0), element_padding=(5,3))
|
||||
sg.set_options(border_width=0, margins=(0, 0), element_padding=(5, 3))
|
||||
|
||||
frame_layout = [
|
||||
[sg.Button('', image_data=mac_red,
|
||||
button_color=('white', sg.COLOR_SYSTEM_DEFAULT), key='-exit-'),
|
||||
sg.Button('', image_data=mac_orange,
|
||||
button_color=('white', sg.COLOR_SYSTEM_DEFAULT)),
|
||||
sg.Button('', image_data=mac_green,
|
||||
button_color=('white', sg.COLOR_SYSTEM_DEFAULT), key='-minimize-'),
|
||||
sg.Text(' '*40)], ]
|
||||
|
||||
frame_layout = [ [sg.Button('', image_data=mac_red, button_color=('white', sg.COLOR_SYSTEM_DEFAULT), key='_exit_'),
|
||||
sg.Button('', image_data=mac_orange, button_color=('white', sg.COLOR_SYSTEM_DEFAULT)),
|
||||
sg.Button('', image_data=mac_green, button_color=('white', sg.COLOR_SYSTEM_DEFAULT), key='_minimize_'),
|
||||
sg.Text(' '*40)],]
|
||||
layout = [[sg.Frame('', frame_layout)],
|
||||
[sg.Text('')],
|
||||
[sg.Text('My Mac-alike window', size=(25, 2))], ]
|
||||
|
||||
layout = [[sg.Frame('',frame_layout)],
|
||||
[sg.T('')],
|
||||
[ sg.Text(' My Mac-alike window', size=(25,2)) ],]
|
||||
|
||||
window = sg.Window('My new window',
|
||||
no_titlebar=True,
|
||||
grab_anywhere=True,
|
||||
alpha_channel=0,
|
||||
).Layout(layout).Finalize()
|
||||
window = sg.Window('My new window', layout,
|
||||
no_titlebar=True, grab_anywhere=True,
|
||||
alpha_channel=0, finalize=True)
|
||||
|
||||
for i in range(100):
|
||||
window.SetAlpha(i/100)
|
||||
window.eet_alpha(i/100)
|
||||
time.sleep(.01)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
if event is None or event == '_exit_':
|
||||
event, values = window.read()
|
||||
if event is None or event == '-exit-':
|
||||
break
|
||||
if event == '_minimize_':
|
||||
if event == '-minimize-':
|
||||
# window.Minimize() # cannot minimize a window with no titlebar
|
||||
pass
|
||||
print(event, values)
|
||||
|
||||
|
||||
|
||||
mac_red = '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'
|
||||
|
||||
mac_green = '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'
|
||||
|
||||
mac_orange = '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'
|
||||
|
||||
|
||||
show_win()
|
||||
show_win()
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,15 +1,13 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[sg.T('Calendar Test')],
|
||||
[sg.In('', size=(20,1), key='input')],
|
||||
|
||||
layout = [[sg.Text('Calendar Test')],
|
||||
[sg.Input('', size=(20, 1), key='input')],
|
||||
[sg.CalendarButton('Choose Date', target='input', key='date')],
|
||||
[sg.Ok(key=1)]]
|
||||
|
||||
window = sg.Window('Calendar', grab_anywhere=False).Layout(layout)
|
||||
event,values = window.Read()
|
||||
sg.Popup(values['input'])
|
||||
window = sg.Window('Calendar', layout, grab_anywhere=False)
|
||||
event, values = window.read()
|
||||
sg.popup(values['input'])
|
||||
windowclose()
|
||||
|
|
|
@ -1,22 +1,18 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [
|
||||
[sg.Canvas(size=(150, 150), background_color='red', key='canvas')],
|
||||
[sg.T('Change circle color to:'), sg.Button('Red'), sg.Button('Blue')]
|
||||
]
|
||||
[sg.Canvas(size=(150, 150), background_color='red', key='canvas')],
|
||||
[sg.Text('Change circle color to:'), sg.Button('Red'), sg.Button('Blue')]
|
||||
]
|
||||
|
||||
window = sg.Window('Canvas test').Layout(layout).Finalize()
|
||||
window = sg.Window('Canvas test', layout, finalize=True)
|
||||
|
||||
cir = window.FindElement('canvas').TKCanvas.create_oval(50, 50, 100, 100)
|
||||
cir = window['canvas'].TKCanvas.create_oval(50, 50, 100, 100)
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event is None:
|
||||
break
|
||||
if event in ('Blue', 'Red'):
|
||||
window.FindElement('canvas').TKCanvas.itemconfig(cir, fill=event)
|
||||
window['canvas'].TKCanvas.itemconfig(cir, fill=event)
|
||||
|
|
|
@ -7,12 +7,13 @@ import PySimpleGUI as sg
|
|||
In this program, as soon as a listbox entry is clicked, the read returns.
|
||||
"""
|
||||
|
||||
sg.ChangeLookAndFeel('GreenTan')
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
|
||||
layout = [ [sg.Text('Look and Feel Browser')],
|
||||
[sg.Text('Click a look and feel color to see demo window')],
|
||||
[sg.Listbox(values=sg.list_of_look_and_feel_values(), size=(20,12), key='-LIST-', enable_events=True)],
|
||||
[sg.Button('Show Window'), sg.Button('Exit')] ]
|
||||
layout = [[sg.Text('Look and Feel Browser')],
|
||||
[sg.Text('Click a look and feel color to see demo window')],
|
||||
[sg.Listbox(values=sg.list_of_look_and_feel_values(),
|
||||
size=(20, 12), key='-LIST-', enable_events=True)],
|
||||
[sg.Button('Show Window'), sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Look and Feel Browser', layout)
|
||||
|
||||
|
@ -22,4 +23,5 @@ while True: # Event Loop
|
|||
break
|
||||
sg.change_look_and_feel(values['-LIST-'][0])
|
||||
sg.popup_get_text('This is {}'.format(values['-LIST-'][0]))
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,48 +1,46 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
"""
|
||||
Demonstrates the new change_submits parameter for inputtext elements
|
||||
It ONLY submits when a button changes the field, not normal user input
|
||||
Be careful on persistent forms to not clear the input
|
||||
"""
|
||||
layout = [[ sg.Text('Test of reading input field') ],
|
||||
[sg.T('This input is normal'), sg.In()],
|
||||
[sg.T('This input change submits'), sg.In(change_submits=True)],
|
||||
[sg.T('This multiline input change submits'), sg.Multiline(change_submits=True, do_not_clear=True)],
|
||||
[sg.T('This input is normal'), sg.In(), sg.FileBrowse()],
|
||||
[sg.T('File Browse submits'), sg.In(change_submits=True,
|
||||
do_not_clear=True,
|
||||
key='_in1_'), sg.FileBrowse()],
|
||||
[sg.T('Color Chooser submits'), sg.In(change_submits=True,
|
||||
do_not_clear=True,
|
||||
key='_in2_'), sg.ColorChooserButton('Color...', target=(sg.ThisRow, -1))],
|
||||
[sg.T('Folder Browse submits'), sg.In(change_submits=True,
|
||||
do_not_clear=True,
|
||||
key='_in3_'), sg.FolderBrowse()],
|
||||
[sg.T('Calendar Chooser submits'), sg.In(change_submits=True,
|
||||
do_not_clear=True,
|
||||
key='_in4_'), sg.CalendarButton('Date...', target=(sg.ThisRow, -1))],
|
||||
[sg.T('Disabled input submits'), sg.In(change_submits=True,
|
||||
do_not_clear=True,
|
||||
disabled=True,
|
||||
key='_in5'), sg.FileBrowse()],
|
||||
[sg.T('This input clears after submit'),sg.In(change_submits=True,
|
||||
key='_in6_'), sg.FileBrowse()],
|
||||
[ sg.Button('Read')]]
|
||||
layout = [[sg.Text('Test of reading input field')],
|
||||
[sg.Text('This input is normal'), sg.Input()],
|
||||
[sg.Text('This input change submits'),
|
||||
sg.Input(change_submits=True)],
|
||||
[sg.Text('This multiline input change submits'),
|
||||
sg.ML('', change_submits=True)],
|
||||
[sg.Text('This input is normal'),
|
||||
sg.Input(), sg.FileBrowse()],
|
||||
[sg.Text('File Browse submits'),
|
||||
sg.Input(change_submits=True,
|
||||
key='-in1-'), sg.FileBrowse()],
|
||||
[sg.Text('Color Chooser submits'),
|
||||
sg.Input(change_submits=True,
|
||||
key='-in2-'), sg.ColorChooserButton('Color...', target=(sg.ThisRow, -1))],
|
||||
[sg.Text('Folder Browse submits'),
|
||||
sg.Input(change_submits=True,
|
||||
key='-in3-'), sg.FolderBrowse()],
|
||||
[sg.Text('Calendar Chooser submits'),
|
||||
sg.Input(change_submits=True,
|
||||
key='-in4-'), sg.CalendarButton('Date...', target=(sg.ThisRow, -1))],
|
||||
[sg.Text('Disabled input submits'),
|
||||
sg.Input(change_submits=True,
|
||||
disabled=True,
|
||||
key='_in5'), sg.FileBrowse()],
|
||||
[sg.Text('This input clears after submit'),
|
||||
sg.Input(change_submits=True, key='-in6-'), sg.FileBrowse()],
|
||||
[sg.Button('Read')]]
|
||||
|
||||
window = sg.Window('Demonstration of InputText with change_submits',
|
||||
auto_size_text=False,
|
||||
default_element_size=(22,1),
|
||||
text_justification='right',
|
||||
).Layout(layout)
|
||||
layout, auto_size_text=False, default_element_size=(22, 1),
|
||||
text_justification='right')
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
print(event, values)
|
||||
if event is None:
|
||||
break
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
'''
|
||||
A chat window. Add call to your send-routine, print the response and you're done
|
||||
|
@ -15,27 +11,27 @@ Note that the size of the display on repl.it is smaller than most, so the sizes
|
|||
Multiline and Output text areas were reduced in the online version. Nothing else was changed
|
||||
'''
|
||||
|
||||
sg.ChangeLookAndFeel('GreenTan') # give our window a spiffy set of colors
|
||||
# give our window a spiffy set of colors
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
|
||||
layout = [ [sg.Text('Your output will go here', size=(40, 1))],
|
||||
[sg.Output(size=(127, 30), font=('Helvetica 10'))],
|
||||
[sg.Multiline(size=(85, 5), enter_submits=True, key='query'),
|
||||
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
|
||||
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
|
||||
layout = [[sg.Text('Your output will go here', size=(40, 1))],
|
||||
[sg.Output(size=(127, 30), font=('Helvetica 10'))],
|
||||
[sg.MLine(size=(85, 5), enter_submits=True, key='query'),
|
||||
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
|
||||
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
|
||||
|
||||
window = sg.Window('Chat window',
|
||||
layout,
|
||||
default_element_size=(30, 2),
|
||||
font=('Helvetica',' 13'),
|
||||
default_button_element_size=(8,2)).Layout(layout)
|
||||
font=('Helvetica', ' 13'),
|
||||
default_button_element_size=(8, 2))
|
||||
|
||||
# ---===--- Loop taking in user input and using it --- #
|
||||
while True:
|
||||
event, value = window.Read()
|
||||
event, value = window.read()
|
||||
if event == 'SEND':
|
||||
query = value['query'].rstrip()
|
||||
# EXECUTE YOUR COMMAND HERE
|
||||
print('The command you entered was {}'.format(query))
|
||||
elif event in (None, 'EXIT'): # quit if exit button or X
|
||||
break
|
||||
sys.exit(69)
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
'''
|
||||
A chatbot with history
|
||||
|
@ -15,46 +11,60 @@ Special keyboard keys:
|
|||
Control C - exit form
|
||||
'''
|
||||
|
||||
|
||||
def ChatBotWithHistory():
|
||||
# ------- Make a new Window ------- #
|
||||
sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors
|
||||
# give our form a spiffy set of colors
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
|
||||
layout = [[sg.Text('Your output will go here', size=(40, 1))],
|
||||
[sg.Output(size=(127, 30), font=('Helvetica 10'))],
|
||||
[sg.T('Command History'), sg.T('', size=(20,3), key='history')],
|
||||
[sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
|
||||
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
|
||||
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
|
||||
layout = [[sg.Text('Your output will go here', size=(40, 1))],
|
||||
[sg.Output(size=(127, 30), font=('Helvetica 10'))],
|
||||
[sg.Text('Command History'),
|
||||
sg.Text('', size=(20, 3), key='history')],
|
||||
[sg.ML(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
|
||||
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
|
||||
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]]
|
||||
|
||||
window = sg.Window('Chat window with history', default_element_size=(30, 2), font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True).Layout(layout)
|
||||
window = sg.Window('Chat window with history', layout,
|
||||
default_element_size=(30, 2),
|
||||
font=('Helvetica', ' 13'),
|
||||
default_button_element_size=(8, 2),
|
||||
return_keyboard_events=True)
|
||||
|
||||
# ---===--- Loop taking in user input and using it --- #
|
||||
command_history = []
|
||||
history_offset = 0
|
||||
|
||||
while True:
|
||||
(event, value) = window.Read()
|
||||
event, value = window.read()
|
||||
|
||||
if event == 'SEND':
|
||||
query = value['query'].rstrip()
|
||||
# EXECUTE YOUR COMMAND HERE
|
||||
print('The command you entered was {}'.format(query))
|
||||
command_history.append(query)
|
||||
history_offset = len(command_history)-1
|
||||
window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear
|
||||
window.FindElement('history').Update('\n'.join(command_history[-3:]))
|
||||
# manually clear input because keyboard events blocks clear
|
||||
window['query'].update('')
|
||||
window['history'].update('\n'.join(command_history[-3:]))
|
||||
|
||||
elif event in (None, 'EXIT'): # quit if exit event or X
|
||||
break
|
||||
|
||||
elif 'Up' in event and len(command_history):
|
||||
command = command_history[history_offset]
|
||||
history_offset -= 1 * (history_offset > 0) # decrement is not zero
|
||||
window.FindElement('query').Update(command)
|
||||
# decrement is not zero
|
||||
history_offset -= 1 * (history_offset > 0)
|
||||
window['query'].update(command)
|
||||
|
||||
elif 'Down' in event and len(command_history):
|
||||
history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list
|
||||
# increment up to end of list
|
||||
history_offset += 1 * (history_offset < len(command_history)-1)
|
||||
command = command_history[history_offset]
|
||||
window.FindElement('query').Update(command)
|
||||
window['query'].update(command)
|
||||
|
||||
elif 'Escape' in event:
|
||||
window.FindElement('query').Update('')
|
||||
|
||||
sys.exit(69)
|
||||
window['query'].update('')
|
||||
|
||||
|
||||
ChatBotWithHistory()
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
from chatterbot import ChatBot
|
||||
import chatterbot.utils
|
||||
|
||||
|
@ -18,36 +13,40 @@ to collect user input that is sent to the chatbot. The reply is displayed in th
|
|||
|
||||
# Create the 'Trainer GUI'
|
||||
# The Trainer GUI consists of a lot of progress bars stacked on top of each other
|
||||
sg.ChangeLookAndFeel('GreenTan')
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
# sg.DebugWin()
|
||||
MAX_PROG_BARS = 20 # number of training sessions
|
||||
bars = []
|
||||
texts = []
|
||||
training_layout = [[sg.T('TRAINING PROGRESS', size=(20, 1), font=('Helvetica', 17))], ]
|
||||
training_layout = [[sg.Text('TRAINING PROGRESS', size=(20, 1), font=('Helvetica', 17))]]
|
||||
for i in range(MAX_PROG_BARS):
|
||||
bars.append(sg.ProgressBar(100, size=(30, 4)))
|
||||
texts.append(sg.T(' ' * 20, size=(20, 1), justification='right'))
|
||||
training_layout += [[texts[i], bars[i]],] # add a single row
|
||||
texts.append(sg.Text(' ' * 20, size=(20, 1), justification='right'))
|
||||
training_layout += [[texts[i], bars[i]], ] # add a single row
|
||||
|
||||
training_window = sg.Window('Training').Layout(training_layout)
|
||||
training_window = sg.Window('Training', training_layout)
|
||||
current_bar = 0
|
||||
|
||||
# callback function for training runs
|
||||
|
||||
|
||||
def print_progress_bar(description, iteration_counter, total_items, progress_bar_length=20):
|
||||
global current_bar
|
||||
global bars
|
||||
global texts
|
||||
global training_window
|
||||
# update the window and the bars
|
||||
button, values = training_window.Read(timeout=0)
|
||||
button, values = training_window.read(timeout=0)
|
||||
if button is None: # if user closed the window on us, exit
|
||||
sys.exit(69)
|
||||
return
|
||||
if bars[current_bar].UpdateBar(iteration_counter, max=total_items) is False:
|
||||
sys.exit(69)
|
||||
texts[current_bar].Update(description) # show the training dataset name
|
||||
return
|
||||
# show the training dataset name
|
||||
texts[current_bar].update(description)
|
||||
if iteration_counter == total_items:
|
||||
current_bar += 1
|
||||
|
||||
|
||||
# redefine the chatbot text based progress bar with a graphical one
|
||||
chatterbot.utils.print_progress_bar = print_progress_bar
|
||||
|
||||
|
@ -59,18 +58,19 @@ chatbot.train("chatterbot.corpus.english")
|
|||
################# GUI #################
|
||||
|
||||
layout = [[sg.Output(size=(80, 20))],
|
||||
[sg.Multiline(size=(70, 5), enter_submits=True),
|
||||
[sg.MLine(size=(70, 5), enter_submits=True),
|
||||
sg.Button('SEND', bind_return_key=True), sg.Button('EXIT')]]
|
||||
|
||||
window = sg.Window('Chat Window', auto_size_text=True, default_element_size=(30, 2)).Layout(layout)
|
||||
window = sg.Window('Chat Window', layout,
|
||||
default_element_size=(30, 2))
|
||||
|
||||
# ---===--- Loop taking in user input and using it to query HowDoI web oracle --- #
|
||||
while True:
|
||||
event, (value,) = window.Read()
|
||||
event, (value,) = window.read()
|
||||
if event != 'SEND':
|
||||
break
|
||||
string = value.rstrip()
|
||||
print(' '+string)
|
||||
print(' ' + string)
|
||||
# send the user input to chatbot to get a response
|
||||
response = chatbot.get_response(value.rstrip())
|
||||
print(response)
|
||||
print(response)
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
from chatterbot import ChatBot
|
||||
import chatterbot.utils
|
||||
|
||||
from gtts import gTTS
|
||||
from pygame import mixer
|
||||
import time
|
||||
|
@ -22,18 +16,18 @@ to collect user input that is sent to the chatbot. The reply is displayed in th
|
|||
|
||||
# Create the 'Trainer GUI'
|
||||
# The Trainer GUI consists of a lot of progress bars stacked on top of each other
|
||||
sg.ChangeLookAndFeel('NeutralBlue')
|
||||
sg.change_look_and_feel('NeutralBlue')
|
||||
# sg.DebugWin()
|
||||
MAX_PROG_BARS = 20 # number of training sessions
|
||||
bars = []
|
||||
texts = []
|
||||
training_layout = [[sg.T('TRAINING PROGRESS', size=(20, 1), font=('Helvetica', 17))], ]
|
||||
training_layout = [[sg.Text('TRAINING PROGRESS', size=(20, 1), font=('Helvetica', 17))], ]
|
||||
for i in range(MAX_PROG_BARS):
|
||||
bars.append(sg.ProgressBar(100, size=(30, 4)))
|
||||
texts.append(sg.T(' ' * 20, size=(20, 1), justification='right'))
|
||||
texts.append(sg.Text(' ' * 20, size=(20, 1), justification='right'))
|
||||
training_layout += [[texts[i], bars[i]],] # add a single row
|
||||
|
||||
training_window = sg.Window('Training').Layout(training_layout)
|
||||
training_window = sg.Window('Training', training_layout)
|
||||
current_bar = 0
|
||||
|
||||
# callback function for training runs
|
||||
|
@ -43,12 +37,12 @@ def print_progress_bar(description, iteration_counter, total_items, progress_bar
|
|||
global texts
|
||||
global training_window
|
||||
# update the window and the bars
|
||||
button, values = training_window.Read(timeout=0)
|
||||
button, values = training_window.read(timeout=0)
|
||||
if button is None: # if user closed the window on us, exit
|
||||
sys.exit(69)
|
||||
if bars[current_bar].UpdateBar(iteration_counter, max=total_items) is False:
|
||||
sys.exit(69)
|
||||
texts[current_bar].Update(description) # show the training dataset name
|
||||
return
|
||||
if bars[current_bar].update_bar(iteration_counter, max=total_items) is False:
|
||||
return
|
||||
texts[current_bar].update(description) # show the training dataset name
|
||||
if iteration_counter == total_items:
|
||||
current_bar += 1
|
||||
|
||||
|
@ -79,14 +73,14 @@ chatbot.train("chatterbot.corpus.english")
|
|||
################# GUI #################
|
||||
|
||||
layout = [[sg.Output(size=(80, 20))],
|
||||
[sg.Multiline(size=(70, 5), enter_submits=True),
|
||||
[sg.MLine(size=(70, 5), enter_submits=True),
|
||||
sg.Button('SEND', bind_return_key=True), sg.Button('EXIT')]]
|
||||
|
||||
window = sg.Window('Chat Window', auto_size_text=True, default_element_size=(30, 2)).Layout(layout)
|
||||
window = sg.Window('Chat Window', layout, default_element_size=(30, 2))
|
||||
|
||||
# ---===--- Loop taking in user input and using it to query HowDoI web oracle --- #
|
||||
while True:
|
||||
event, (value,) = window.Read()
|
||||
event, (value,) = window.read()
|
||||
if event != 'SEND':
|
||||
break
|
||||
string = value.rstrip()
|
||||
|
@ -94,4 +88,6 @@ while True:
|
|||
# send the user input to chatbot to get a response
|
||||
response = chatbot.get_response(value.rstrip())
|
||||
print(response)
|
||||
speak(str(response))
|
||||
speak(str(response))
|
||||
|
||||
window.close()
|
|
@ -1,16 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
MY_WINDOW_ICON = 'E:\\TheRealMyDocs\\Icons\\The Planets\\jupiter.ico'
|
||||
reverse = {}
|
||||
colorhex = {}
|
||||
|
||||
colors = {
|
||||
"abbey" : ( 76, 79, 86),
|
||||
"abbey" : ( 76, 79, 86),
|
||||
"acadia" : ( 27, 20, 4),
|
||||
"acapulco" : (124, 176, 161),
|
||||
"aero blue" : (201, 255, 229),
|
||||
|
@ -1583,9 +1579,9 @@ def build_reverse_dict():
|
|||
global colors
|
||||
for color in colors:
|
||||
rgb = colors[color]
|
||||
hex = '#%02X%02X%02X' % (rgb)
|
||||
reverse[hex] = color
|
||||
colorhex[color] = hex
|
||||
hex_val = '#%02X%02X%02X' % (rgb)
|
||||
reverse[hex_val] = color
|
||||
colorhex[color] = hex_val
|
||||
return
|
||||
|
||||
|
||||
|
@ -1621,9 +1617,9 @@ def get_name_from_hex(hex):
|
|||
global colorhex
|
||||
global colors
|
||||
|
||||
hex = hex.upper()
|
||||
hex_val = hex.upper()
|
||||
try:
|
||||
name = reverse[hex]
|
||||
name = reverse[hex_val]
|
||||
except:
|
||||
name = 'No Hex For Name'
|
||||
return name
|
||||
|
@ -1635,22 +1631,22 @@ def get_hex_from_name(name):
|
|||
|
||||
name = name.lower()
|
||||
try:
|
||||
hex = colorhex[name]
|
||||
hex_val = colorhex[name]
|
||||
except:
|
||||
hex = '#000000'
|
||||
return hex
|
||||
hex_val = '#000000'
|
||||
return hex_val
|
||||
|
||||
def show_all_colors_on_buttons():
|
||||
global reverse
|
||||
global colorhex
|
||||
global colors
|
||||
window = sg.Window('Colors on Buttons Demo', default_element_size=(3, 1), location=(0, 0), icon=MY_WINDOW_ICON, font=("Helvetica", 7))
|
||||
window = sg.Window('Colors on Buttons Demo', default_element_size=(3, 1), location=(0, 0), font=("Helvetica", 7))
|
||||
row = []
|
||||
row_len = 20
|
||||
for i, c in enumerate(colors):
|
||||
hex = get_hex_from_name(c)
|
||||
button1 = sg.CButton(button_text=c, button_color=(get_complementary_hex(hex), hex), size=(8, 1))
|
||||
button2 = sg.CButton(button_text=c, button_color=(hex, get_complementary_hex(hex)), size=(8, 1))
|
||||
hex_val = get_hex_from_name(c)
|
||||
button1 = sg.CButton(button_text=c, button_color=(get_complementary_hex(hex_val), hex_val), size=(8, 1))
|
||||
button2 = sg.CButton(button_text=c, button_color=(hex_val, get_complementary_hex(hex_val)), size=(8, 1))
|
||||
row.append(button1)
|
||||
row.append(button2)
|
||||
if (i+1) % row_len == 0:
|
||||
|
@ -1678,18 +1674,18 @@ def main():
|
|||
list_of_colors = [c for c in colors]
|
||||
printable = '\n'.join(map(str, list_of_colors))
|
||||
# show_all_colors_on_buttons()
|
||||
sg.SetOptions(element_padding=(0,0))
|
||||
sg.set_options(element_padding=(0,0))
|
||||
while True:
|
||||
# ------- Form show ------- #
|
||||
layout = [[sg.Text('Find color')],
|
||||
[sg.Text('Demonstration of colors')],
|
||||
[sg.Text('Enter a color name in text or hex #RRGGBB format')],
|
||||
[sg.InputText(key='hex')],
|
||||
[sg.Listbox(list_of_colors, size=(20, 30), bind_return_key=True, key='listbox'), sg.T('Or choose from list')],
|
||||
[sg.Listbox(list_of_colors, size=(20, 30), bind_return_key=True, key='listbox'), sg.Text('Or choose from list')],
|
||||
[sg.Submit(), sg.Button('Many buttons', button_color=('white', '#0e6251'), key='Many buttons'), sg.ColorChooserButton( 'Chooser', target=(3,0), key='Chooser'), sg.Quit(),],
|
||||
]
|
||||
# [g.Multiline(DefaultText=str(printable), Size=(30,20))]]
|
||||
event, values = sg.Window('Color Demo', auto_size_buttons=False).Layout(layout).Read()
|
||||
event, values = sg.Window('Color Demo', layout, auto_size_buttons=False).read()
|
||||
|
||||
# ------- OUTPUT results portion ------- #
|
||||
if event == 'Quit' or event is None:
|
||||
|
@ -1720,7 +1716,8 @@ def main():
|
|||
[sg.CloseButton(button_text=color_name, button_color=(color_hex, complementary_hex))],
|
||||
[sg.CloseButton(button_text=complementary_hex + ' ' + complementary_color, button_color=(complementary_hex , color_hex), size=(30, 1))],
|
||||
]
|
||||
sg.Window('Color demo', default_element_size=(100, 1), auto_size_text=True, auto_close=True, auto_close_duration=5, icon=MY_WINDOW_ICON).Layout(layout).Read()
|
||||
sg.Window('Color demo', layout, default_element_size=(100, 1),
|
||||
auto_close=True, auto_close_duration=5).read()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
|
||||
|
@ -671,17 +666,18 @@ color_map = {
|
|||
}
|
||||
|
||||
|
||||
sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=1, tooltip_time=100)
|
||||
sg.set_options(button_element_size=(12, 1),
|
||||
element_padding=(0, 0),
|
||||
auto_size_buttons=False,
|
||||
border_width=1, tooltip_time=100)
|
||||
|
||||
#start layout with the tittle
|
||||
layout = [[sg.Text('Hover mouse to see RGB value, click for white & black text',
|
||||
text_color='blue',
|
||||
font='Any 15',
|
||||
relief=sg.RELIEF_SUNKEN,
|
||||
justification='center',
|
||||
size=(100,1),
|
||||
background_color='light green',
|
||||
pad=(0,(0,20))),]]
|
||||
# start layout with the tittle
|
||||
layout = [
|
||||
[sg.Text('Hover mouse to see RGB value, click for white & black text',
|
||||
justification='center',
|
||||
text_color='blue', background_color='light green',
|
||||
size=(100, 1), pad=(0, (0, 20)))]
|
||||
]
|
||||
|
||||
# -- Create primary color viewer window --
|
||||
color_list = [key for key in color_map]
|
||||
|
@ -691,19 +687,25 @@ for rows in range(40):
|
|||
for i in range(12):
|
||||
try:
|
||||
color = color_list[rows+40*i]
|
||||
row.append(sg.Button(color, button_color=('black', color), key=color, tooltip=color_map[color]))
|
||||
row.append(sg.Button(color, button_color=('black', color),
|
||||
key=color, tooltip=color_map[color]))
|
||||
except:
|
||||
pass
|
||||
layout.append(row)
|
||||
|
||||
|
||||
window = sg.Window('Color Viewer', grab_anywhere=False, font=('any 9')).Layout(layout)
|
||||
window = sg.Window('Color Viewer', layout, grab_anywhere=False, font=('any 9'))
|
||||
|
||||
# -- Event loop --
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event is None:
|
||||
break
|
||||
# -- Create a secondary window that shows white and black text on chosen color
|
||||
layout2 =[[sg.DummyButton(event, button_color=('white', event), tooltip=color_map[event]), sg.DummyButton(event, button_color=('black', event), tooltip=color_map[event])] ]
|
||||
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read(timeout=0)
|
||||
layout2 = [[
|
||||
sg.DummyButton(event, button_color=(
|
||||
'white', event), tooltip=color_map[event]),
|
||||
sg.DummyButton(event, button_color=('black', event), tooltip=color_map[event])
|
||||
]]
|
||||
sg.Window('Buttons with white and black text',
|
||||
layout2, keep_on_top=True).read(timeout=0)
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
Color names courtesy of Big Daddy's Wiki-Python
|
||||
|
@ -15,7 +11,6 @@ else:
|
|||
"""
|
||||
|
||||
|
||||
|
||||
COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace',
|
||||
'linen', 'antique white', 'papaya whip', 'blanched almond', 'bisque', 'peach puff',
|
||||
'navajo white', 'lemon chiffon', 'mint cream', 'azure', 'alice blue', 'lavender',
|
||||
|
@ -93,17 +88,18 @@ COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'ol
|
|||
'grey84', 'grey85', 'grey86', 'grey87', 'grey88', 'grey89', 'grey90', 'grey91', 'grey92',
|
||||
'grey93', 'grey94', 'grey95', 'grey97', 'grey98', 'grey99']
|
||||
|
||||
sg.set_options(button_element_size=(12, 1),
|
||||
element_padding=(0, 0),
|
||||
auto_size_buttons=False,
|
||||
border_width=0)
|
||||
|
||||
|
||||
|
||||
sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=0)
|
||||
|
||||
layout = [[sg.Text('Click on a color square to see both white and black text on that color', text_color='blue', font='Any 15')]]
|
||||
layout = [[sg.Text('Click on a color square to see both white and black text on that color',
|
||||
text_color='blue', font='Any 15')]]
|
||||
row = []
|
||||
layout = []
|
||||
|
||||
# -- Create primary color viewer window --
|
||||
for rows in range(40):
|
||||
|
||||
row = []
|
||||
for i in range(12):
|
||||
try:
|
||||
|
@ -113,20 +109,16 @@ for rows in range(40):
|
|||
pass
|
||||
layout.append(row)
|
||||
|
||||
|
||||
# for i, color in enumerate(COLORS):
|
||||
# row.append(sg.Button(color, button_color=('black', color), key=color))
|
||||
# if (i+1) % 12 == 0:
|
||||
# layout.append(row)
|
||||
# row = []
|
||||
|
||||
window = sg.Window('Color Viewer', grab_anywhere=False, font=('any 9')).Layout(layout)
|
||||
window = sg.Window('Color Viewer', layout, grab_anywhere=False, font=('any 9'))
|
||||
|
||||
# -- Event loop --
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event is None:
|
||||
break
|
||||
# -- Create a secondary window that shows white and black text on chosen color
|
||||
layout2 =[[sg.DummyButton(event, button_color=('white', event)), sg.DummyButton(event, button_color=('black', event))]]
|
||||
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read(timeout=0)
|
||||
layout2 = [[sg.DummyButton(event, button_color=('white', event)),
|
||||
sg.DummyButton(event, button_color=('black', event))]]
|
||||
sg.Window('Buttons with white and black text', layout2, keep_on_top=True).read(timeout=0)
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
import PySimpleGUI as sg
|
||||
# this one long import has the effect of making the code more compact as there is no 'sg.' prefix required for Elements
|
||||
from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu, Canvas, Column, Col, Combo, Frame, Graph, Image, InputText, Input, In, Listbox, LBox, Menu, Multiline, ML, MLine, OptionMenu, Output, Pane, ProgressBar, Radio, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, TreeData, VerticalSeparator, Window, Sizer
|
||||
import PySimpleGUI as sg
|
||||
from PySimpleGUI import InputCombo, Combo, Multiline, ML,
|
||||
MLine, Checkbox, CB, Check,
|
||||
Button, B, Btn, ButtonMenu,
|
||||
Canvas, Column, Col, Combo,
|
||||
Frame, Graph, Image, InputText,
|
||||
Input, In, Listbox, LBox, Menu,
|
||||
Multiline, ML, MLine, OptionMenu,
|
||||
Output, Pane, ProgressBar, Radio,
|
||||
Slider, Spin, StatusBar, Tab,
|
||||
TabGroup, Table, Text, Txt, T,
|
||||
Tree, TreeData, VerticalSeparator, Window, Sizer
|
||||
|
||||
"""
|
||||
Demo Columns and Frames
|
||||
|
@ -14,29 +24,33 @@ from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, C
|
|||
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
|
||||
col2 = Column([[Frame('Accounts:', [[Column([[Listbox(['Account '+str(i) for i in range(1,16)], key='-ACCT-LIST-', size=(15,20)),]],size=(150,400))]])]], pad=(0,0))
|
||||
col2 = Column([[Frame('Accounts:', [[Column([[Listbox(['Account '+str(i) for i in range(1, 16)],
|
||||
key='-ACCT-LIST-', size=(15, 20)), ]], size=(150, 400))]])]], pad=(0, 0))
|
||||
|
||||
col1 = Column([
|
||||
# Categories frame
|
||||
[Frame('Categories:', [[Radio('Websites', 'radio1', default=True, key='-WEBSITES-', size=(10, 1)),
|
||||
Radio('Software', 'radio1',key='-SOFTWARE-', size=(10, 1))]],)],
|
||||
Radio('Software', 'radio1', key='-SOFTWARE-', size=(10, 1))]],)],
|
||||
# Information frame
|
||||
[Frame('Information:', [[Column([[Text('Account:')],
|
||||
[Input(key='-ACCOUNT-IN-', size=(19, 1))],
|
||||
[Text('User Id:')],
|
||||
[Input(key='-USERID-IN-', size=(19, 1)), Button('Copy', key='-USERID-')],
|
||||
[Text('Password:')],
|
||||
[Input(key='-PW-IN-', size=(19, 1)), Button('Copy', key='-PASS-')],
|
||||
[Text('Location:')],
|
||||
[Input(key='-LOC-IN-', size=(19, 1)), Button('Copy', key='-LOC')],
|
||||
[Text('Notes:')],
|
||||
[Multiline(key='-NOTES-', size=(25, 5))],
|
||||
], size=(235,350),pad=(0,0))]])],], pad=(0,0))
|
||||
[Input(key='-ACCOUNT-IN-', size=(19, 1))],
|
||||
[Text('User Id:')],
|
||||
[Input(key='-USERID-IN-', size=(19, 1)),
|
||||
Button('Copy', key='-USERID-')],
|
||||
[Text('Password:')],
|
||||
[Input(key='-PW-IN-', size=(19, 1)),
|
||||
Button('Copy', key='-PASS-')],
|
||||
[Text('Location:')],
|
||||
[Input(key='-LOC-IN-', size=(19, 1)),
|
||||
Button('Copy', key='-LOC')],
|
||||
[Text('Notes:')],
|
||||
[Multiline(key='-NOTES-', size=(25, 5))],
|
||||
], size=(235, 350), pad=(0, 0))]])], ], pad=(0, 0))
|
||||
|
||||
col3 = Column([[Frame('Actions:', [[Column([[Button('Save'), Button('Clear'), Button('Delete'),]], size=(450,45), pad=(0,0))]])]], pad=(0,0))
|
||||
col3 = Column([[Frame('Actions:', [[Column([[Button('Save'), Button(
|
||||
'Clear'), Button('Delete'), ]], size=(450, 45), pad=(0, 0))]])]], pad=(0, 0))
|
||||
|
||||
layout = [ [col1, col2],
|
||||
[col3]]
|
||||
layout = [[col1, col2], [col3]]
|
||||
|
||||
window = Window('Passwords', layout)
|
||||
|
||||
|
@ -45,4 +59,5 @@ while True:
|
|||
print(event, values)
|
||||
if event is None:
|
||||
break
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
sg.ChangeLookAndFeel('BlueMono')
|
||||
'''
|
||||
Usage of Column Element
|
||||
'''
|
||||
|
||||
sg.change_look_and_feel('BlueMono')
|
||||
|
||||
css = {'text_color': 'white', 'background_color': 'blue'}
|
||||
# Column layout
|
||||
col = [[sg.Text('col Row 1', text_color='white', background_color='blue')],
|
||||
[sg.Text('col Row 2', text_color='white', background_color='blue'), sg.Input('col input 1')],
|
||||
[sg.Text('col Row 3', text_color='white', background_color='blue'), sg.Input('col input 2')]]
|
||||
col = [[sg.Text('col Row 1', **css)],
|
||||
[sg.Text('col Row 2', **css), sg.Input('col input 1')],
|
||||
[sg.Text('col Row 3', **css), sg.Input('col input 2')]]
|
||||
# Window layout
|
||||
layout = [[sg.Listbox(values=('Listbox Item 1', 'Listbox Item 2', 'Listbox Item 3'),
|
||||
select_mode=sg.LISTBOX_SELECT_MODE_MULTIPLE, size=(20, 3)),
|
||||
sg.Column(col, background_color='blue')],
|
||||
sg.Col(col, background_color='blue')],
|
||||
[sg.Input('Last input')],
|
||||
[sg.OK()]]
|
||||
|
||||
# Display the window and get values
|
||||
event, values = sg.Window('Compact 1-line form with column').Layout(layout).Read()
|
||||
window = sg.Window('Compact 1-line form with column', layout)
|
||||
event, values = window.read()
|
||||
|
||||
sg.Popup(event, values, line_width=200)
|
||||
sg.popup(event, values, line_width=200)
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import PySimpleGUI as sg
|
||||
# Import the elements individually to save space
|
||||
from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, Check, Button, B, Btn, ButtonMenu,BMenu, Canvas, Column, Col, Combo, DropDown, Drop, DD, Frame, Graph, Image, InputText, Input, In, I, Listbox, LBox, LB, Menu, Multiline, ML, MLine, OptionMenu, Output, Pane, ProgressBar, Prog, PBar, Radio, R, Rad, Sizer, Slider, Spin, StatusBar, Tab, TabGroup, Table, Text, Txt, T, Tree, TreeData, VerticalSeparator, Window, Print
|
||||
|
||||
|
||||
"""
|
||||
Demo - Compact Layouts and Element Renaming
|
||||
|
@ -10,7 +7,7 @@ from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, C
|
|||
programmers, there is little additional knowledge to be gained by writing
|
||||
sg.Text('My text')
|
||||
rather than using one of the shortcuts such as
|
||||
sg.T('My text')
|
||||
sg.Text('My text')
|
||||
However, even with shortcut usage, you continue to have the package prefix of
|
||||
sg.
|
||||
That's 3 characters per element that are added to your layout!
|
||||
|
@ -19,7 +16,7 @@ from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, C
|
|||
|
||||
If you don't want to use that very-long import or perhaps want to use your own shortcut names, you can easily
|
||||
create your shortcut by simple assignment:
|
||||
T = sg.Text
|
||||
T = sg.T
|
||||
This enables you to use T just as if you imported the Class T from PySimpleGUI. You could develop your own
|
||||
template that you copy and paste at the top of all of your PySimpleGUI programs. Or perhaps perform an import
|
||||
of those assignments from a .py file you create.
|
||||
|
@ -37,11 +34,14 @@ from PySimpleGUI import InputCombo, Combo, Multiline, ML, MLine, Checkbox, CB, C
|
|||
# A user created shortcut....
|
||||
# Suppose this user's layout contains many Multiline Elements. It could be advantageous to have a single letter
|
||||
# shortcut version for Multiline
|
||||
M = sg.Multiline
|
||||
M = sg.MLine
|
||||
B = sg.B
|
||||
|
||||
# This layout uses the user defined "M" element as well as the PySimpleGUI Button shortcut, B.
|
||||
layout = [[M(size=(30,3))],
|
||||
layout = [[M(size=(30, 3))],
|
||||
[B('OK')]]
|
||||
|
||||
event, values = Window('Shortcuts', layout).read()
|
||||
window = sg.Window('Shortcuts', layout).read()
|
||||
event, values = window.read()
|
||||
sg.popup_scrolled(event, values)
|
||||
window.close()
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# sg.SetOptions(button_color=sg.COLOR_SYSTEM_DEFAULT)
|
||||
'''
|
||||
Simple "diff" in PySimpleGUI
|
||||
'''
|
||||
|
||||
def GetFilesToCompare():
|
||||
form_rows = [[sg.Text('Enter 2 files to comare')],
|
||||
[sg.Text('File 1', size=(15, 1)), sg.InputText(key='file1'), sg.FileBrowse()],
|
||||
[sg.Text('File 2', size=(15, 1)), sg.InputText(key='file2'), sg.FileBrowse(target='file2')],
|
||||
[sg.Text('File 1', size=(15, 1)),
|
||||
sg.InputText(key='-file1-'), sg.FileBrowse()],
|
||||
[sg.Text('File 2', size=(15, 1)), sg.InputText(key='-file2-'),
|
||||
sg.FileBrowse(target='file2')],
|
||||
[sg.Submit(), sg.Cancel()]]
|
||||
|
||||
window = sg.Window('File Compare')
|
||||
event, values = window.Layout(form_rows).Read()
|
||||
window = sg.Window('File Compare', form_rows)
|
||||
event, values = window.read()
|
||||
window.close()
|
||||
return event, values
|
||||
|
||||
def main():
|
||||
button, values = GetFilesToCompare()
|
||||
f1 = values['file1']
|
||||
f2 = values['file2']
|
||||
|
||||
if any((button != 'Submit', f1 =='', f2 == '')):
|
||||
sg.PopupError('Operation cancelled')
|
||||
sys.exit(69)
|
||||
def main():
|
||||
|
||||
button, values = GetFilesToCompare()
|
||||
f1, f2 = values['-file1-'], values['-file2-']
|
||||
|
||||
if any((button != 'Submit', f1 == '', f2 == '')):
|
||||
sg.popup_error('Operation cancelled')
|
||||
return
|
||||
|
||||
# --- This portion of the code is not GUI related ---
|
||||
with open(f1, 'rb') as file1:
|
||||
|
@ -34,11 +36,12 @@ def main():
|
|||
|
||||
for i, x in enumerate(a):
|
||||
if x != b[i]:
|
||||
sg.Popup('Compare results for files', f1, f2, '**** Mismatch at offset {} ****'.format(i))
|
||||
sg.popup('Compare results for files', f1, f2,
|
||||
'**** Mismatch at offset {} ****'.format(i))
|
||||
break
|
||||
else:
|
||||
if len(a) == len(b):
|
||||
sg.Popup('**** The files are IDENTICAL ****')
|
||||
sg.popup('**** The files are IDENTICAL ****')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import numpy
|
||||
import PySimpleGUI as sg # Take your pick! Tkinter
|
||||
# import PySimpleGUIWeb as sg # Or the Web! (Remi!)
|
||||
import PySimpleGUI as sg
|
||||
|
||||
BOX_SIZE = 15
|
||||
|
||||
|
||||
class GameOfLife:
|
||||
|
||||
def __init__(self, N=20, T=200):
|
||||
|
@ -98,40 +98,56 @@ class GameOfLife:
|
|||
self.t += 1
|
||||
|
||||
def init_graphics(self):
|
||||
self.graph = sg.Graph((600, 600), (0, 0), (450, 450), key='_GRAPH_', change_submits=True, drag_submits=False, background_color='lightblue')
|
||||
self.graph = sg.Graph((600, 600), (0, 0), (450, 450),
|
||||
key='-GRAPH-',
|
||||
change_submits=True,
|
||||
drag_submits=False,
|
||||
background_color='lightblue')
|
||||
layout = [
|
||||
[sg.Text('Game of Life ', font='ANY 15'), sg.Text('', key='_OUTPUT_', size=(30,1), font='ANY 15')],
|
||||
[sg.Text('Game of Life', font='ANY 15'),
|
||||
sg.Text('', key='-OUTPUT-', size=(30, 1), font='ANY 15')],
|
||||
[self.graph],
|
||||
[sg.Button('Go!', key='_DONE_'),
|
||||
sg.Text(' Delay (ms)') , sg.Slider([0,800], orientation='h', key='_SLIDER_', enable_events=True, size=(15,15)), sg.T('', size=(3,1), key='_S1_OUT_'),
|
||||
sg.Text(' Num Generations'), sg.Slider([0, 20000],default_value=4000, orientation='h',size=(15,15),enable_events=True, key='_SLIDER2_'), sg.T('', size=(3,1), key='_S2_OUT_')]
|
||||
[sg.Button('Go!', key='-DONE-'),
|
||||
sg.Text(' Delay (ms)'),
|
||||
sg.Slider([0, 800],
|
||||
orientation='h',
|
||||
key='-SLIDER-',
|
||||
enable_events=True,
|
||||
size=(15, 15)),
|
||||
sg.Text('', size=(3, 1), key='-S1-OUT-'),
|
||||
sg.Text(' Num Generations'), sg.Slider([0, 20000],
|
||||
default_value=4000,
|
||||
orientation='h',
|
||||
size=(15, 15),
|
||||
enable_events=True,
|
||||
key='-SLIDER2-'),
|
||||
sg.Text('', size=(3, 1), key='-S2-OUT-')]
|
||||
]
|
||||
|
||||
self.window = sg.Window('Window Title', ).Layout(layout).Finalize()
|
||||
event, values = self.window.Read(timeout=0)
|
||||
self.delay = values['_SLIDER_']
|
||||
self.window.Element('_S1_OUT_').Update(values['_SLIDER_'])
|
||||
self.window.Element('_S2_OUT_').Update(values['_SLIDER2_'])
|
||||
|
||||
self.window = sg.Window('Window Title', layout, finalize=True)
|
||||
event, values = self.window.read(timeout=0)
|
||||
self.delay = values['-SLIDER-']
|
||||
self.window['-S1-OUT-'].update(values['-SLIDER-'])
|
||||
self.window['-S2-OUT-'].update(values['-SLIDER2-'])
|
||||
|
||||
def draw_board(self):
|
||||
BOX_SIZE = 15
|
||||
self.graph.Erase()
|
||||
self.graph.erase()
|
||||
for i in range(self.N):
|
||||
for j in range(self.N):
|
||||
if self.old_grid[i][j]:
|
||||
self.graph.DrawRectangle((i * BOX_SIZE, j * BOX_SIZE),
|
||||
(i * BOX_SIZE + BOX_SIZE, j * (BOX_SIZE) + BOX_SIZE),
|
||||
line_color='black', fill_color='yellow')
|
||||
event, values = self.window.Read(timeout=self.delay)
|
||||
if event in (None, '_DONE_'):
|
||||
exit()
|
||||
self.delay = values['_SLIDER_']
|
||||
self.T = int(values['_SLIDER2_'])
|
||||
self.window.Element('_S1_OUT_').Update(values['_SLIDER_'])
|
||||
self.window.Element('_S2_OUT_').Update(values['_SLIDER2_'])
|
||||
self.window.Element('_OUTPUT_').Update('Generation {}'.format(self.t))
|
||||
|
||||
self.graph.draw_rectangle((i * BOX_SIZE, j * BOX_SIZE),
|
||||
(i * BOX_SIZE + BOX_SIZE,
|
||||
j * (BOX_SIZE) + BOX_SIZE),
|
||||
line_color='black', fill_color='yellow')
|
||||
event, values = self.window.read(timeout=self.delay)
|
||||
if event in (None, '-DONE-'):
|
||||
return
|
||||
self.delay = values['-SLIDER-']
|
||||
self.T = int(values['-SLIDER2-'])
|
||||
self.window['-S1-OUT-'].update(values['-SLIDER-'])
|
||||
self.window['-S2-OUT-'].update(values['-SLIDER2-'])
|
||||
self.window['-OUTPUT-'].update('Generation {}'.format(self.t))
|
||||
|
||||
def manual_board_setup(self):
|
||||
ids = []
|
||||
|
@ -140,31 +156,33 @@ class GameOfLife:
|
|||
for j in range(self.N):
|
||||
ids[i].append(0)
|
||||
while True: # Event Loop
|
||||
event, values = self.window.Read()
|
||||
if event is None or event == '_DONE_':
|
||||
event, values = self.window.read()
|
||||
if event is None or event == '-DONE-':
|
||||
break
|
||||
self.window.Element('_S1_OUT_').Update(values['_SLIDER_'])
|
||||
self.window.Element('_S2_OUT_').Update(values['_SLIDER2_'])
|
||||
mouse = values['_GRAPH_']
|
||||
self.window['-S1-OUT-'].update(values['-SLIDER-'])
|
||||
self.window['-S2-OUT-'].update(values['-SLIDER2-'])
|
||||
mouse = values['-GRAPH-']
|
||||
|
||||
if event == '_GRAPH_':
|
||||
if event == '-GRAPH-':
|
||||
if mouse == (None, None):
|
||||
continue
|
||||
box_x = mouse[0] // BOX_SIZE
|
||||
box_y = mouse[1] // BOX_SIZE
|
||||
if self.old_grid[box_x][box_y] == 1:
|
||||
id = ids[box_x][box_y]
|
||||
self.graph.DeleteFigure(id)
|
||||
id_val = ids[box_x][box_y]
|
||||
self.graph.delete_figure(id_val)
|
||||
self.old_grid[box_x][box_y] = 0
|
||||
else:
|
||||
id = self.graph.DrawRectangle((box_x * BOX_SIZE, box_y * BOX_SIZE),
|
||||
(box_x * BOX_SIZE + BOX_SIZE, box_y * (BOX_SIZE) + BOX_SIZE),
|
||||
line_color='black', fill_color='yellow')
|
||||
ids[box_x][box_y] = id
|
||||
id_val = self.graph.draw_rectangle((box_x * BOX_SIZE, box_y * BOX_SIZE),
|
||||
(box_x * BOX_SIZE + BOX_SIZE,
|
||||
box_y * (BOX_SIZE) + BOX_SIZE),
|
||||
line_color='black', fill_color='yellow')
|
||||
ids[box_x][box_y] = id_val
|
||||
self.old_grid[box_x][box_y] = 1
|
||||
self.window.Element('_DONE_').Update(text='Exit')
|
||||
self.window['-DONE-'].update(text='Exit')
|
||||
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
game = GameOfLife(N=35, T=200)
|
||||
game.play()
|
||||
game.window.Close()
|
||||
game.window.close()
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
# import PySimpleGUIWeb as sg # take your pick of ports. Runs on both
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import random
|
||||
import string
|
||||
|
||||
|
@ -17,38 +12,41 @@ import string
|
|||
BOX_SIZE = 25
|
||||
|
||||
layout = [
|
||||
[sg.Text('Crossword Puzzle Using PySimpleGUI'), sg.Text('', key='_OUTPUT_')],
|
||||
[sg.Graph((800,800), (0,450), (450,0), key='_GRAPH_', change_submits=True, drag_submits=False)],
|
||||
[sg.Button('Show'), sg.Button('Exit')]
|
||||
]
|
||||
[sg.Text('Crossword Puzzle Using PySimpleGUI'), sg.Text('', key='-OUTPUT-')],
|
||||
[sg.Graph((800, 800), (0, 450), (450, 0), key='-GRAPH-',
|
||||
change_submits=True, drag_submits=False)],
|
||||
[sg.Button('Show'), sg.Button('Exit')]
|
||||
]
|
||||
|
||||
window = sg.Window('Window Title', ).Layout(layout).Finalize()
|
||||
window = sg.Window('Window Title', layout, finalize=True)
|
||||
|
||||
g = window.FindElement('_GRAPH_')
|
||||
g = window['-GRAPH-']
|
||||
|
||||
for row in range(16):
|
||||
for col in range(16):
|
||||
if random.randint(0,100) > 10:
|
||||
g.DrawRectangle((col * BOX_SIZE + 5, row * BOX_SIZE + 3), (col * BOX_SIZE + BOX_SIZE + 5, row * BOX_SIZE + BOX_SIZE + 3), line_color='black')
|
||||
if random.randint(0, 100) > 10:
|
||||
g.draw_rectangle((col * BOX_SIZE + 5, row * BOX_SIZE + 3), (col * BOX_SIZE + BOX_SIZE + 5, row * BOX_SIZE + BOX_SIZE + 3), line_color='black')
|
||||
else:
|
||||
g.DrawRectangle((col * BOX_SIZE + 5, row * BOX_SIZE + 3), (col * BOX_SIZE + BOX_SIZE + 5, row * BOX_SIZE + BOX_SIZE + 3), line_color='black', fill_color='black')
|
||||
g.draw_rectangle((col * BOX_SIZE + 5, row * BOX_SIZE + 3), (col * BOX_SIZE + BOX_SIZE + 5, row * BOX_SIZE + BOX_SIZE + 3), line_color='black', fill_color='black')
|
||||
|
||||
g.DrawText('{}'.format(row * 6 + col + 1), (col * BOX_SIZE + 10, row * BOX_SIZE + 8))
|
||||
g.draw_text('{}'.format(row * 6 + col + 1),
|
||||
(col * BOX_SIZE + 10, row * BOX_SIZE + 8))
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
print(event, values)
|
||||
if event is None or event == 'Exit':
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
mouse = values['_GRAPH_']
|
||||
mouse = values['-GRAPH-']
|
||||
|
||||
if event == '_GRAPH_':
|
||||
if event == '-GRAPH-':
|
||||
if mouse == (None, None):
|
||||
continue
|
||||
box_x = mouse[0]//BOX_SIZE
|
||||
box_y = mouse[1]//BOX_SIZE
|
||||
letter_location = (box_x * BOX_SIZE + 18, box_y * BOX_SIZE + 17)
|
||||
print(box_x, box_y)
|
||||
g.DrawText('{}'.format(random.choice(string.ascii_uppercase)), letter_location, font='Courier 25')
|
||||
g.draw_text('{}'.format(random.choice(string.ascii_uppercase)),
|
||||
letter_location, font='Courier 25')
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -32,31 +32,30 @@ pixmaps and page re-visits will re-use a once-created display list.
|
|||
import sys
|
||||
import fitz
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
import tkinter as tk
|
||||
from PIL import Image, ImageTk
|
||||
import time
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
fname = sg.PopupGetFile('Document Browser', 'Document file to open', no_window=True,
|
||||
file_types = (
|
||||
("PDF Files", "*.pdf"),
|
||||
("XPS Files", "*.*xps"),
|
||||
("Epub Files", "*.epub"),
|
||||
("Fiction Books", "*.fb2"),
|
||||
("Comic Books", "*.cbz"),
|
||||
("HTML", "*.htm*")
|
||||
# add more document types here
|
||||
)
|
||||
)
|
||||
fname = sg.popup_get_file('Document Browser', 'Document file to open',
|
||||
no_window=True,
|
||||
file_types=(
|
||||
("PDF Files", "*.pdf"),
|
||||
("XPS Files", "*.*xps"),
|
||||
("Epub Files", "*.epub"),
|
||||
("Fiction Books", "*.fb2"),
|
||||
("Comic Books", "*.cbz"),
|
||||
("HTML", "*.htm*")
|
||||
# add more document types here
|
||||
)
|
||||
)
|
||||
else:
|
||||
fname = sys.argv[1]
|
||||
|
||||
if not fname:
|
||||
sg.Popup("Cancelling:", "No filename supplied")
|
||||
sg.popup("Cancelling:", "No filename supplied")
|
||||
raise SystemExit("Cancelled: no filename supplied")
|
||||
|
||||
doc = fitz.open(fname)
|
||||
|
@ -64,15 +63,16 @@ page_count = len(doc)
|
|||
|
||||
# used for response time statistics only
|
||||
fitz_img_time = 0.0
|
||||
tk_img_time = 0.0
|
||||
img_count = 1
|
||||
tk_img_time = 0.0
|
||||
img_count = 1
|
||||
|
||||
# allocate storage for page display lists
|
||||
dlist_tab = [None] * page_count
|
||||
|
||||
title = "PyMuPDF display of '%s', pages: %i" % (fname, page_count)
|
||||
|
||||
def get_page(pno, zoom = False, max_size = None, first = False):
|
||||
|
||||
def get_page(pno, zoom=False, max_size=None, first=False):
|
||||
"""Return a PNG image for a document page number.
|
||||
"""
|
||||
dlist = dlist_tab[pno] # get display list of page number
|
||||
|
@ -91,7 +91,7 @@ def get_page(pno, zoom = False, max_size = None, first = False):
|
|||
mat_0 = fitz.Matrix(zoom_0, zoom_0)
|
||||
|
||||
if not zoom: # show total page
|
||||
pix = dlist.getPixmap(matrix = mat_0, alpha=False)
|
||||
pix = dlist.getPixmap(matrix=mat_0, alpha=False)
|
||||
else:
|
||||
mp = r.tl + (r.br - r.tl) * 0.5 # page rect center
|
||||
w2 = r.width / 2
|
||||
|
@ -125,22 +125,15 @@ max_size = (max_width, max_height)
|
|||
root.destroy()
|
||||
del root
|
||||
|
||||
window = sg.Window(title, return_keyboard_events = True,
|
||||
location = (0,0), use_default_focus = False, no_titlebar=False)
|
||||
|
||||
cur_page = 0
|
||||
data, clip_pos = get_page(cur_page,
|
||||
zoom = False,
|
||||
max_size = max_size,
|
||||
first = True)
|
||||
data, clip_pos = get_page(cur_page, zoom=False, max_size=max_size, first=True)
|
||||
|
||||
image_elem = sg.Image(data = data)
|
||||
image_elem = sg.Image(data=data)
|
||||
|
||||
goto = sg.InputText(str(cur_page + 1), size=(5, 1), do_not_clear=True,
|
||||
key = "PageNumber")
|
||||
goto = sg.InputText(str(cur_page + 1), size=(5, 1), key="-PageNumber-")
|
||||
|
||||
layout = [
|
||||
[
|
||||
layout = [[
|
||||
sg.ReadButton('Next'),
|
||||
sg.ReadButton('Prev'),
|
||||
sg.Text('Page:'),
|
||||
|
@ -152,17 +145,18 @@ layout = [
|
|||
[image_elem],
|
||||
]
|
||||
|
||||
window.Layout(layout)
|
||||
window = sg.Window(title, layout, return_keyboard_events=True,
|
||||
location=(0, 0), use_default_focus=False, no_titlebar=False)
|
||||
|
||||
# now define the buttons / events we want to handle
|
||||
enter_buttons = [chr(13), "Return:13"]
|
||||
quit_buttons = ["Escape:27", chr(27)]
|
||||
next_buttons = ["Next", "Next:34", "MouseWheel:Down"]
|
||||
prev_buttons = ["Prev", "Prior:33", "MouseWheel:Up"]
|
||||
Up = "Up:38"
|
||||
Left = "Left:37"
|
||||
Up = "Up:38"
|
||||
Left = "Left:37"
|
||||
Right = "Right:39"
|
||||
Down = "Down:40"
|
||||
Down = "Down:40"
|
||||
zoom_buttons = ["Zoom", Up, Down, Left, Right]
|
||||
|
||||
# all the buttons we will handle
|
||||
|
@ -173,8 +167,8 @@ old_page = 0
|
|||
old_zoom = False
|
||||
|
||||
while True:
|
||||
event, value = window.Read()
|
||||
if event is None and (value is None or value['PageNumber'] is None):
|
||||
event, value = window.read()
|
||||
if event is None and (value is None or value['-PageNumber-'] is None):
|
||||
break
|
||||
if event in quit_buttons:
|
||||
break
|
||||
|
@ -184,7 +178,7 @@ while True:
|
|||
|
||||
if event in enter_buttons:
|
||||
try:
|
||||
cur_page = int(value['PageNumber']) - 1 # check if valid
|
||||
cur_page = int(value['-PageNumber-']) - 1 # check if valid
|
||||
while cur_page < 0:
|
||||
cur_page += page_count
|
||||
except:
|
||||
|
@ -216,21 +210,22 @@ while True:
|
|||
zoom = zoom_pressed = old_zoom = False
|
||||
|
||||
t0 = time.perf_counter()
|
||||
data, clip_pos = get_page(cur_page, zoom = zoom, max_size = max_size,
|
||||
first = False)
|
||||
data, clip_pos = get_page(cur_page, zoom=zoom, max_size=max_size,
|
||||
first=False)
|
||||
t1 = time.perf_counter()
|
||||
image_elem.Update(data = data)
|
||||
image_elem.update(data=data)
|
||||
t2 = time.perf_counter()
|
||||
fitz_img_time += t1 - t0
|
||||
tk_img_time += t2 - t1
|
||||
img_count += 1
|
||||
tk_img_time += t2 - t1
|
||||
img_count += 1
|
||||
old_page = cur_page
|
||||
old_zoom = zoom_pressed or zoom
|
||||
|
||||
# update page number field
|
||||
if event in my_keys:
|
||||
goto.Update(str(cur_page + 1))
|
||||
goto.update(str(cur_page + 1))
|
||||
|
||||
window.close()
|
||||
|
||||
# print some response time statistics
|
||||
if img_count > 0:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import PySimpleGUI as sg
|
||||
# import imwatchingyou # Not needed because using the one inside PySimpleGUI.py code itself
|
||||
|
||||
"""
|
||||
Demo program that shows you how to integrate the PySimpleGUI Debugger
|
||||
|
@ -20,36 +19,38 @@ import PySimpleGUI as sg
|
|||
"""
|
||||
|
||||
layout = [
|
||||
[sg.T('A typical PSG application')],
|
||||
[sg.In(key='_IN_')],
|
||||
[sg.T(' ', key='_OUT_', size=(45,1))],
|
||||
[sg.CBox('Checkbox 1'), sg.CBox('Checkbox 2')],
|
||||
[sg.Radio('a',1, key='_R1_'), sg.Radio('b',1, key='_R2_'), sg.Radio('c',1, key='_R3_')],
|
||||
[sg.Combo(['c1', 'c2', 'c3'], size=(6,3), key='_COMBO_')],
|
||||
[sg.Output(size=(50,6))],
|
||||
[sg.Ok(), sg.Exit(), sg.Button('Enable'), sg.Button('Popout'), sg.Button('Debugger'), sg.Debug(key='Debug')],
|
||||
]
|
||||
[sg.Text('A typical PSG application')],
|
||||
[sg.Input(key='-IN-')],
|
||||
[sg.Text(' ', key='-OUT-', size=(45, 1))],
|
||||
[sg.CBox('Checkbox 1'), sg.CBox('Checkbox 2')],
|
||||
[sg.Radio('a', 1, key='-R1-'), sg.Radio('b', 1, key='-R2-'),
|
||||
sg.Radio('c', 1, key='-R3-')],
|
||||
[sg.Combo(['c1', 'c2', 'c3'], size=(6, 3), key='-COMBO-')],
|
||||
[sg.Output(size=(50, 6))],
|
||||
[sg.Ok(), sg.Exit(), sg.Button('Enable'), sg.Button('Popout'),
|
||||
sg.Button('Debugger'), sg.Debug(key='Debug')],
|
||||
]
|
||||
|
||||
window = sg.Window('This is your Application Window', layout, debugger_enabled=False)
|
||||
window = sg.Window('This is your Application Window',
|
||||
layout, debugger_enabled=False)
|
||||
|
||||
counter = 0
|
||||
timeout = 100
|
||||
|
||||
# Note that you can launch the debugger windows right away, without waiting for user input
|
||||
sg.show_debugger_popout_window()
|
||||
|
||||
while True: # Your Event Loop
|
||||
event, values = window.Read(timeout=timeout)
|
||||
event, values = window.read(timeout=100)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
elif event == 'Enable':
|
||||
window.EnableDebugger()
|
||||
window.enable_debugger()
|
||||
elif event == 'Popout':
|
||||
sg.show_debugger_popout_window() # replaces old popout with a new one, possibly with new variables`
|
||||
# replaces old popout with a new one, possibly with new variables`
|
||||
sg.show_debugger_popout_window()
|
||||
elif event == 'Debugger':
|
||||
sg.show_debugger_window()
|
||||
counter += 1
|
||||
# to prove window is operating, show the input in another area in the window.
|
||||
window.Element('_OUT_').Update(values['_IN_'])
|
||||
window['-OUT-'].update(values['-IN-'])
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -20,29 +20,29 @@ import PySimpleGUI as sg
|
|||
"""
|
||||
|
||||
layout = [
|
||||
[sg.T('A typical PSG application')],
|
||||
[sg.In(key='_IN_')],
|
||||
[sg.T(' ', key='_OUT_', size=(45,1))],
|
||||
[sg.CBox('Checkbox 1'), sg.CBox('Checkbox 2')],
|
||||
[sg.Radio('a',1, key='_R1_'), sg.Radio('b',1, key='_R2_'), sg.Radio('c',1, key='_R3_')],
|
||||
[sg.Combo(['c1', 'c2', 'c3'], size=(6,3), key='_COMBO_')],
|
||||
[sg.Output(size=(50,6))],
|
||||
[sg.Ok(), sg.Exit(), sg.Button('Enable'), sg.Debug(key='Debug')],
|
||||
]
|
||||
|
||||
window = sg.Window('This is your Application Window', layout, debugger_enabled=False)
|
||||
[sg.Text('A typical PSG application')],
|
||||
[sg.Input(key='-IN-')],
|
||||
[sg.Text(' ', key='-OUT-', size=(45, 1))],
|
||||
[sg.CBox('Checkbox 1'), sg.CBox('Checkbox 2')],
|
||||
[sg.Radio('a', 1, key='-R1-'), sg.Radio('b', 1, key='-R2-'),
|
||||
sg.Radio('c', 1, key='-R3-')],
|
||||
[sg.Combo(['c1', 'c2', 'c3'], size=(6, 3), key='-COMBO-')],
|
||||
[sg.Output(size=(50, 6))],
|
||||
[sg.Ok(), sg.Exit(), sg.Button('Enable'), sg.Debug(key='Debug')],
|
||||
]
|
||||
|
||||
window = sg.Window('This is your Application Window',
|
||||
layout, debugger_enabled=False)
|
||||
counter = 0
|
||||
timeout = 100
|
||||
|
||||
while True: # Your Event Loop
|
||||
event, values = window.Read(timeout=timeout)
|
||||
event, values = window.read(timeout=100)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
elif event == 'Enable':
|
||||
window.EnableDebugger()
|
||||
window.enable_debugger()
|
||||
counter += 1
|
||||
# to prove window is operating, show the input in another area in the window.
|
||||
window.Element('_OUT_').Update(values['_IN_'])
|
||||
window['-OUT-'].update(values['-IN-'])
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -20,11 +20,15 @@ import imwatchingyou # STEP 1
|
|||
"""
|
||||
|
||||
layout = [
|
||||
[sg.T('A typical PSG application')],
|
||||
[sg.In(key='_IN_')],
|
||||
[sg.T(' ', key='_OUT_', size=(30, 1))],
|
||||
[sg.Radio('a', 1, key='_R1_'), sg.Radio('b', 1, key='_R2_'), sg.Radio('c', 1, key='_R3_')],
|
||||
[sg.Combo(['c1', 'c2', 'c3'], size=(6, 3), key='_COMBO_')],
|
||||
[sg.Text('A typical PSG application')],
|
||||
[sg.Input(key='-IN-')],
|
||||
[sg.Text(' ', key='-OUT-', size=(30, 1))],
|
||||
[
|
||||
sg.Rad('a', 1, key='-R1-'),
|
||||
sg.Rad('b', 1, key='-R2-'),
|
||||
sg.Rad('c', 1, key='-R3-')
|
||||
],
|
||||
[sg.Combo(['c1', 'c2', 'c3'], size=(6, 3), key='-COMBO-')],
|
||||
[sg.Output(size=(50, 6))],
|
||||
[sg.Ok(), sg.Exit(), sg.Button('Debug'), sg.Button('Popout')],
|
||||
]
|
||||
|
@ -32,10 +36,9 @@ layout = [
|
|||
window = sg.Window('This is your Application Window', layout)
|
||||
|
||||
counter = 0
|
||||
timeout = 100
|
||||
|
||||
while True: # Your Event Loop
|
||||
event, values = window.Read(timeout=timeout)
|
||||
event, values = window.read(timeout=100)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
elif event == 'Ok':
|
||||
|
@ -46,9 +49,9 @@ while True: # Your Event Loop
|
|||
imwatchingyou.show_debugger_popout_window() # STEP 2
|
||||
counter += 1
|
||||
# to prove window is operating, show the input in another area in the window.
|
||||
window.Element('_OUT_').Update(values['_IN_'])
|
||||
window['-OUT-'].update(values['-IN-'])
|
||||
|
||||
# don't worry about the "state" of things, just call this function "frequently"
|
||||
imwatchingyou.refresh_debugger() # STEP 3 - refresh debugger
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
"""
|
||||
Demo - Running 2 windows with both being active at the same time
|
||||
Three important things to note about this design patter:
|
||||
|
@ -15,45 +10,44 @@ else:
|
|||
|
||||
# Window 1 layout
|
||||
layout = [
|
||||
[sg.Text('This is the FIRST WINDOW'), sg.Text(' ', key='_OUTPUT_')],
|
||||
[sg.Text('This is the FIRST WINDOW'), sg.Text(' ', key='-OUTPUT-')],
|
||||
[sg.Text('')],
|
||||
[sg.Button('Launch 2nd Window'),sg.Button('Popup'), sg.Button('Exit')]
|
||||
[sg.Button('Launch 2nd Window'), sg.Button('Popup'), sg.Button('Exit')]
|
||||
]
|
||||
|
||||
window = sg.Window('Window Title', location=(800,600)).Layout(layout)
|
||||
window = sg.Window('Window Title', layout, location=(800,600))
|
||||
win2_active = False
|
||||
i=0
|
||||
while True: # Event Loop
|
||||
event, values = window.Read(timeout=100)
|
||||
event, values = window.read(timeout=100)
|
||||
if event != sg.TIMEOUT_KEY:
|
||||
print(i, event, values)
|
||||
|
||||
if event is None or event == 'Exit':
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
elif event == 'Popup':
|
||||
sg.Popup('This is a BLOCKING popup','all windows remain inactive while popup active')
|
||||
sg.popup('This is a BLOCKING popup','all windows remain inactive while popup active')
|
||||
i+=1
|
||||
if event == 'Launch 2nd Window' and not win2_active: # only run if not already showing a window2
|
||||
win2_active = True
|
||||
# window 2 layout - note - must be "new" every time a window is created
|
||||
layout2 = [
|
||||
[sg.Text('The second window'), sg.Text('', key='_OUTPUT_')],
|
||||
[sg.Input(do_not_clear=True, key='_IN_')],
|
||||
[sg.Text('The second window'), sg.Text('', key='-OUTPUT-')],
|
||||
[sg.Input('', key='-IN-')],
|
||||
[sg.Button('Show'), sg.Button('Exit')]
|
||||
]
|
||||
window2 = sg.Window('Second Window').Layout(layout2)
|
||||
window2 = sg.Window('Second Window', layout2)
|
||||
# Read window 2's events. Must use timeout of 0
|
||||
if win2_active:
|
||||
# print("reading 2")
|
||||
event, values = window2.Read(timeout=100)
|
||||
event, values = window2.read(timeout=100)
|
||||
# print("win2 ", event)
|
||||
if event != sg.TIMEOUT_KEY:
|
||||
print("win2 ", event)
|
||||
if event == 'Exit' or event is None:
|
||||
# print("Closing window 2", event)
|
||||
win2_active = False
|
||||
window2.Close()
|
||||
window2.close()
|
||||
if event == 'Show':
|
||||
sg.Popup('You entered ', values['_IN_'])
|
||||
sg.popup('You entered ', values['-IN-'])
|
||||
|
||||
window.Close()
|
||||
window.close()
|
|
@ -1,35 +1,39 @@
|
|||
import PySimpleGUI as sg
|
||||
"""
|
||||
PySimpleGUI The Complete Course
|
||||
Lesson 7 - Multiple Windows
|
||||
1-lvl nested window
|
||||
"""
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# Design pattern 1 - First window does not remain active
|
||||
|
||||
layout = [[ sg.Text('Window 1'),],
|
||||
[sg.Input(do_not_clear=True)],
|
||||
[sg.Text('', size=(20,1), key='_OUTPUT_')],
|
||||
[sg.Input()],
|
||||
[sg.Text('', size=(20,1), key='-OUTPUT-')],
|
||||
[sg.Button('Launch 2')]]
|
||||
|
||||
win1 = sg.Window('Window 1').Layout(layout)
|
||||
win2_active=False
|
||||
while True:
|
||||
ev1, vals1 = win1.Read(timeout=100)
|
||||
if ev1 is None:
|
||||
break
|
||||
win1.FindElement('_OUTPUT_').Update(vals1[0])
|
||||
window1 = sg.Window('Window 1', layout)
|
||||
window2_active=False
|
||||
|
||||
if ev1 == 'Launch 2' and not win2_active:
|
||||
win2_active = True
|
||||
win1.Hide()
|
||||
while True:
|
||||
event1, values1 = window1.read(timeout=100)
|
||||
if event1 is None:
|
||||
break
|
||||
window1['-OUTPUT-'].update(values1[0])
|
||||
|
||||
if event1 == 'Launch 2' and not window2_active:
|
||||
window2_active = True
|
||||
window1.hide()
|
||||
layout2 = [[sg.Text('Window 2')],
|
||||
[sg.Button('Exit')]]
|
||||
|
||||
win2 = sg.Window('Window 2').Layout(layout2)
|
||||
window2 = sg.Window('Window 2', layout2)
|
||||
while True:
|
||||
ev2, vals2 = win2.Read()
|
||||
ev2, vals2 = window2.read()
|
||||
if ev2 is None or ev2 == 'Exit':
|
||||
win2.Close()
|
||||
win2_active = False
|
||||
win1.UnHide()
|
||||
window2.close()
|
||||
window2_active = False
|
||||
window1.un_hide()
|
||||
break
|
||||
window1.close()
|
||||
|
||||
|
|
|
@ -1,34 +1,37 @@
|
|||
"""
|
||||
PySimpleGUI The Complete Course
|
||||
Lesson 7 - Multiple Windows
|
||||
"""
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
PySimpleGUI The Complete Course
|
||||
Lesson 7
|
||||
Multiple Independent Windows
|
||||
"""
|
||||
# Design pattern 2 - First window remains active
|
||||
|
||||
layout = [[ sg.Text('Window 1'),],
|
||||
[sg.Input(do_not_clear=True)],
|
||||
[sg.Text('', size=(20,1), key='_OUTPUT_')],
|
||||
[sg.Input('')],
|
||||
[sg.Text('', size=(20,1), key='-OUTPUT-')],
|
||||
[sg.Button('Launch 2'), sg.Button('Exit')]]
|
||||
|
||||
win1 = sg.Window('Window 1').Layout(layout)
|
||||
window1 = sg.Window('Window 1', layout)
|
||||
|
||||
win2_active = False
|
||||
window2_active = False
|
||||
while True:
|
||||
ev1, vals1 = win1.Read(timeout=100)
|
||||
win1.FindElement('_OUTPUT_').Update(vals1[0])
|
||||
if ev1 is None or ev1 == 'Exit':
|
||||
event1, values1 = window1.read(timeout=100)
|
||||
window1['-OUTPUT-'].update(values1[0])
|
||||
if event1 is None or event1 == 'Exit':
|
||||
break
|
||||
|
||||
if not win2_active and ev1 == 'Launch 2':
|
||||
win2_active = True
|
||||
if not window2_active and event1 == 'Launch 2':
|
||||
window2_active = True
|
||||
layout2 = [[sg.Text('Window 2')],
|
||||
[sg.Button('Exit')]]
|
||||
|
||||
win2 = sg.Window('Window 2').Layout(layout2)
|
||||
window2 = sg.Window('Window 2', layout2)
|
||||
|
||||
if win2_active:
|
||||
ev2, vals2 = win2.Read(timeout=100)
|
||||
if window2_active:
|
||||
ev2, vals2 = window2.read(timeout=100)
|
||||
if ev2 is None or ev2 == 'Exit':
|
||||
win2_active = False
|
||||
win2.Close()
|
||||
window2_active = False
|
||||
window2.close()
|
||||
|
||||
window1.close()
|
||||
|
|
|
@ -1,48 +1,54 @@
|
|||
import PySimpleGUI as sg
|
||||
|
||||
'''
|
||||
Example of wizard-like PySimpleGUI windows
|
||||
'''
|
||||
|
||||
layout = [[sg.Text('Window 1'), ],
|
||||
[sg.Input(do_not_clear=True)],
|
||||
[sg.Text('',size=(20,1), key='_OUTPUT_')],
|
||||
[sg.Input('')],
|
||||
[sg.Text('',size=(20,1), key='-OUTPUT-')],
|
||||
[sg.Button('Next >'), sg.Button('Exit')]]
|
||||
|
||||
win1 = sg.Window('Window 1').Layout(layout)
|
||||
window = sg.Window('Window 1', layout)
|
||||
|
||||
win3_active = win2_active = False
|
||||
window3_active = window2_active = False
|
||||
while True:
|
||||
if not win2_active:
|
||||
ev1, vals1 = win1.Read()
|
||||
if ev1 is None or ev1 == 'Exit':
|
||||
if not window2_active:
|
||||
event1, values1 = window.read()
|
||||
if event1 is None or event1 == 'Exit':
|
||||
break
|
||||
win1.FindElement('_OUTPUT_').Update(vals1[0])
|
||||
window['-OUTPUT-'].update(values1[0])
|
||||
|
||||
if not win2_active and ev1 == 'Next >':
|
||||
win2_active = True
|
||||
win1.Hide()
|
||||
if not window2_active and event1 == 'Next >':
|
||||
window2_active = True
|
||||
window.hide()
|
||||
layout2 = [[sg.Text('Window 2')],
|
||||
[sg.Button('< Prev'), sg.Button('Next >')]]
|
||||
|
||||
win2 = sg.Window('Window 2').Layout(layout2)
|
||||
window2 = sg.Window('Window 2', layout2)
|
||||
|
||||
if win2_active:
|
||||
ev2, vals2 = win2.Read()
|
||||
if ev2 in (None, 'Exit', '< Prev'):
|
||||
win2_active = False
|
||||
win2.Close()
|
||||
win1.UnHide()
|
||||
elif ev2 == 'Next >':
|
||||
win3_active = True
|
||||
win2_active = False
|
||||
win2.Hide()
|
||||
if window2_active:
|
||||
event2 = window2.read()[0]
|
||||
if event2 in (None, 'Exit', '< Prev'):
|
||||
window2_active = False
|
||||
window2.close()
|
||||
window.un_hide()
|
||||
elif event2 == 'Next >':
|
||||
window3_active = True
|
||||
window2_active = False
|
||||
window2.hide()
|
||||
layout3 = [[sg.Text('Window 3')],
|
||||
[sg.Button('< Prev'), sg.Button('Exit')]]
|
||||
win3 = sg.Window('Window 3').Layout(layout3)
|
||||
window3 = sg.Window('Window 3', layout3)
|
||||
|
||||
if win3_active:
|
||||
ev3, vals3 = win3.Read()
|
||||
if window3_active:
|
||||
ev3, vals3 = window3.read()
|
||||
if ev3 == '< Prev':
|
||||
win3.Close()
|
||||
win3_active = False
|
||||
win2_active = True
|
||||
win2.UnHide()
|
||||
window3.close()
|
||||
window3_active = False
|
||||
window2_active = True
|
||||
window2.un_hide()
|
||||
elif ev3 in (None, 'Exit'):
|
||||
break
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,24 +1,21 @@
|
|||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [
|
||||
[sg.Text('Your typed chars appear here:'), sg.Text('', size=(20,1), key='-OUTPUT-')],
|
||||
[sg.Input(do_not_clear=True, key='-IN-')],
|
||||
[sg.Button('Show'), sg.Button('Exit')]
|
||||
]
|
||||
layout = [
|
||||
[sg.Text('Your typed chars appear here:'),
|
||||
sg.Text(size=(20, 1), key='-OUTPUT-')],
|
||||
[sg.Input('', key='-IN-')],
|
||||
[sg.Button('Show'), sg.Button('Exit')]
|
||||
]
|
||||
|
||||
window = sg.Window('Window Title').Layout(layout)
|
||||
window = sg.Window('Window Title', layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
while True:
|
||||
event, values = window.read()
|
||||
print(event, values)
|
||||
if event is None or event == 'Exit':
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
if event == 'Show':
|
||||
# change the "output" element to be the value of "input" element
|
||||
window.FindElement('-OUTPUT-').Update(values['-IN-'])
|
||||
# change the "output" element to be the value of "input" element
|
||||
window['-OUTPUT-'].update(values['-IN-'])
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import PySimpleGUI as sg
|
||||
"""
|
||||
When creating a new PySimpleGUI program from scratch, start here.
|
||||
These are the accepted design patterns that cover the two primary use cases
|
||||
|
||||
1. A "One Shot" window
|
||||
2. A persistent window that stays open after button clicks (uses an event loop)
|
||||
3. A persistent window that need to perform Update of an element before the window.read
|
||||
3. A persistent window that need to perform update of an element before the window.read
|
||||
"""
|
||||
# ---------------------------------#
|
||||
# DESIGN PATTERN 1 - Simple Window #
|
||||
# ---------------------------------#
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[ sg.Text('My Oneshot') ],
|
||||
[ sg.Button('OK') ]]
|
||||
|
@ -22,7 +22,6 @@ window.close()
|
|||
# -------------------------------------#
|
||||
# DESIGN PATTERN 2 - Persistent Window #
|
||||
# -------------------------------------#
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[ sg.Text('My layout') ],
|
||||
[ sg.Button('OK'), sg.Button('Cancel') ]]
|
||||
|
@ -38,14 +37,13 @@ window.close()
|
|||
# ------------------------------------------------------------------#
|
||||
# DESIGN PATTERN 3 - Persistent Window with "early update" required #
|
||||
# ------------------------------------------------------------------#
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[ sg.Text('My layout', key='-TEXT-KEY-') ],
|
||||
[ sg.Button('OK'), sg.Button('Cancel') ]]
|
||||
|
||||
window = sg.Window('Design Pattern 3', layout, finalize=True)
|
||||
|
||||
window['-TEXT-KEY-'].Update('NEW Text') # Change the text field. Finalize allows us to do this
|
||||
window['-TEXT-KEY-'].update('NEW Text') # Change the text field. Finalize allows us to do this
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.read()
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
|
@ -20,34 +16,36 @@ import os
|
|||
|
||||
ROOT_PATH = './'
|
||||
|
||||
|
||||
def Launcher():
|
||||
|
||||
# def print(line):
|
||||
# window.FindElement('output').Update(line)
|
||||
sg.change_look_and_feel('Dark')
|
||||
|
||||
sg.ChangeLookAndFeel('Dark')
|
||||
|
||||
namesonly = [f for f in os.listdir(ROOT_PATH) if f.endswith('.py') ]
|
||||
namesonly = [f for f in os.listdir(ROOT_PATH) if f.endswith('.py')]
|
||||
|
||||
if len(namesonly) == 0:
|
||||
namesonly = ['test 1', 'test 2', 'test 3']
|
||||
|
||||
sg.SetOptions(element_padding=(0,0), button_element_size=(12,1), auto_size_buttons=False)
|
||||
sg.set_options(element_padding=(0, 0),
|
||||
button_element_size=(12, 1), auto_size_buttons=False)
|
||||
|
||||
layout = [[sg.Combo(values=namesonly, size=(35,30), key='demofile'),
|
||||
sg.Button('Run', button_color=('white', '#00168B')),
|
||||
sg.Button('Program 1'),
|
||||
sg.Button('Program 2'),
|
||||
sg.Button('Program 3', button_color=('white', '#35008B')),
|
||||
sg.Button('EXIT', button_color=('white','firebrick3'))],
|
||||
[sg.T('', text_color='white', size=(50,1), key='output')]]
|
||||
|
||||
window = sg.Window('Floating Toolbar', no_titlebar=True, grab_anywhere=True, keep_on_top=True).Layout(layout)
|
||||
layout = [[sg.Combo(values=namesonly, size=(35, 30), key='demofile'),
|
||||
sg.Button('Run', button_color=('white', '#00168B')),
|
||||
sg.Button('Program 1'),
|
||||
sg.Button('Program 2'),
|
||||
sg.Button('Program 3', button_color=('white', '#35008B')),
|
||||
sg.Button('EXIT', button_color=('white', 'firebrick3'))],
|
||||
[sg.Text('', text_color='white', size=(50, 1), key='output')]]
|
||||
|
||||
window = sg.Window('Floating Toolbar',
|
||||
layout,
|
||||
no_titlebar=True,
|
||||
grab_anywhere=True,
|
||||
keep_on_top=True)
|
||||
|
||||
# ---===--- Loop taking in user input and executing appropriate program --- #
|
||||
while True:
|
||||
(event, values) = window.Read()
|
||||
event, values = window.read()
|
||||
if event == 'EXIT' or event is None:
|
||||
break # exit button clicked
|
||||
if event == 'Program 1':
|
||||
|
@ -56,11 +54,14 @@ def Launcher():
|
|||
print('Run your program 2 here!')
|
||||
elif event == 'Run':
|
||||
file = values['demofile']
|
||||
print('Launching %s'%file)
|
||||
print('Launching %s' % file)
|
||||
ExecuteCommandSubprocess('python', os.path.join(ROOT_PATH, file))
|
||||
else:
|
||||
print(event)
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
def ExecuteCommandSubprocess(command, *args, wait=False):
|
||||
try:
|
||||
if sys.platform == 'linux':
|
||||
|
@ -69,10 +70,16 @@ def ExecuteCommandSubprocess(command, *args, wait=False):
|
|||
# for arg in args:
|
||||
# arg_string += ' ' + str(arg)
|
||||
print('python3 ' + arg_string)
|
||||
sp = subprocess.Popen(['python3 ', arg_string ], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
sp = subprocess.Popen(['python3 ', arg_string],
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
else:
|
||||
arg_string = ' '.join([str(arg) for arg in args])
|
||||
sp = subprocess.Popen([command, arg_string], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
sp = subprocess.Popen([command, arg_string],
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
# sp = subprocess.Popen([command, list(args)], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
if wait:
|
||||
|
@ -81,10 +88,9 @@ def ExecuteCommandSubprocess(command, *args, wait=False):
|
|||
print(out.decode("utf-8"))
|
||||
if err:
|
||||
print(err.decode("utf-8"))
|
||||
except: pass
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Launcher()
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import psutil
|
||||
|
||||
"""
|
||||
|
@ -32,14 +28,17 @@ class DashGraph(object):
|
|||
self.color = color
|
||||
|
||||
def graph_percentage_abs(self, value):
|
||||
self.graph_elem.DrawLine((self.graph_current_item, 0), (self.graph_current_item, value), color=self.color)
|
||||
self.graph_elem.draw_line(
|
||||
(self.graph_current_item, 0),
|
||||
(self.graph_current_item, value),
|
||||
color=self.color)
|
||||
if self.graph_current_item >= GRAPH_WIDTH:
|
||||
self.graph_elem.Move(-1,0)
|
||||
self.graph_elem.move(-1,0)
|
||||
else:
|
||||
self.graph_current_item += 1
|
||||
|
||||
def text_display(self, text):
|
||||
self.text_elem.Update(text)
|
||||
self.text_elem.update(text)
|
||||
|
||||
def main():
|
||||
# A couple of "Uber Elements" that combine several elements and enable bulk edits
|
||||
|
@ -47,7 +46,7 @@ def main():
|
|||
return(sg.Text(text, font=('Helvetica 8'), **kwargs))
|
||||
|
||||
def GraphColumn(name, key):
|
||||
col = sg.Column([[Txt(name, key=key+'_TXT_'), ],
|
||||
col = sg.Col([[Txt(name, key=key+'_TXT_'), ],
|
||||
[sg.Graph((GRAPH_WIDTH, GRAPH_HEIGHT), (0, 0), (GRAPH_WIDTH, 100), background_color='black',
|
||||
key=key+'_GRAPH_')]], pad=(2, 2))
|
||||
return col
|
||||
|
@ -55,10 +54,11 @@ def main():
|
|||
|
||||
num_cores = len(psutil.cpu_percent(percpu=True)) # get the number of cores in the CPU
|
||||
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.SetOptions(element_padding=(0,0), margins=(1,1), border_width=0)
|
||||
sg.change_look_and_feel('Black')
|
||||
sg.set_options(element_padding=(0,0), margins=(1,1), border_width=0)
|
||||
|
||||
# ---------------- Create Layout ----------------
|
||||
# the clever Red X graphic
|
||||
red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
|
||||
layout = [[ sg.Button('', image_data=red_x, button_color=('black', 'black'), key='Exit', tooltip='Closes window'),
|
||||
sg.Text(' CPU Core Usage')] ]
|
||||
|
||||
|
@ -70,7 +70,7 @@ def main():
|
|||
layout.append(row)
|
||||
|
||||
# ---------------- Create Window ----------------
|
||||
window = sg.Window('PSG System Dashboard',
|
||||
window = sg.Window('PSG System Dashboard', layout,
|
||||
keep_on_top=True,
|
||||
auto_size_buttons=False,
|
||||
grab_anywhere=True,
|
||||
|
@ -79,32 +79,31 @@ def main():
|
|||
return_keyboard_events=True,
|
||||
alpha_channel=TRANSPARENCY,
|
||||
use_default_focus=False,
|
||||
).Layout(layout).Finalize()
|
||||
finalize=True)
|
||||
|
||||
# setup graphs & initial values
|
||||
graphs = []
|
||||
for i in range(num_cores):
|
||||
graphs.append(DashGraph(window.FindElement('_CPU_'+str(i)+'_GRAPH_'),
|
||||
window.FindElement('_CPU_'+str(i) + '_TXT_'),
|
||||
graphs.append(DashGraph(window['_CPU_'+str(i)+'_GRAPH_'],
|
||||
window['_CPU_'+str(i) + '_TXT_'],
|
||||
0, colors[i%6]))
|
||||
|
||||
# ---------------- main loop ----------------
|
||||
while (True):
|
||||
while True :
|
||||
# --------- Read and update window once every Polling Frequency --------
|
||||
event, values = window.Read(timeout=POLL_FREQUENCY)
|
||||
event, values = window.read(timeout=POLL_FREQUENCY)
|
||||
if event in (None, 'Exit'): # Be nice and give an exit
|
||||
break
|
||||
# read CPU for each core
|
||||
stats = psutil.cpu_percent(percpu=True)
|
||||
# Update each graph
|
||||
|
||||
# update each graph
|
||||
for i in range(num_cores):
|
||||
graphs[i].graph_percentage_abs(stats[i])
|
||||
graphs[i].text_display('{} CPU {:2.0f}'.format(i, stats[i]))
|
||||
window.Close()
|
||||
|
||||
window.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# the clever Red X graphic
|
||||
red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
|
||||
|
||||
main()
|
||||
sys.exit(69)
|
|
@ -1,20 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import time
|
||||
import random
|
||||
import psutil
|
||||
from threading import Thread
|
||||
|
||||
|
||||
STEP_SIZE=3
|
||||
STEP_SIZE = 3
|
||||
SAMPLES = 300
|
||||
SAMPLE_MAX = 500
|
||||
CANVAS_SIZE = (300,200)
|
||||
CANVAS_SIZE = (300, 200)
|
||||
|
||||
|
||||
g_interval = .25
|
||||
|
@ -22,6 +17,7 @@ g_cpu_percent = 0
|
|||
g_procs = None
|
||||
g_exit = False
|
||||
|
||||
|
||||
def CPU_thread(args):
|
||||
global g_interval, g_cpu_percent, g_procs, g_exit
|
||||
|
||||
|
@ -32,48 +28,63 @@ def CPU_thread(args):
|
|||
except:
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
global g_exit, g_response_time
|
||||
# start ping measurement thread
|
||||
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.SetOptions(element_padding=(0,0))
|
||||
sg.change_look_and_feel('Black')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [ [sg.Quit( button_color=('white','black')), sg.T('', pad=((100,0),0), font='Any 15', key='output')],
|
||||
[sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,SAMPLE_MAX),background_color='black', key='graph')],]
|
||||
layout = [
|
||||
[sg.Quit(button_color=('white', 'black')),
|
||||
sg.Text('', pad=((100, 0), 0), font='Any 15', key='output')],
|
||||
[sg.Graph(CANVAS_SIZE, (0, 0), (SAMPLES, SAMPLE_MAX),
|
||||
background_color='black', key='graph')]
|
||||
]
|
||||
|
||||
window = sg.Window('CPU Graph', grab_anywhere=True, keep_on_top=True, background_color='black', no_titlebar=True, use_default_focus=False).Layout(layout)
|
||||
window = sg.Window('CPU Graph', layout,
|
||||
grab_anywhere=True, keep_on_top=True,
|
||||
background_color='black', no_titlebar=True,
|
||||
use_default_focus=False)
|
||||
|
||||
graph = window.FindElement('graph')
|
||||
output = window.FindElement('output')
|
||||
graph = window['graph']
|
||||
output = window['output']
|
||||
# start cpu measurement thread
|
||||
thread = Thread(target=CPU_thread,args=(None,))
|
||||
thread = Thread(target=CPU_thread, args=(None,))
|
||||
thread.start()
|
||||
|
||||
last_cpu = i = 0
|
||||
prev_x, prev_y = 0, 0
|
||||
while True: # the Event Loop
|
||||
time.sleep(.5)
|
||||
event, values = window.Read(timeout=0)
|
||||
if event == 'Quit' or event is None: # always give ths user a way out
|
||||
event, values = window.read(timeout=0)
|
||||
if event in ('Quit', None): # always give ths user a way out
|
||||
break
|
||||
# do CPU measurement and graph it
|
||||
current_cpu = int(g_cpu_percent*10)
|
||||
|
||||
if current_cpu == last_cpu:
|
||||
continue
|
||||
output.Update(current_cpu/10) # show current cpu usage at top
|
||||
# show current cpu usage at top
|
||||
output.update(current_cpu/10)
|
||||
|
||||
if current_cpu > SAMPLE_MAX:
|
||||
current_cpu = SAMPLE_MAX
|
||||
new_x, new_y = i, current_cpu
|
||||
|
||||
if i >= SAMPLES:
|
||||
graph.Move(-STEP_SIZE,0) # shift graph over if full of data
|
||||
# shift graph over if full of data
|
||||
graph.move(-STEP_SIZE, 0)
|
||||
prev_x = prev_x - STEP_SIZE
|
||||
graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
graph.draw_line((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
prev_x, prev_y = new_x, new_y
|
||||
i += STEP_SIZE if i < SAMPLES else 0
|
||||
last_cpu = current_cpu
|
||||
|
||||
g_exit = True
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import psutil
|
||||
import time
|
||||
from threading import Thread
|
||||
|
@ -29,6 +24,7 @@ g_cpu_percent = 0
|
|||
g_procs = None
|
||||
g_exit = False
|
||||
|
||||
|
||||
def CPU_thread(args):
|
||||
global g_interval, g_cpu_percent, g_procs, g_exit
|
||||
|
||||
|
@ -44,30 +40,30 @@ def main():
|
|||
global g_interval, g_procs, g_exit
|
||||
|
||||
# ---------------- Create Form ----------------
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
layout = [[sg.Text('', size=(8,1), font=('Helvetica', 20),text_color=sg.YELLOWS[0],
|
||||
justification='center', key='text')],
|
||||
[sg.Text('', size=(30, 8), font=('Courier New', 12),text_color='white', justification='left', key='processes')],
|
||||
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0), size=(9,1)),
|
||||
sg.Spin([x+1 for x in range(10)], 3, key='spin')],]
|
||||
sg.change_look_and_feel('Black')
|
||||
layout = [
|
||||
[sg.Text('', size=(8, 1), font=('Helvetica', 20),
|
||||
text_color=sg.YELLOWS[0], justification='center', key='text')],
|
||||
[sg.Text('', size=(30, 8), font=('Courier New', 12),
|
||||
text_color='white', justification='left', key='processes')],
|
||||
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15, 0), 0), size=(9, 1)),
|
||||
sg.Spin([x+1 for x in range(10)], 3, key='spin')]
|
||||
]
|
||||
|
||||
window = sg.Window('CPU Utilization',
|
||||
no_titlebar=True,
|
||||
keep_on_top=True,
|
||||
alpha_channel=.8,
|
||||
grab_anywhere=True).Layout(layout)
|
||||
window = sg.Window('CPU Utilization', layout
|
||||
no_titlebar=True, keep_on_top=True, alpha_channel=.8, grab_anywhere=True)
|
||||
|
||||
# start cpu measurement thread
|
||||
thread = Thread(target=CPU_thread,args=(None,))
|
||||
thread = Thread(target=CPU_thread, args=(None,))
|
||||
thread.start()
|
||||
timeout_value = 1 # make first read really quick
|
||||
g_interval = 1
|
||||
# ---------------- main loop ----------------
|
||||
while (True):
|
||||
while True:
|
||||
# --------- Read and update window --------
|
||||
event, values = window.Read(timeout=timeout_value, timeout_key='Timeout')
|
||||
event, values = window.read(timeout=timeout_value, timeout_key='Timeout')
|
||||
# --------- Do Button Operations --------
|
||||
if event is None or event == 'Exit':
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
timeout_value = int(values['spin']) * 1000
|
||||
|
@ -77,11 +73,12 @@ def main():
|
|||
if g_procs:
|
||||
# --------- Create list of top % CPU porocesses --------
|
||||
try:
|
||||
top = {proc.name() : proc.cpu_percent() for proc in g_procs}
|
||||
except: pass
|
||||
top = {proc.name(): proc.cpu_percent() for proc in g_procs}
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
top_sorted = sorted(top.items(), key=operator.itemgetter(1), reverse=True)
|
||||
top_sorted = sorted(
|
||||
top.items(), key=operator.itemgetter(1), reverse=True)
|
||||
if top_sorted:
|
||||
top_sorted.pop(0)
|
||||
display_string = ''
|
||||
|
@ -89,11 +86,14 @@ def main():
|
|||
display_string += '{:2.2f} {}\n'.format(cpu/10, proc)
|
||||
|
||||
# --------- Display timer and proceses in window --------
|
||||
window.FindElement('text').Update('CPU {}'.format(cpu_percent))
|
||||
window.FindElement('processes').Update(display_string)
|
||||
window['text'].update('CPU ' + str(cpu_percent))
|
||||
window['processes'].update(display_string)
|
||||
|
||||
g_exit = True
|
||||
thread.join()
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -1,45 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
import psutil
|
||||
|
||||
# Yet another usage of CPU data
|
||||
|
||||
# ---------------- Create Form ----------------
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.change_look_and_feel('Black')
|
||||
|
||||
layout = [[sg.Text('CPU Utilization')],
|
||||
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='_text_')],
|
||||
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15, 0), 0), size=(9,1)),
|
||||
sg.Spin([x + 1 for x in range(10)], 3, key='_spin_')]]
|
||||
[sg.Text('', size=(8, 2), font=('Helvetica', 20),
|
||||
justification='center', key='-text-')],
|
||||
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15, 0), 0), size=(9, 1)),
|
||||
sg.Spin([x + 1 for x in range(10)], 3, key='-spin-')]]
|
||||
|
||||
# Layout the rows of the Window
|
||||
window = sg.Window('CPU Meter',
|
||||
layout,
|
||||
no_titlebar=True,
|
||||
keep_on_top=True,
|
||||
grab_anywhere=True).Layout(layout).Finalize()
|
||||
grab_anywhere=True, finalize=True)
|
||||
|
||||
# ---------------- main loop ----------------
|
||||
interval = 10 # For the first one, make it quick
|
||||
while (True):
|
||||
while True:
|
||||
# --------- Read and update window --------
|
||||
event, values = window.Read(timeout=interval)
|
||||
event, values = window.read(timeout=interval)
|
||||
# --------- Do Button Operations --------
|
||||
if event is None or event == 'Exit':
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
interval = int(values['_spin_'])*1000
|
||||
|
||||
|
||||
interval = int(values['-spin-'])*1000
|
||||
|
||||
cpu_percent = psutil.cpu_percent(interval=1)
|
||||
|
||||
# --------- Display timer in window --------
|
||||
|
||||
window.FindElement('_text_').Update(f'CPU {cpu_percent:02.0f}%')
|
||||
window['-text-'].update(f'CPU {cpu_percent:02.0f}%')
|
||||
|
||||
# Broke out of main loop. Close the window.
|
||||
window.CloseNonBlocking()
|
||||
window.CloseNonBlocking()
|
||||
|
|
|
@ -1,66 +1,67 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
sg.PopupError('Sorry, at the moment this program only runs on Python 3')
|
||||
sys.exit()
|
||||
|
||||
import PySimpleGUI as sg
|
||||
import email
|
||||
import imaplib
|
||||
from datetime import datetime
|
||||
import calendar
|
||||
|
||||
'''
|
||||
Usage of Notification in PSG
|
||||
'''
|
||||
|
||||
IMAP_SERVER_GMAIL = 'imap.gmail.com' # gmail server address
|
||||
IMAP_SERVER_HOTMAIL = 'imap-mail.outlook.com' # hotmail server address
|
||||
|
||||
################# Change these to match your email setup ################
|
||||
LOGIN_EMAIL = 'you@mail.com'
|
||||
LOGIN_PASSWORD = 'your email password'
|
||||
IMAP_SERVER = IMAP_SERVER_GMAIL # change to match your email service
|
||||
|
||||
# change to match your email service
|
||||
IMAP_SERVER = IMAP_SERVER_GMAIL
|
||||
MAX_EMAILS = 10
|
||||
|
||||
|
||||
def gui():
|
||||
sg.ChangeLookAndFeel('Topanga')
|
||||
|
||||
sg.SetOptions(border_width=0, margins=(0, 0), element_padding=(4, 0))
|
||||
|
||||
layout = [[sg.T('Email New Mail Notification' + 48 * ' '),
|
||||
sg.Button('', image_data=refresh, button_color=('#282923', '#282923'), key='_refresh_',
|
||||
tooltip='Refreshes Email'),
|
||||
sg.Button('', image_data=red_x, button_color=('#282923', '#282923'), key='_quit_',
|
||||
tooltip='Closes window')],
|
||||
[sg.T('', key='_status_', size=(25, 1))], ]
|
||||
sg.change_look_and_feel('Topanga')
|
||||
sg.set_options(border_width=0, margins=(0, 0), element_padding=(4, 0))
|
||||
color = ('#282923', '#282923')
|
||||
layout = [[sg.Text('Email New Mail Notification' + 48 * ' '),
|
||||
sg.Button('', image_data=refresh,
|
||||
button_color=color,
|
||||
key='-refresh-',
|
||||
tooltip='refreshes Email'),
|
||||
sg.Button('', image_data=red_x,
|
||||
button_color=color,
|
||||
key='-quit-',
|
||||
tooltip='Closes window')],
|
||||
[sg.Text('', key='-status-', size=(25, 1))], ]
|
||||
|
||||
for i in range(MAX_EMAILS):
|
||||
layout.append([sg.T('', size=(20, 1), key='{}date'.format(i), font='Sans 8'),
|
||||
sg.T('', size=(45, 1), font='Sans 8', key='{}from'.format(i))])
|
||||
layout.append([sg.Text('', size=(20, 1), key='{}date'.format(i), font='Sans 8'),
|
||||
sg.Text('', size=(45, 1), font='Sans 8', key='{}from'.format(i))])
|
||||
|
||||
window = sg.Window('',
|
||||
layout,
|
||||
no_titlebar=True,
|
||||
grab_anywhere=True,
|
||||
keep_on_top=True,
|
||||
alpha_channel=0,
|
||||
).Layout(layout).Finalize()
|
||||
finalize=True)
|
||||
|
||||
# move the window to the upper right corner of the screen
|
||||
w, h = window.GetScreenDimensions()
|
||||
window.Move(w - 410, 0)
|
||||
window.SetAlpha(.9)
|
||||
window.Refresh()
|
||||
status_elem = window.FindElement('_status_')
|
||||
# The Event Loop
|
||||
w, h = window.get_screen_dimensions()
|
||||
window.move(w - 410, 0)
|
||||
window.set_alpha(.9)
|
||||
window.refresh()
|
||||
|
||||
status_elem = window['-status-']
|
||||
|
||||
while True:
|
||||
status_elem.Update('Reading...')
|
||||
window.Refresh()
|
||||
status_elem.update('Reading...')
|
||||
window.refresh()
|
||||
read_mail(window)
|
||||
status_elem.Update('')
|
||||
event, values = window.Read(timeout=30 * 1000) # return every 30 seconds
|
||||
if event == '_quit_':
|
||||
status_elem.update('')
|
||||
# return every 30 seconds
|
||||
event, values = window.read(timeout=30 * 1000)
|
||||
if event == '-quit-':
|
||||
break
|
||||
|
||||
|
||||
|
@ -78,31 +79,35 @@ def read_mail(window):
|
|||
n = 0
|
||||
now = datetime.now()
|
||||
# get messages from today
|
||||
search_string = '(SENTON {}-{}-{})'.format(now.day, calendar.month_abbr[now.month], now.year)
|
||||
search_string = '(SENTON {}-{}-{})'.format(now.day,
|
||||
calendar.month_abbr[now.month], now.year)
|
||||
(retcode, messages) = mail.search(None, search_string)
|
||||
if retcode == 'OK':
|
||||
msg_list = messages[0].split() # message numbers are separated by spaces, turn into list
|
||||
# message numbers are separated by spaces, turn into list
|
||||
msg_list = messages[0].split()
|
||||
msg_list.sort(reverse=True) # sort messages descending
|
||||
for n, message in enumerate(msg_list):
|
||||
if n >= MAX_EMAILS:
|
||||
break
|
||||
from_elem = window.FindElement('{}from'.format(n))
|
||||
date_elem = window.FindElement('{}date'.format(n))
|
||||
from_elem.Update('') # erase them so you know they're changing
|
||||
date_elem.Update('')
|
||||
window.Refresh()
|
||||
|
||||
from_elem = window['{}from'.format(n)]
|
||||
date_elem = window['{}date'.format(n)]
|
||||
from_elem.update('') # erase them so you know they're changing
|
||||
date_elem.update('')
|
||||
window.refresh()
|
||||
|
||||
typ, data = mail.fetch(message, '(RFC822)')
|
||||
for response_part in data:
|
||||
if isinstance(response_part, tuple):
|
||||
|
||||
original = email.message_from_bytes(response_part[1])
|
||||
date_str = original['Date'][:22]
|
||||
from_elem.Update(original['From'])
|
||||
date_elem.Update(date_str)
|
||||
window.Refresh() # make the window changes show up right away
|
||||
|
||||
from_elem.update(original['From'])
|
||||
date_elem.update(date_str)
|
||||
window.refresh() # make the window changes show up right away
|
||||
|
||||
|
||||
red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
|
||||
|
||||
refresh = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACb0lEQVR4XpVTXUiTbxT/vePdFuF0BTFW9ufVvMlu+iACka6CQY1gQVdtEmTMpSKzzJT/RTdCRHhT4F0Us8LGVqlo1lZaFslWQWBkN+tDkpSpbfNz797T8zy6DbUbf/Dbec7vfOycMwa0DBJjM7Ko72mBtz+KplCS6Ronf3NNxNZBt2qv4dJzL0uKwGRqU/6zHDqyd1dBk32/xMnfXOMxkVPXXYlVSLjykk4fKIb/4zgUSxEO7zRBKd4Bjm/jU9ys8f2fJoCFhRiWl6pw6+Qw0BymhlfT5Lg/xmycHA++ktL+nsRqrUOrdpBpH6hhKC7yhObti0CgKUTu0KTgcd8X4j4aB2bYvj7UPqkQrO/1cU25ESV3eJJO8LzLIQ11/CYXn5Grf4KqGF19E3Ts9iixe2QPm0dtt5PtP6NcHxF5ZVfDhIbeqMQ6E0hcI4ec327jah513T4YDM5TR/dh8vc0hkfHUxI2gwuPKyDLb2wV5cIdePuZZGwWmQxSSyqICFBVyKgJJkFaQW4Hna4THQ4X/gUiD2+QXEwjNZsASJvTgWgMqoY95WWw7raAJdjheeTEeniCTqgZu2IxswnSmGI3gEZjMiQpAMocTC2nJcm4hU9gRjp9E+6Ajb07wKFpHqRVOzKqedFUhOX4HyRnEwSjMQCB8/4IqnxU2DYiaGnsIe7n2UlK61MWe0dbW18Ijdfk/wuy7IXeEEvEvmM+kcRM4XYYSkohW62ChtIS/NKbWGwO8z9+Anp9TNSsQU2wEtVdEZy5o7Gfi7Z5ewj/vxbkPs51kYhVP4zAw3I3IN+ohSVFcfZeEs67Gid/c03E1uEv5QpTFzvZK5EAAAAASUVORK5CYII='
|
||||
|
||||
gui()
|
||||
|
|
|
@ -14,30 +14,38 @@ import time
|
|||
|
||||
"""
|
||||
|
||||
|
||||
def time_as_int():
|
||||
return int(round(time.time() * 100))
|
||||
|
||||
|
||||
# ---------------- Create Form ----------------
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.change_look_and_feel('Black')
|
||||
|
||||
layout = [[sg.Text('')],
|
||||
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
|
||||
[sg.Button('Pause', key='-RUN-PAUSE-', button_color=('white', '#001480')),
|
||||
sg.Button('Reset', button_color=('white', '#007339'), key='-RESET-'),
|
||||
sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]
|
||||
[sg.Text('', size=(8, 2), font=('Helvetica', 20),
|
||||
justification='center', key='text')],
|
||||
[sg.Button('Pause', key='-RUN-PAUSE-', button_color=('white', '#001480')),
|
||||
sg.Button('Reset', button_color=('white', '#007339'), key='-RESET-'),
|
||||
sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]
|
||||
|
||||
window = sg.Window('Running Timer', layout, no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True, element_padding=(0,0))
|
||||
window = sg.Window('Running Timer', layout,
|
||||
no_titlebar=True,
|
||||
auto_size_buttons=False,
|
||||
keep_on_top=True,
|
||||
grab_anywhere=True,
|
||||
element_padding=(0, 0))
|
||||
|
||||
# ---------------- main loop ----------------
|
||||
current_time, paused_time, paused = 0, 0, False
|
||||
start_time = time_as_int()
|
||||
while (True):
|
||||
|
||||
while True:
|
||||
# --------- Read and update window --------
|
||||
if not paused:
|
||||
event, values = window.Read(timeout=10)
|
||||
event, values = window.read(timeout=10)
|
||||
current_time = time_as_int() - start_time
|
||||
else:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
# --------- Do Button Operations --------
|
||||
if event in (None, 'Exit'): # ALWAYS give a way out of program
|
||||
break
|
||||
|
@ -50,10 +58,11 @@ while (True):
|
|||
paused_time = time_as_int()
|
||||
else:
|
||||
start_time = start_time + time_as_int() - paused_time
|
||||
window['-RUN-PAUSE-'].Update('Run' if paused else 'Pause') # Change button's text
|
||||
# Change button's text
|
||||
window['-RUN-PAUSE-'].update('Run' if paused else 'Pause')
|
||||
|
||||
# --------- Display timer in window --------
|
||||
window['text'].Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
|
||||
(current_time // 100) % 60,
|
||||
current_time % 100))
|
||||
window.close()
|
||||
window['text'].update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
|
||||
(current_time // 100) % 60,
|
||||
current_time % 100))
|
||||
window.close()
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import psutil
|
||||
|
||||
"""
|
||||
|
@ -20,6 +16,7 @@ GRAPH_WIDTH = 120 # each individual graph size in pixels
|
|||
GRAPH_HEIGHT = 40
|
||||
ALPHA = .7
|
||||
|
||||
|
||||
class DashGraph(object):
|
||||
def __init__(self, graph_elem, starting_count, color):
|
||||
self.graph_current_item = 0
|
||||
|
@ -33,106 +30,118 @@ class DashGraph(object):
|
|||
self.prev_value = current_value
|
||||
self.max_sent = max(self.max_sent, delta)
|
||||
percent_sent = 100 * delta / self.max_sent
|
||||
self.graph_elem.DrawLine((self.graph_current_item, 0), (self.graph_current_item, percent_sent), color=self.color)
|
||||
self.graph_elem.draw_line((self.graph_current_item, 0),
|
||||
(self.graph_current_item, percent_sent),
|
||||
color=self.color)
|
||||
if self.graph_current_item >= GRAPH_WIDTH:
|
||||
self.graph_elem.Move(-1,0)
|
||||
self.graph_elem.move(-1, 0)
|
||||
else:
|
||||
self.graph_current_item += 1
|
||||
return delta
|
||||
|
||||
def graph_percentage_abs(self, value):
|
||||
self.graph_elem.DrawLine((self.graph_current_item, 0), (self.graph_current_item, value), color=self.color)
|
||||
self.graph_elem.draw_line((self.graph_current_item, 0),
|
||||
(self.graph_current_item, value),
|
||||
color=self.color)
|
||||
if self.graph_current_item >= GRAPH_WIDTH:
|
||||
self.graph_elem.Move(-1,0)
|
||||
self.graph_elem.move(-1, 0)
|
||||
else:
|
||||
self.graph_current_item += 1
|
||||
|
||||
|
||||
def human_size(bytes, units=[' bytes','KB','MB','GB','TB', 'PB', 'EB']):
|
||||
def human_size(bytes, units=[' bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB']):
|
||||
""" Returns a human readable string reprentation of bytes"""
|
||||
return str(bytes) + units[0] if bytes < 1024 else human_size(bytes>>10, units[1:])
|
||||
return str(bytes) + units[0] if bytes < 1024 else human_size(bytes >> 10, units[1:])
|
||||
|
||||
|
||||
def main():
|
||||
# Make the layout less cluttered and allow bulk-changes to text formatting
|
||||
def Txt(text, **kwargs):
|
||||
return(sg.Text(text, font=('Helvetica 8'), **kwargs))
|
||||
# Update a Text Element
|
||||
def Txt_Update(window, key, value):
|
||||
window.FindElement(key).Update(value)
|
||||
|
||||
# ---------------- Create Window ----------------
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.SetOptions(element_padding=(0,0), margins=(1,1), border_width=0)
|
||||
sg.change_look_and_feel('Black')
|
||||
sg.set_options(element_padding=(0, 0), margins=(1, 1), border_width=0)
|
||||
|
||||
def GraphColumn(name, key):
|
||||
col = sg.Column([[Txt(name, key=key+'TXT_'), ],
|
||||
[sg.Graph((GRAPH_WIDTH, GRAPH_HEIGHT), (0, 0), (GRAPH_WIDTH, 100), background_color='black',
|
||||
key=key+'GRAPH_')]], pad=(2, 2))
|
||||
return col
|
||||
layout = [
|
||||
[sg.Text(name, font=('Helvetica 8'), key=key+'TXT_')],
|
||||
[sg.Graph((GRAPH_WIDTH, GRAPH_HEIGHT),
|
||||
(0, 0),
|
||||
(GRAPH_WIDTH, 100),
|
||||
background_color='black',
|
||||
key=key+'GRAPH_')]]
|
||||
return sg.Col(layout, pad=(2, 2))
|
||||
|
||||
layout = [[sg.Text('System Status Dashboard'+' '*18), sg.Button('', image_data=red_x, button_color=('black', 'black'), key='Exit', tooltip='Closes window')],
|
||||
[GraphColumn('Net Out', '_NET_OUT_'),
|
||||
GraphColumn('Net In', '_NET_IN_')],
|
||||
[GraphColumn('Disk Read', '_DISK_READ_'),
|
||||
GraphColumn('Disk Write', '_DISK_WRITE_')],
|
||||
[GraphColumn('CPU Usage', '_CPU_'),
|
||||
GraphColumn('Memory Usage', '_MEM_')],]
|
||||
red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
|
||||
layout = [
|
||||
[sg.Text('System Status Dashboard'+' '*18),
|
||||
sg.Button('',
|
||||
image_data=red_x,
|
||||
button_color=('black', 'black'),
|
||||
key='Exit',
|
||||
tooltip='Closes window')],
|
||||
[GraphColumn('Net Out', '_NET_OUT_'),
|
||||
GraphColumn('Net In', '_NET_IN_')],
|
||||
[GraphColumn('Disk Read', '_DISK_READ_'),
|
||||
GraphColumn('Disk Write', '_DISK_WRITE_')],
|
||||
[GraphColumn('CPU Usage', '_CPU_'),
|
||||
GraphColumn('Memory Usage', '_MEM_')], ]
|
||||
|
||||
window = sg.Window('PSG System Dashboard',
|
||||
keep_on_top=True,
|
||||
auto_size_buttons=False,
|
||||
grab_anywhere=True,
|
||||
no_titlebar=True,
|
||||
default_button_element_size=(12, 1),
|
||||
return_keyboard_events=True,
|
||||
alpha_channel=ALPHA,
|
||||
use_default_focus=False,
|
||||
).Layout(layout).Finalize()
|
||||
window = sg.Window('PSG System Dashboard', layout,
|
||||
keep_on_top=True, auto_size_buttons=False,
|
||||
grab_anywhere=True, no_titlebar=True,
|
||||
default_button_element_size=(12, 1),
|
||||
return_keyboard_events=True, alpha_channel=ALPHA,
|
||||
use_default_focus=False, finalize=True)
|
||||
|
||||
# setup graphs & initial values
|
||||
netio = psutil.net_io_counters()
|
||||
net_graph_in = DashGraph(window.FindElement('_NET_IN_GRAPH_'), netio.bytes_recv, '#23a0a0')
|
||||
net_graph_out = DashGraph(window.FindElement('_NET_OUT_GRAPH_'), netio.bytes_sent, '#56d856')
|
||||
|
||||
net_in = window['_NET_IN_GRAPH_']
|
||||
net_graph_in = DashGraph(net_in,
|
||||
netio.bytes_recv, '#23a0a0')
|
||||
net_out = window['_NET_OUT_GRAPH_']
|
||||
net_graph_out = DashGraph(net_out,
|
||||
netio.bytes_sent, '#56d856')
|
||||
|
||||
diskio = psutil.disk_io_counters()
|
||||
disk_graph_write = DashGraph(window.FindElement('_DISK_WRITE_GRAPH_'), diskio.write_bytes, '#be45be')
|
||||
disk_graph_read = DashGraph(window.FindElement('_DISK_READ_GRAPH_'), diskio.read_bytes, '#5681d8')
|
||||
disk_graph_write = DashGraph(
|
||||
window['_DISK_WRITE_GRAPH_'], diskio.write_bytes, '#be45be')
|
||||
disk_graph_read = DashGraph(
|
||||
window['_DISK_READ_GRAPH_'], diskio.read_bytes, '#5681d8')
|
||||
|
||||
cpu_usage_graph = DashGraph(window.FindElement('_CPU_GRAPH_'), 0, '#d34545')
|
||||
mem_usage_graph = DashGraph(window.FindElement('_MEM_GRAPH_'), 0, '#BE7C29')
|
||||
cpu_usage_graph = DashGraph(window['_CPU_GRAPH_'], 0, '#d34545')
|
||||
mem_usage_graph = DashGraph(window['_MEM_GRAPH_'], 0, '#BE7C29')
|
||||
|
||||
print(psutil.cpu_percent(percpu=True))
|
||||
# ---------------- main loop ----------------
|
||||
while (True):
|
||||
while True :
|
||||
# --------- Read and update window once a second--------
|
||||
event, values = window.Read(timeout=1000)
|
||||
if event in (None, 'Exit'): # Be nice and give an exit, expecially since there is no titlebar
|
||||
event, values = window.read(timeout=1000)
|
||||
# Be nice and give an exit, expecially since there is no titlebar
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
# ----- Network Graphs -----
|
||||
netio = psutil.net_io_counters()
|
||||
write_bytes = net_graph_out.graph_value(netio.bytes_sent)
|
||||
read_bytes = net_graph_in.graph_value(netio.bytes_recv)
|
||||
Txt_Update(window, '_NET_OUT_TXT_', 'Net out {}'.format(human_size(write_bytes)))
|
||||
Txt_Update(window, '_NET_IN_TXT_', 'Net In {}'.format(human_size(read_bytes)))
|
||||
window['_NET_OUT_TXT_'].update(
|
||||
'Net out {}'.format(human_size(write_bytes)))
|
||||
window['_NET_IN_TXT_'].update(
|
||||
'Net In {}'.format(human_size(read_bytes)))
|
||||
# ----- Disk Graphs -----
|
||||
diskio = psutil.disk_io_counters()
|
||||
write_bytes = disk_graph_write.graph_value(diskio.write_bytes)
|
||||
read_bytes = disk_graph_read.graph_value(diskio.read_bytes)
|
||||
Txt_Update(window, '_DISK_WRITE_TXT_', 'Disk Write {}'.format(human_size(write_bytes)))
|
||||
Txt_Update(window, '_DISK_READ_TXT_', 'Disk Read {}'.format(human_size(read_bytes)))
|
||||
window['_DISK_WRITE_TXT_'].update(
|
||||
'Disk Write {}'.format(human_size(write_bytes)))
|
||||
window['_DISK_READ_TXT_'].update(
|
||||
'Disk Read {}'.format(human_size(read_bytes)))
|
||||
# ----- CPU Graph -----
|
||||
cpu = psutil.cpu_percent(0)
|
||||
cpu_usage_graph.graph_percentage_abs(cpu)
|
||||
Txt_Update(window, '_CPU_TXT_', '{0:2.0f}% CPU Used'.format(cpu))
|
||||
window['_CPU_TXT_'].update('{0:2.0f}% CPU Used'.format(cpu))
|
||||
# ----- Memory Graph -----
|
||||
mem_used = psutil.virtual_memory().percent
|
||||
mem_usage_graph.graph_percentage_abs(mem_used)
|
||||
Txt_Update(window, '_MEM_TXT_', '{}% Memory Used'.format(mem_used))
|
||||
window['_MEM_TXT_'].update('{}% Memory Used'.format(mem_used))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# the clever Red X graphic
|
||||
red_x = "R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
|
||||
|
||||
main()
|
||||
sys.exit(69)
|
|
@ -1,45 +1,66 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
sg.ChangeLookAndFeel('Dark')
|
||||
sg.SetOptions(element_padding=(0, 0))
|
||||
'''
|
||||
Usage of Disable elements
|
||||
'''
|
||||
|
||||
sg.change_look_and_feel('Dark')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [
|
||||
[sg.T('Notes:', pad=((3, 0), 0)), sg.In(size=(44, 1), background_color='white', text_color='black', key='notes')],
|
||||
[sg.T('Output:', pad=((3, 0), 0)), sg.T('', size=(44, 1), text_color='white', key='output')],
|
||||
[sg.CBox('Checkbox:', default=True, pad=((3, 0), 0), disabled=True, key='cbox'), sg.Listbox((1,2,3,4),size=(8,3),disabled=True, key='listbox'),
|
||||
sg.Radio('Radio 1', default=True, group_id='1', disabled=True, key='radio1'), sg.Radio('Radio 2', default=False, group_id='1', disabled=True, key='radio2')],
|
||||
[sg.Spin((1,2,3,4),1,disabled=True, key='spin'), sg.OptionMenu((1,2,3,4),disabled=True, key='option'), sg.Combo(values=(1,2,3,4),disabled=True,key='combo')],
|
||||
[sg.Multiline('Multiline', size=(20,3),disabled=True, key='multi')],
|
||||
[sg.Slider((1,10), size=(20,20), orientation='h', disabled=True, key='slider')],
|
||||
[sg.Button('Enable', button_color=('white', 'black')),
|
||||
sg.Button('Disable', button_color=('white', 'black')),
|
||||
sg.Button('Reset', button_color=('white', '#9B0023'), key='reset'),
|
||||
sg.Button('Values', button_color=('white', 'springgreen4')),
|
||||
sg.Button('Exit', disabled=True, button_color=('white', '#00406B'), key='exit')]]
|
||||
[ sg.Text('Notes:', pad=((3, 0), 0)),
|
||||
sg.Input(size=(44, 1), background_color='white', text_color='black', key='notes')],
|
||||
|
||||
window = sg.Window("Disable Elements Demo", default_element_size=(12, 1), text_justification='r', auto_size_text=False,
|
||||
auto_size_buttons=False, keep_on_top=True, grab_anywhere=False,
|
||||
default_button_element_size=(12, 1)).Layout(layout).Finalize()
|
||||
[ sg.Text('Output:', pad=((3, 0), 0)),
|
||||
sg.Text('', size=(44, 1), text_color='white', key='output')],
|
||||
|
||||
[sg.CBox('Checkbox:', default=True, pad=((3, 0), 0), disabled=True, key='cbox'),
|
||||
sg.Listbox((1, 2, 3, 4), size=(8, 3), disabled=True, key='listbox'),
|
||||
sg.Radio('Radio 1', default=True, group_id='1', disabled=True, key='radio1'),
|
||||
sg.Radio('Radio 2', default=False, group_id='1', disabled=True, key='radio2')],
|
||||
|
||||
[sg.Spin((1, 2, 3, 4), 1, disabled=True, key='spin'),
|
||||
sg.OptionMenu((1, 2, 3, 4), disabled=True, key='option'),
|
||||
sg.Combo(values=(1, 2, 3, 4), disabled=True, key='combo')],
|
||||
|
||||
[sg.ML('Multiline', size=(20, 3), disabled=True, key='multi')],
|
||||
|
||||
[sg.Slider((1, 10), size=(20, 20), orientation='h', disabled=True, key='slider')],
|
||||
|
||||
[sg.Button('Enable', button_color=('white', 'black')),
|
||||
sg.Button('Disable', button_color=('white', 'black')),
|
||||
sg.Button('Reset', button_color=('white', '#9B0023'), key='reset'),
|
||||
sg.Button('Values', button_color=('white', 'springgreen4')),
|
||||
sg.Button('Exit', disabled=True, button_color=('white', '#00406B'), key='exit')]]
|
||||
|
||||
window = sg.Window("Disable Elements Demo", layout,
|
||||
default_element_size=(12, 1),
|
||||
text_justification='r',
|
||||
auto_size_text=False,
|
||||
auto_size_buttons=False,
|
||||
keep_on_top=True,
|
||||
grab_anywhere=False,
|
||||
default_button_element_size=(12, 1),
|
||||
finalize=True)
|
||||
|
||||
key_list = 'cbox', 'listbox', 'radio1', 'radio2', 'spin', 'option', 'combo', 'reset', 'notes', 'multi', 'slider', 'exit'
|
||||
|
||||
for key in key_list: window.FindElement(key).Update(disabled=True) # don't do this kind of for-loop
|
||||
# don't do this kind of for-loop
|
||||
for key in key_list:
|
||||
window[key].update(disabled=True)
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event in (None, 'exit'):
|
||||
break
|
||||
elif event == 'Disable':
|
||||
for key in key_list: window.FindElement(key).Update(disabled=True)
|
||||
for key in key_list:
|
||||
window[key].update(disabled=True)
|
||||
elif event == 'Enable':
|
||||
for key in key_list: window.FindElement(key).Update(disabled=False)
|
||||
for key in key_list:
|
||||
window[key].update(disabled=False)
|
||||
elif event == 'Values':
|
||||
sg.Popup(values, keep_on_top=True)
|
||||
sg.popup(values, keep_on_top=True)
|
||||
|
||||
sys.exit(0)
|
||||
window.close()
|
|
@ -1,29 +1,30 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
'''
|
||||
Find dups with PySimpleGUI
|
||||
'''
|
||||
|
||||
# ====____====____==== FUNCTION DeDuplicate_folder(path) ====____====____==== #
|
||||
# Function to de-duplicate the folder passed in #
|
||||
# --------------------------------------------------------------------------- #
|
||||
def FindDuplicatesFilesInFolder(path):
|
||||
shatab = []
|
||||
total = 0
|
||||
small_count, dup_count, error_count = 0,0,0
|
||||
total, small_count, dup_count, error_count = [0]*4
|
||||
pngdir = path
|
||||
if not os.path.exists(path):
|
||||
sg.Popup('Duplicate Finder', '** Folder doesn\'t exist***', path)
|
||||
sg.popup('Duplicate Finder', '** Folder doesn\'t exist***', path)
|
||||
return
|
||||
pngfiles = os.listdir(pngdir)
|
||||
total_files = len(pngfiles)
|
||||
|
||||
for idx, f in enumerate(pngfiles):
|
||||
if not sg.OneLineProgressMeter('Counting Duplicates', idx + 1, total_files, 'Counting Duplicate Files'):
|
||||
if not sg.one_line_progress_meter('Counting Duplicates',
|
||||
idx + 1,
|
||||
total_files,
|
||||
'Counting Duplicate Files'):
|
||||
break
|
||||
total += 1
|
||||
fname = os.path.join(pngdir, f)
|
||||
|
@ -42,8 +43,10 @@ def FindDuplicatesFilesInFolder(path):
|
|||
continue
|
||||
shatab.append(f_sha)
|
||||
|
||||
msg = '{} Files processed\n {} Duplicates found'.format(total_files, dup_count)
|
||||
sg.Popup('Duplicate Finder Ended', msg)
|
||||
msg = '{} Files processed\n {} Duplicates found'.format(
|
||||
total_files, dup_count)
|
||||
sg.popup('Duplicate Finder Ended', msg)
|
||||
|
||||
|
||||
# ====____====____==== Pseudo-MAIN program ====____====____==== #
|
||||
# This is our main-alike piece of code #
|
||||
|
@ -54,9 +57,10 @@ def FindDuplicatesFilesInFolder(path):
|
|||
if __name__ == '__main__':
|
||||
|
||||
source_folder = None
|
||||
source_folder = sg.PopupGetFolder('Duplicate Finder - Count number of duplicate files', 'Enter path to folder you wish to find duplicates in')
|
||||
source_folder = sg.popup_get_folder(
|
||||
'Duplicate Finder - Count number of duplicate files', 'Enter path to folder you wish to find duplicates in')
|
||||
if source_folder is not None:
|
||||
FindDuplicatesFilesInFolder(source_folder)
|
||||
else:
|
||||
sg.PopupCancel('Cancelling', '*** Cancelling ***')
|
||||
sg.popup_cancel('Cancelling', '*** Cancelling ***')
|
||||
exit(0)
|
||||
|
|
|
@ -4,72 +4,79 @@ from shutil import copyfile
|
|||
import shutil
|
||||
import os
|
||||
|
||||
def Launcher():
|
||||
sg.ChangeLookAndFeel('LightGreen')
|
||||
'''
|
||||
Make a "Windows os" executable with PyInstaller
|
||||
'''
|
||||
|
||||
layout = [[sg.T('PyInstaller EXE Creator', font='Any 15')],
|
||||
[sg.T('Source Python File'), sg.In(key='_sourcefile_', size=(45,1)), sg.FileBrowse(file_types=(("Python Files", "*.py"),))],
|
||||
[sg.T('Icon File'), sg.In(key='_iconfile_', size=(45,1)), sg.FileBrowse(file_types=(("Icon Files", "*.ico"),))],
|
||||
[sg.Frame('Output', font='Any 15',layout= [[sg.Output(size=(65, 15), font='Courier 10')]])],
|
||||
[sg.ReadFormButton('Make EXE',bind_return_key=True),
|
||||
sg.SimpleButton('Quit', button_color=('white','firebrick3')),]]
|
||||
def Launcher():
|
||||
sg.change_look_and_feel('LightGreen')
|
||||
|
||||
layout = [[sg.Text('PyInstaller EXE Creator', font='Any 15')],
|
||||
[sg.Text('Source Python File'), sg.Input(key='-sourcefile-', size=(45, 1)),
|
||||
sg.FileBrowse(file_types=(("Python Files", "*.py"),))],
|
||||
[sg.Text('Icon File'), sg.Input(key='-iconfile-', size=(45, 1)),
|
||||
sg.FileBrowse(file_types=(("Icon Files", "*.ico"),))],
|
||||
[sg.Frame('Output', font='Any 15', layout=[
|
||||
[sg.Output(size=(65, 15), font='Courier 10')]])],
|
||||
[sg.ReadFormButton('Make EXE', bind_return_key=True),
|
||||
sg.SimpleButton('Quit', button_color=('white', 'firebrick3')), ]]
|
||||
|
||||
window = sg.Window('PySimpleGUI EXE Maker',
|
||||
layout,
|
||||
auto_size_text=False,
|
||||
auto_size_buttons=False,
|
||||
default_element_size=(20,1,),
|
||||
default_element_size=(20, 1,),
|
||||
text_justification='right')
|
||||
|
||||
window.Layout(layout)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
(button, values) = window.Read()
|
||||
if button in ('Quit', None):
|
||||
break # exit button clicked
|
||||
|
||||
source_file = values['_sourcefile_']
|
||||
icon_file = values['_iconfile_']
|
||||
event, values = window.read()
|
||||
if event in ('Exit', 'Quit', None):
|
||||
break
|
||||
|
||||
source_file = values['-sourcefile-']
|
||||
icon_file = values['-iconfile-']
|
||||
|
||||
icon_option = '-i "{}"'.format(icon_file) if icon_file else ''
|
||||
source_path, source_filename = os.path.split(source_file)
|
||||
workpath_option = '--workpath "{}"'.format(source_path)
|
||||
dispath_option = '--distpath "{}"'.format(source_path)
|
||||
specpath_option = '--specpath "{}"'.format(source_path)
|
||||
folder_to_remove = os.path.join(source_path,source_filename[:-3])
|
||||
file_to_remove = os.path.join(source_path, source_filename[:-3]+'.spec')
|
||||
command_line = 'pyinstaller -wF "{}" {} {} {} {}'.format(source_file, icon_option, workpath_option, dispath_option, specpath_option)
|
||||
folder_to_remove = os.path.join(source_path, source_filename[:-3])
|
||||
file_to_remove = os.path.join(
|
||||
source_path, source_filename[:-3]+'.spec')
|
||||
command_line = 'pyinstaller -wF "{}" {} {} {} {}'.format(
|
||||
source_file, icon_option, workpath_option, dispath_option, specpath_option)
|
||||
|
||||
if button == 'Make EXE':
|
||||
if event == 'Make EXE':
|
||||
try:
|
||||
print(command_line)
|
||||
print('Making EXE... this will take a while.. the program has NOT locked up...')
|
||||
window.Refresh()
|
||||
print(
|
||||
'Making EXE...the program has NOT locked up...')
|
||||
window.refresh()
|
||||
# print('Running command {}'.format(command_line))
|
||||
runCommand(command_line)
|
||||
shutil.rmtree(folder_to_remove)
|
||||
os.remove(file_to_remove)
|
||||
print('**** DONE ****')
|
||||
except:
|
||||
sg.PopupError('Something went wrong')
|
||||
sg.popup_error('Something went wrong')
|
||||
|
||||
|
||||
def runCommand(cmd, timeout=None):
|
||||
""" run shell command
|
||||
"""
|
||||
run shell command
|
||||
|
||||
@param cmd: command to execute
|
||||
@param timeout: timeout for command execution
|
||||
@param cmd: command to execute
|
||||
@param timeout: timeout for command execution
|
||||
|
||||
@return: (return code from command, command output)
|
||||
"""
|
||||
@return: (return code from command, command output)
|
||||
"""
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
output = ''
|
||||
|
||||
out, err = p.communicate()
|
||||
p.wait(timeout)
|
||||
|
||||
return (out, err)
|
||||
|
||||
if __name__ == '__main__':
|
||||
Launcher()
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import PySimpleGUI as sg
|
||||
# import PySimpleGUIQt as sg
|
||||
# import PySimpleGUIWx as sg
|
||||
|
||||
'''
|
||||
Event Callback Simulation
|
||||
|
@ -15,17 +13,28 @@ import PySimpleGUI as sg
|
|||
|
||||
# The callback functions
|
||||
# These callbacks all display a message in a non-blocking way and immediately return
|
||||
|
||||
|
||||
def button1(event, values):
|
||||
sg.popup_quick_message('Button 1 callback', background_color='red', text_color='white')
|
||||
sg.popup_quick_message('Button 1 callback',
|
||||
background_color='red',
|
||||
text_color='white')
|
||||
|
||||
|
||||
def button2(event, values):
|
||||
sg.popup_quick_message('Button 2 callback', background_color='green', text_color='white')
|
||||
sg.popup_quick_message('Button 2 callback',
|
||||
background_color='green',
|
||||
text_color='white')
|
||||
|
||||
|
||||
def catch_all(event, values):
|
||||
sg.popup_quick_message(f'An unplanned event = "{event}" happend', background_color='blue', text_color='white', auto_close_duration=6)
|
||||
sg.popup_quick_message(f'An unplanned event = "{event}" happend',
|
||||
background_color='blue',
|
||||
text_color='white', auto_close_duration=6)
|
||||
|
||||
|
||||
# Lookup dictionary that maps event to function to call. In this case, only 2 event have defined callbacks
|
||||
func_dict = {'1':button1, '2':button2}
|
||||
func_dict = {'1': button1, '2': button2}
|
||||
|
||||
# Layout the design of the GUI
|
||||
layout = [[sg.Text('Please click a button')],
|
||||
|
@ -50,4 +59,4 @@ while True:
|
|||
window.close()
|
||||
|
||||
# All done!
|
||||
sg.popup_auto_close('Done... this window auto closes')
|
||||
sg.popup_auto_close('Done... this window auto closes')
|
||||
|
|
|
@ -1,66 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
def Everything():
|
||||
sg.ChangeLookAndFeel('TanBlue')
|
||||
'''
|
||||
Example of GUI
|
||||
'''
|
||||
|
||||
def main():
|
||||
sg.change_look_and_feel('TanBlue')
|
||||
|
||||
column1 = [
|
||||
[sg.Text('Column 1', background_color=sg.DEFAULT_BACKGROUND_COLOR, justification='center', size=(10, 1))],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1', key='spin1')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Text('Column 1', background_color=sg.DEFAULT_BACKGROUND_COLOR,
|
||||
justification='center', size=(10, 1))],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'),
|
||||
initial_value='Spin Box 1', key='spin1')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'),
|
||||
initial_value='Spin Box 2', key='spin2')],
|
||||
[sg.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 3', key='spin3')]]
|
||||
|
||||
layout = [
|
||||
[sg.Text('All graphic widgets in one form!', size=(30, 1), font=("Helvetica", 25))],
|
||||
[sg.Text('Here is some text.... and a place to enter text')],
|
||||
[sg.InputText('This is my text', key='in1', do_not_clear=True)],
|
||||
[sg.Checkbox('Checkbox', key='cb1'), sg.Checkbox('My second checkbox!', key='cb2', default=True)],
|
||||
[sg.InputText('This is my text', key='in1')],
|
||||
[sg.CBox('Checkbox', key='cb1'), sg.CBox(
|
||||
'My second checkbox!', key='cb2', default=True)],
|
||||
[sg.Radio('My first Radio! ', "RADIO1", key='rad1', default=True),
|
||||
sg.Radio('My second Radio!', "RADIO1", key='rad2')],
|
||||
[sg.Multiline(default_text='This is the default Text should you decide not to type anything', size=(35, 3),
|
||||
key='multi1', do_not_clear=True),
|
||||
sg.Multiline(default_text='A second multi-line', size=(35, 3), key='multi2', do_not_clear=True)],
|
||||
[sg.InputCombo(('Combobox 1', 'Combobox 2'), key='combo', size=(20, 1)),
|
||||
[sg.MLine(default_text='This is the default Text should you decide not to type anything', size=(35, 3),
|
||||
key='multi1'),
|
||||
sg.MLine(default_text='A second multi-line', size=(35, 3), key='multi2')],
|
||||
[sg.Combo(('Combobox 1', 'Combobox 2'), key='combo', size=(20, 1)),
|
||||
sg.Slider(range=(1, 100), orientation='h', size=(34, 20), key='slide1', default_value=85)],
|
||||
[sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'), key='optionmenu')],
|
||||
[sg.OptionMenu(('Menu Option 1', 'Menu Option 2',
|
||||
'Menu Option 3'), key='optionmenu')],
|
||||
[sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3), key='listbox'),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=25, key='slide2', ),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=75, key='slide3', ),
|
||||
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=10, key='slide4'),
|
||||
sg.Column(column1, background_color='gray34')],
|
||||
sg.Slider(range=(1, 100),
|
||||
orientation='v',
|
||||
size=(5, 20),
|
||||
default_value=25, key='slide2', ),
|
||||
sg.Slider(range=(1, 100),
|
||||
orientation='v',
|
||||
size=(5, 20),
|
||||
default_value=75, key='slide3', ),
|
||||
sg.Slider(range=(1, 100),
|
||||
orientation='v',
|
||||
size=(5, 20),
|
||||
default_value=10, key='slide4'),
|
||||
sg.Col(column1, background_color='gray34')],
|
||||
[sg.Text('_' * 80)],
|
||||
[sg.Text('Choose A Folder', size=(35, 1))],
|
||||
[sg.Text('Your Folder', size=(15, 1), auto_size_text=False, justification='right'),
|
||||
sg.InputText('Default Folder', key='folder', do_not_clear=True), sg.FolderBrowse()],
|
||||
[sg.Text('Your Folder', size=(15, 1), justification='right'),
|
||||
sg.InputText('Default Folder', key='folder'), sg.FolderBrowse()],
|
||||
[sg.Button('Exit'),
|
||||
sg.Text(' ' * 40), sg.Button('SaveSettings'), sg.Button('LoadSettings')]
|
||||
]
|
||||
|
||||
window = sg.Window('Form Fill Demonstration', default_element_size=(40, 1), grab_anywhere=False)
|
||||
# button, values = window.LayoutAndRead(layout, non_blocking=True)
|
||||
window.Layout(layout)
|
||||
window = sg.Window('Form Fill Demonstration', layout, default_element_size=(40, 1), grab_anywhere=False)
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
if event == 'SaveSettings':
|
||||
filename = sg.PopupGetFile('Save Settings', save_as=True, no_window=True)
|
||||
filename = sg.popup_get_file('Save Settings', save_as=True, no_window=True)
|
||||
window.SaveToDisk(filename)
|
||||
# save(values)
|
||||
elif event == 'LoadSettings':
|
||||
filename = sg.PopupGetFile('Load Settings', no_window=True)
|
||||
filename = sg.popup_get_file('Load Settings', no_window=True)
|
||||
window.LoadFromDisk(filename)
|
||||
# load(form)
|
||||
elif event in ('Exit', None):
|
||||
break
|
||||
|
||||
# window.CloseNonBlocking()
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
Everything()
|
||||
main()
|
||||
|
|
|
@ -1,28 +1,34 @@
|
|||
import PySimpleGUI as sg
|
||||
import sys
|
||||
|
||||
button_names = ('close', 'cookbook', 'cpu', 'github', 'pysimplegui', 'run', 'storage', 'timer')
|
||||
|
||||
house64='iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAHPklEQVRYhbVXbUxb1xl+zjn30/a9/gBsbBwCBhPAUD4W2pClSZM0TemkdZPaSf0RTfszTZv2o1qzqmqiaL82salSqzZptVVqqmRV1dEssERKxJKxLAWajEYkAcxXyoBg4xgcY8AY23c/+EgwNiTRdqTz557zPOd5n/Oe95wLPGFzOp24fPp0yeTJk4cbjxzJelIe9qTA5uPHt7mHho6HOzsP1RQUWODxnO/o6Pj/C3A6naT5/ffLC9raWqZbW2v8t29GEz7/d3dXVuY56us7W69cmX1EHqaqKn1sAWffe6+ipK/vROjChaq+WNj/r2wWN44FEvAHamtcLhtfW3uuo7NT24xHVVUKPIYDzrw80vzuu1WuixdbQufPV3SJC747VcxUWC1ZvtFoRPX6tMX+wR27PJ6CLbt3d3zV1WWy2+0HZVn2APAkEgmPKIqeeDzeAwDhcFgLh8MaeVQB//j445qSrq4TU2fO1HlF+L07BGN5hVmXnWXG4PA4+q/OTVb1RwSjwSRZGxqaLm3deq7z+vU/B4NBjIyMwOfzQVEU+Hw+AgD19fUCAGwqwJmXR08dO1brampqjly7Zuu26/3j35GNNdutOqvVAV4QEA6H0D8wgr7u6OS29oCgSxCj7eWXvyB7snLjCDwLAiSTSe3YB20/avv3aNPD/NxmAk4dPbq9pLX1w3BHh23IrPMH6lW1vMyks+XmQxBEAIDRlI2iIoATJqw9kaS/sDt4P3b27A90d2yJql83EMIzxGILcYGniVT+jAKcDgc99dZbT7tOnGgO9/dn9RZb/f5nzeo2t1lPIGM6GAUlUbBlDxl4WA1GcAcEW2+27LddGiXz7cPqrd9fROXPDkC2GMAYv8q/sgUZBZw6fLi+5PPPj0d6e7NHnNm+qX1Wtdht0muLAj7rVhB0fR81VgLc/AKXTK/ioIuHe/5LFG6NgeMmbTdn4r6szrvM195vIAkN24+8AkYfLNfe3h5bEp4aud3Omo8e3eVubPzrgtdb4PU4fYHvbVFLn3LobblOxKJJdMyWwPXiL/F8XQV6brQjWv8r1D9VBvdsJ7Jy9JBlCXorMYyJmsBGZjA74ENo0IeEq7T5Srf3FrBBHWh5++09ZZ9+eiI2MpL/baHdH/yhS813Z+lzrHmQJD1mQrNIjvXBEf4G/NAFZEXvYCfrRtn9v0MI3oZozYUo6cDxFIZsEWOLiLDAQnR+2Cd7bPkm8759Z77u6oqtqwNOu51refPNvaWNjWcWx8edAzUu3/QrJWphuV2fk+OEJCsglGFuZhYtoTJ0lh2BuXwvvvrPLD6SfwHOtReFiUEYFApKOciyAlEUoOZJwj2zMq0N309GbvWU1VosTxcfOPB1y+XLgXA4rK0K+Nsbbzxfefr0B/GJCceoy+EPveZRHEUWgyXLAUlWQAkDIQxzMzO4Iz+Dssrt2FkkYnzgNsxFz+ClIh7ucBsgLM2jlFtyggKKhTP4CD+FiYg26x1wlypKhfm555qv3bgRZc7cXP7c668frHznnb/EJybsQ3Vuf/hQteIssRnMFgcknRGEstWemI0gSXR4oWARXHQEJVNXUesQ4Ex8C8PkNSQU0+pcSjmIsgJe4GByykooxzgd9wYQ6ekrrTEa64v377/OXqiutv387t0/LHq928bcW3wzP9mu5BRY9EazDZLOuBr5SudFEYViAPpIP5RwP7IMGrIXvJAjXkDgoEnGNfMp5SCIOhCahDFHNAQ5YSoxGsLcwFDRnoaGEDcej09M7NrVNDo+VBR8tcJcVmzT6/QWyDpT2uPJ61RAp0IDoAFIpowTkHX1lTEeJrMTjPlRup/Y2+ZjI4XDscG7VmszAYAd5eXGaHCi7seH6n7TsK9ip6LawPO6tAI+OfklAvem0o4BwEsv7oHH404zoiESnsS9YAD+hfzjv/vtJ38cDoZ6OQDo6Om5D6D1NY3+lOMFUMaDPlS1Hm6Dff2IT42D0vVjszEgUFedEct4AYwTUOyqvnm1b+AGkFIJCWVLi9Olnq7xjEAQCWiaayyhLXOkxWqgjANlHAh5AF4jgFIGxjhQxoNkiIJjFJLIAWStAgJgUUsuJV8GLGU82EYCVqhWsjddY5RCFrjU9UEIEI1vhNWWEjQ1oHSLEMqBMCG9AEZhkLl1W0AAROPxzFhNA8j6xMkgYGMHjBIPgaWQEWBuESCEpsdq2hrrNxGQ2QGOMQgcA5ey/j99KtR44H/hwOY5oOpEiPxash1kAdMzfEYHNE0D8KhbwLiNTwFPwLO1L+98I0FykS47sB5LNDziFhAsO5DpKFHIAoOQ8pIgBJB4BkJpWqz2OElIM0QBLOWAQeIgpiAJAFlkICSTA4+RhNjAAUYpZJGDlLIFhBBIPIOWoRI+hgNk+T7P8F4lFJIkQxHXk0nCIuYJTYsl0ECWk5DQB8/zTf8LUluScAguUG0mvv73bz6exuOHJKwUwg8/+lNk5et/AVSZbsni/k4yAAAAAElFTkSuQmCC'
|
||||
|
||||
cpu64='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'
|
||||
|
||||
timer64='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'
|
||||
'''
|
||||
Example of borderless floating toolbar.
|
||||
'''
|
||||
|
||||
button_names = ('close', 'cookbook', 'cpu', 'github',
|
||||
'pysimplegui', 'run', 'storage', 'timer')
|
||||
house64 = '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'
|
||||
cpu64 = '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'
|
||||
timer64 = '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'
|
||||
close64 = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEQ0lEQVR42r2XW2wbRRSG/1177TgkdkyoS4shaaWogVIKRAXUVn4BgRBEIRBSkSK1lAakPhTxABJSK6BEtAoXCUHEWwWi4oEXUAVvRUASSBuJliAh5QJp6hrspoGQi69r73LO7Npu6kvsBGek0ezOrvf79szsmbG0D2iwAN8DaMQaFA0YHQFaLwCX6TQuHQAuNtjR2PawD05LZeFzKeC7b/txPoLxU8Aj1BVkAf1wqw/uejeU9RsASaqYQGp+Dv8EAvjgdD9OAg9S14gQOPKED1XNWyv7+lT0VArxiVH0fCUEOqjr3JoKcImN/pYW2EOnQyUJTESBJkdpgGkV8Cj/owDDdx59A8Mf92FT+GpR+KSlBrt6ehE6+hL0pLp6AYbvfusE5FontFgUZ989UVAiDU+X0OsvQ0/EVy4g4MeOQ3a6Mn38wKHet3MkrofzZJMsFlzpeRVaeLF8ASPsb8Javy7nDXRVxdA7x7FpIZQXnrlP0yDJMoKvHVpZBKq23Qv3M8/nzQt6PIah93qhRxaLwvPNhbLmgGP7Drg694mHlVqKwcsWEBItD8DVvleM6WrhRQXUwBSsnpthvclDY++BZLdnflS9YxecrZ2QFGVZePDIYcq5yWuGK47k39NIzlCdDkHxNuYXiJzrz/xIrr4BFpdbfAFyTS1CSi1uf7IDrqeeheyoLihxubsD2sI8UuEFaItUKfen5mahRcLZl7nft7xAvjIQs+GFP2cLCmjRCL5p3oDN6nzR56xIYDl4ORJlCwyqDnT7Z5aFL5G4w4vN8dnVCwymatA9daVkeCkSJQv8qDtxcDKYF86AwKEuSDYbvB+doq/DlnMPJ6uvmzfmSJQk0E9D+OLVcEG4f38bwgNnxLmz9Wl4+z6HZLXm3JuYHMfE7i0ri8Ck3Y3Hx4L0lvYl8Et7H0Xk7NJ7Xe1d8H74GX2/2YyZmv8XY3euo4SUXJkAFyvtEbdc+CsDn2r3Ifrrz3nHvW7Pftzy/kmxdhSCly2Qlmj66Xf88dB2qP6LRme+jauuo67rIDyvHMN4i1esmvlK6QIUTrEISbKxDnDlPkk2BK6VIDhXXaddP6Vk0H6A9wSUn0WKFn2lCgiYbDEmFVXJYjWOuU1LcHudgAASSLS0FnD4dV4TksYxNEOqsMDwgAAxELToSFZFfGaiVWzGNV6MWM4Uyc5OE8wQCr2AqwmxIuoJowX3k5CjZSd6vvxhqcBj921Fc2g8C2Mwzf5sax7zNZZjSdkcCg6/EEgacAYzlLZvRk1kW7rm39iELwZHsgLPATN311rqb7trG+65dT2FXTEg4o1NoDinZKOYQ8ICFo4ADwMJpEwBDrnKIU+YMqZQ0pAbC4QwODwCf0Rd/BQ4IATagM46oI+CeiNPPVS40EDF6M/pJ78Ap+n0PL8Cp7sGs9asgQSFDLxBmKJ6STKBVSbcZsa10gKcJHi/Hv0PWqbBbaFH/AEAAAAASUVORK5CYII='
|
||||
|
||||
|
||||
def main():
|
||||
btn_css = {
|
||||
'button_color': ('white', 'black'),
|
||||
'pad': (0, 0),
|
||||
}
|
||||
|
||||
toolbar_buttons = [[sg.Button('', image_data=close64,button_color=('white', 'black'), pad=(0,0), key='-CLOSE-'),
|
||||
sg.Button('', image_data=timer64, button_color=('white', 'black'), pad=(0, 0), key='-TIMER-'),
|
||||
sg.Button('', image_data=house64, button_color=('white', 'black'), pad=(0, 0), key='-HOUSE-'),
|
||||
sg.Button('', image_data=cpu64, button_color=('white', 'black'), pad=(0,0), key='-CPU-'),]]
|
||||
toolbar_buttons = [[sg.Button(image_data=close64, **btn_css, key='-CLOSE-'),
|
||||
sg.Button(image_data=timer64, **btn_css, key='-TIMER-'),
|
||||
sg.Button(image_data=house64, **btn_css, key='-HOUSE-'),
|
||||
sg.Button(image_data=cpu64, **btn_css, key='-CPU-'), ]]
|
||||
|
||||
# layout = toolbar_buttons
|
||||
layout = [[sg.Column( toolbar_buttons, background_color='black')]]
|
||||
layout = [[sg.Col(toolbar_buttons, background_color='black')]]
|
||||
|
||||
window = sg.Window('Toolbar', layout, no_titlebar=True, grab_anywhere=True, background_color='black', margins=(0,0))
|
||||
window = sg.Window('Toolbar', layout, no_titlebar=True,
|
||||
grab_anywhere=True, background_color='black', margins=(0, 0))
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
|
@ -31,14 +37,16 @@ def main():
|
|||
if button == '-CLOSE-' or button is None:
|
||||
break # exit button clicked
|
||||
elif button == '-TIMER-':
|
||||
print('Timer Button') # add your call to launch a timer program
|
||||
# add your call to launch a timer program
|
||||
print('Timer Button')
|
||||
elif button == '-CPU-':
|
||||
print('CPU Button') # add your call to launch a CPU measuring utility
|
||||
# add your call to launch a CPU measuring utility
|
||||
print('CPU Button')
|
||||
elif button == '-HOUSE-':
|
||||
print('Home Button')
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
from tkinter import font
|
||||
import tkinter
|
||||
root = tkinter.Tk()
|
||||
|
@ -12,38 +8,38 @@ fonts = list(font.families())
|
|||
fonts.sort()
|
||||
root.destroy()
|
||||
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
'''
|
||||
Showing fonts in PSG / tk
|
||||
'''
|
||||
|
||||
layout = [[ sg.Text('My Text Element',
|
||||
size=(20,1),
|
||||
auto_size_text=False,
|
||||
click_submits=True,
|
||||
relief=sg.RELIEF_GROOVE,
|
||||
font = 'Courier` 25',
|
||||
text_color='#FF0000',
|
||||
background_color='white',
|
||||
justification='center',
|
||||
pad=(5,3),
|
||||
key='_text_',
|
||||
tooltip='This is a text element',
|
||||
) ],
|
||||
[sg.Listbox(fonts, size=(30,20), change_submits=True, key='_list_')],
|
||||
[sg.Input(key='_in_')],
|
||||
[ sg.Button('Read', bind_return_key=True), sg.Exit()]]
|
||||
sg.change_look_and_feel('Black')
|
||||
|
||||
window = sg.Window('My new window',
|
||||
# grab_anywhere=True,
|
||||
# force_toplevel=True,
|
||||
).Layout(layout)
|
||||
layout = [[sg.Text('My Text Element',
|
||||
size=(20, 1),
|
||||
click_submits=True,
|
||||
relief=sg.RELIEF_GROOVE,
|
||||
font='Courier` 25',
|
||||
text_color='#FF0000',
|
||||
background_color='white',
|
||||
justification='center',
|
||||
pad=(5, 3),
|
||||
key='-text-',
|
||||
tooltip='This is a text element',
|
||||
)],
|
||||
[sg.Listbox(fonts, size=(30, 20), change_submits=True, key='-list-')],
|
||||
[sg.Input(key='-in-')],
|
||||
[sg.Button('Read', bind_return_key=True), sg.Exit()]]
|
||||
|
||||
window = sg.Window('My new window', layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
if event is None or event == 'Exit':
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
text_elem = window.FindElement('_text_')
|
||||
text_elem = window['-text-']
|
||||
print(event, values)
|
||||
if values['_in_'] != '':
|
||||
text_elem.Update(font=values['_in_'])
|
||||
if values['-in-'] != '':
|
||||
text_elem.update(font=values['-in-'])
|
||||
else:
|
||||
text_elem.Update(font=(values['_list_'][0], 25))
|
||||
text_elem.update(font=(values['-list-'][0], 25))
|
||||
window.close()
|
||||
|
|
|
@ -1,30 +1,34 @@
|
|||
import PySimpleGUI as sg
|
||||
|
||||
# Testing async form, see if can have a slider
|
||||
# that adjusts the size of text displayed
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
fontSize = 12
|
||||
layout = [[sg.Spin([sz for sz in range(6, 172)], font=('Helvetica 20'), initial_value=fontSize, change_submits=True, key='spin'),
|
||||
sg.Slider(range=(6,172), orientation='h', size=(10,20), change_submits=True, key='slider', font=('Helvetica 20')), sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontSize), key='text')]]
|
||||
layout = [
|
||||
[sg.Spin([sz for sz in range(6, 172)],
|
||||
font=('Helvetica 20'),
|
||||
initial_value=fontSize,
|
||||
change_submits=True, key='spin'),
|
||||
sg.Slider(range=(6, 172), orientation='h', size=(10, 20), change_submits=True, key='slider',
|
||||
font=('Helvetica 20')),
|
||||
sg.Text("Aa", size=(2, 1), font="Helvetica " + str(fontSize), key='text')]
|
||||
]
|
||||
sz = fontSize
|
||||
window = sg.Window("Font size selector", grab_anywhere=False)
|
||||
window.Layout(layout)
|
||||
window = sg.Window("Font size selector", layout, grab_anywhere=False)
|
||||
while True:
|
||||
event, values= window.Read()
|
||||
event, values = window.read()
|
||||
if event is None or event == 'Quit':
|
||||
break
|
||||
sz_spin = int(values['spin'])
|
||||
sz_slider = int(values['slider'])
|
||||
|
||||
sz = sz_spin if sz_spin != fontSize else sz_slider
|
||||
|
||||
if sz != fontSize:
|
||||
fontSize = sz
|
||||
font = "Helvetica " + str(fontSize)
|
||||
window.FindElement('text').Update(font=font)
|
||||
window.FindElement('slider').Update(sz)
|
||||
window.FindElement('spin').Update(sz)
|
||||
window['text'].update(font=font)
|
||||
window['slider'].update(sz)
|
||||
window['spin'].update(sz)
|
||||
|
||||
print("Done.")
|
||||
window.close()
|
||||
|
|
|
@ -1,34 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[sg.Text('This is my sample text',size=(20,1), key='_text_') ],
|
||||
[sg.CB('Bold', key='_bold_', change_submits=True),
|
||||
sg.CB('Italics', key='_italics_', change_submits=True),
|
||||
sg.CB('Underline', key='_underline_', change_submits=True)],
|
||||
[sg.Slider((6,50), default_value=12, size=(14,20), orientation='h', key='_slider_', change_submits=True),
|
||||
'''
|
||||
App that shows "how fonts work in PySimpleGUI".
|
||||
'''
|
||||
|
||||
layout = [[sg.Text('This is my sample text', size=(20, 1), key='-text-')],
|
||||
[sg.CB('Bold', key='-bold-', change_submits=True),
|
||||
sg.CB('Italics', key='-italics-', change_submits=True),
|
||||
sg.CB('Underline', key='-underline-', change_submits=True)],
|
||||
[sg.Slider((6, 50), default_value=12, size=(14, 20),
|
||||
orientation='h', key='-slider-', change_submits=True),
|
||||
sg.Text('Font size')],
|
||||
[sg.Text('Font string = '), sg.Text('', size=(25,1), key='_fontstring_')],
|
||||
[ sg.Button('Exit')]]
|
||||
[sg.Text('Font string = '), sg.Text('', size=(25, 1), key='-fontstring-')],
|
||||
[sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Font string builder').Layout(layout)
|
||||
window = sg.Window('Font string builder', layout)
|
||||
|
||||
text_elem = window.FindElement('_text_')
|
||||
text_elem = window['-text-']
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
font_string = 'Helvitica '
|
||||
font_string += str(values['_slider_'])
|
||||
if values['_bold_']:
|
||||
font_string += str(values['-slider-'])
|
||||
if values['-bold-']:
|
||||
font_string += ' bold'
|
||||
if values['_italics_']:
|
||||
if values['-italics-']:
|
||||
font_string += ' italic'
|
||||
if values['_underline_']:
|
||||
if values['-underline-']:
|
||||
font_string += ' underline'
|
||||
text_elem.Update(font=font_string)
|
||||
window.FindElement('_fontstring_').Update('"'+font_string+'"')
|
||||
text_elem.update(font=int(font_string.split(' ')[1].split('.')[0]))
|
||||
window['-fontstring-'].update('"'+font_string+'"')
|
||||
print(event, values)
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,53 +1,58 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# Example of colors in PSG
|
||||
|
||||
def main():
|
||||
# ------- Make a new Window ------- #
|
||||
window = sg.Window('GoodColors', auto_size_text=True, default_element_size=(30,2))
|
||||
window.AddRow(sg.Text('Having trouble picking good colors? Try one of the colors defined by PySimpleGUI'))
|
||||
window = sg.Window('GoodColors', default_element_size=(30, 2))
|
||||
window.AddRow(sg.Text('Having trouble picking good colors? Try this'))
|
||||
window.AddRow(sg.Text('Here come the good colors as defined by PySimpleGUI'))
|
||||
|
||||
#===== Show some nice BLUE colors with yellow text ===== ===== ===== ===== ===== ===== =====#
|
||||
text_color = sg.YELLOWS[0]
|
||||
buttons = (sg.Button('BLUES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.BLUES))
|
||||
window.AddRow(sg.T('Button Colors Using PySimpleGUI.BLUES'))
|
||||
buttons = (sg.Button('BLUES[{}]\n{}'.format(j, c), button_color=(
|
||||
text_color, c), size=(10, 2)) for j, c in enumerate(sg.BLUES))
|
||||
window.AddRow(sg.Text('Button Colors Using PySimpleGUI.BLUES'))
|
||||
window.AddRow(*buttons)
|
||||
window.AddRow(sg.Text('_' * 100, size=(65, 1)))
|
||||
|
||||
#===== Show some nice PURPLE colors with yellow text ===== ===== ===== ===== ===== ===== =====#
|
||||
buttons = (sg.Button('PURPLES[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.PURPLES))
|
||||
window.AddRow(sg.T('Button Colors Using PySimpleGUI.PURPLES'))
|
||||
buttons = (sg.Button('PURPLES[{}]\n{}'.format(j, c), button_color=(
|
||||
text_color, c), size=(10, 2)) for j, c in enumerate(sg.PURPLES))
|
||||
window.AddRow(sg.Text('Button Colors Using PySimpleGUI.PURPLES'))
|
||||
window.AddRow(*buttons)
|
||||
window.AddRow(sg.Text('_' * 100, size=(65, 1)))
|
||||
|
||||
#===== Show some nice GREEN colors with yellow text ===== ===== ===== ===== ===== ===== =====#
|
||||
buttons = (sg.Button('GREENS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.GREENS))
|
||||
window.AddRow(sg.T('Button Colors Using PySimpleGUI.GREENS'))
|
||||
buttons = (sg.Button('GREENS[{}]\n{}'.format(j, c), button_color=(
|
||||
text_color, c), size=(10, 2)) for j, c in enumerate(sg.GREENS))
|
||||
window.AddRow(sg.Text('Button Colors Using PySimpleGUI.GREENS'))
|
||||
window.AddRow(*buttons)
|
||||
window.AddRow(sg.Text('_' * 100, size=(65, 1)))
|
||||
|
||||
#===== Show some nice TAN colors with yellow text ===== ===== ===== ===== ===== ===== =====#
|
||||
text_color = sg.GREENS[0] # let's use GREEN text on the tan
|
||||
buttons = (sg.Button('TANS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.TANS))
|
||||
window.AddRow(sg.T('Button Colors Using PySimpleGUI.TANS'))
|
||||
buttons = (sg.Button('TANS[{}]\n{}'.format(j, c), button_color=(
|
||||
text_color, c), size=(10, 2)) for j, c in enumerate(sg.TANS))
|
||||
window.AddRow(sg.Text('Button Colors Using PySimpleGUI.TANS'))
|
||||
window.AddRow(*buttons)
|
||||
window.AddRow(sg.Text('_' * 100, size=(65, 1)))
|
||||
|
||||
#===== Show some nice YELLOWS colors with black text ===== ===== ===== ===== ===== ===== =====#
|
||||
text_color = 'black' # let's use black text on the tan
|
||||
buttons = (sg.Button('YELLOWS[{}]\n{}'.format(j, c), button_color=(text_color, c), size=(10,2)) for j, c in enumerate(sg.YELLOWS))
|
||||
window.AddRow(sg.T('Button Colors Using PySimpleGUI.YELLOWS'))
|
||||
buttons = (sg.Button('YELLOWS[{}]\n{}'.format(j, c), button_color=(
|
||||
text_color, c), size=(10, 2)) for j, c in enumerate(sg.YELLOWS))
|
||||
window.AddRow(sg.Text('Button Colors Using PySimpleGUI.YELLOWS'))
|
||||
window.AddRow(*buttons)
|
||||
window.AddRow(sg.Text('_' * 100, size=(65, 1)))
|
||||
|
||||
|
||||
#===== Add a click me button for fun and SHOW the window ===== ===== ===== ===== ===== ===== =====#
|
||||
window.AddRow(sg.Button('Click ME!'))
|
||||
event, values = window.Read() # show it!
|
||||
event, values = window.read()
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
48
DemoPrograms/Demo_GoodColors_2.py
Normal file
48
DemoPrograms/Demo_GoodColors_2.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python
|
||||
import PySimpleGUI as sg
|
||||
|
||||
'''
|
||||
Example of colors in PySimpleGUI
|
||||
'''
|
||||
|
||||
def main():
|
||||
s10 = (10, 2)
|
||||
|
||||
window = sg.Window('GoodColors', [
|
||||
[sg.Text('Having trouble picking good colors? Try this')],
|
||||
[sg.Text('Here come the good colors as defined by PySimpleGUI')],
|
||||
[sg.Text('Button Colors Using PySimpleGUI.BLUES')],
|
||||
|
||||
[*[sg.Button('BLUES[{}]\n{}'.format(j, c), button_color=(sg.YELLOWS[0], c), size=s10)
|
||||
for j, c in enumerate(sg.BLUES)]],
|
||||
[sg.Text('_' * 100, size=(65, 1))],
|
||||
[sg.Text('Button Colors Using PySimpleGUI.PURPLES')],
|
||||
|
||||
[*[sg.Button('PURPLES[{}]\n{}'.format(j, c), button_color=(sg.YELLOWS[0], c), size=s10)
|
||||
for j, c in enumerate(sg.PURPLES)]],
|
||||
[sg.Text('_' * 100, size=(65, 1))],
|
||||
[sg.Text('Button Colors Using PySimpleGUI.GREENS')],
|
||||
|
||||
[*[sg.Button('GREENS[{}]\n{}'.format(j, c), button_color=(sg.YELLOWS[0], c), size=s10)
|
||||
for j, c in enumerate(sg.GREENS)]],
|
||||
[sg.Text('_' * 100, size=(65, 1))],
|
||||
[sg.Text('Button Colors Using PySimpleGUI.TANS')],
|
||||
|
||||
[*[sg.Button('TANS[{}]\n{}'.format(j, c), button_color=(sg.GREENS[0], c), size=s10)
|
||||
for j, c in enumerate(sg.TANS)]],
|
||||
[sg.Text('_' * 100, size=(65, 1))],
|
||||
[sg.Text('Button Colors Using PySimpleGUI.YELLOWS')],
|
||||
|
||||
[*[sg.Button('YELLOWS[{}]\n{}'.format(j, c), button_color=('black', c), size=s10)
|
||||
for j, c in enumerate(sg.YELLOWS)]],
|
||||
|
||||
[sg.Text('_' * 100, size=(65, 1))],
|
||||
[sg.Button('Click ME!')]
|
||||
], default_element_size=(30, 2))
|
||||
|
||||
event, values = window.read()
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,9 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
from gtts import gTTS
|
||||
from pygame import mixer
|
||||
import time
|
||||
|
@ -19,16 +15,16 @@ import os
|
|||
'''
|
||||
|
||||
layout = [[sg.Text('What would you like me to say?')],
|
||||
[sg.Multiline(size=(60,10), enter_submits=True)],
|
||||
[sg.MLine(size=(60,10), enter_submits=True)],
|
||||
[sg.Button('Speak', bind_return_key=True), sg.Exit()]]
|
||||
|
||||
window = sg.Window('Google Text to Speech').Layout(layout)
|
||||
window = sg.Window('Google Text to Speech', layout)
|
||||
|
||||
i = 0
|
||||
mixer.init()
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
if event is None or event == 'Exit':
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
# Get the text and convert to mp3 file
|
||||
tts = gTTS(text=values[0], lang='en',slow=False)
|
||||
|
@ -42,6 +38,8 @@ while True:
|
|||
mixer.stop()
|
||||
i += 1
|
||||
|
||||
window.close()
|
||||
|
||||
# try to remove the temp files. You'll likely be left with 1 to clean up
|
||||
try:
|
||||
os.remove('speech0.mp3')
|
||||
|
|
|
@ -10,21 +10,24 @@ import socket
|
|||
Note this exact same demo runs with PySimpleGUIWeb by changing the import statement
|
||||
"""
|
||||
|
||||
|
||||
class Ball():
|
||||
def __init__(self, x, y, r, graph_elem, *args, **kwargs):
|
||||
mass = 10
|
||||
self.body = pymunk.Body(mass,
|
||||
pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment
|
||||
# Create a Body with mass and moment
|
||||
self.body = pymunk.Body(
|
||||
mass, pymunk.moment_for_circle(mass, 0, r, (0, 0)))
|
||||
self.body.position = x, y
|
||||
self.shape = pymunk.Circle(self.body, r, offset=(0, 0)) # Create a box shape and attach to body
|
||||
# Create a box shape and attach to body
|
||||
self.shape = pymunk.Circle(self.body, r, offset=(0, 0))
|
||||
self.shape.elasticity = 0.99999
|
||||
self.shape.friction = 0.8
|
||||
self.gui_circle_figure = None
|
||||
self.graph_elem = graph_elem
|
||||
|
||||
def move(self):
|
||||
self.graph_elem.RelocateFigure(self.gui_circle_figure, self.body.position[0], ball.body.position[1])
|
||||
|
||||
self.graph_elem.RelocateFigure(
|
||||
self.gui_circle_figure, self.body.position[0], ball.body.position[1])
|
||||
|
||||
|
||||
class Playfield():
|
||||
|
@ -37,9 +40,8 @@ class Playfield():
|
|||
self.arena_balls = [] # type: [] Ball
|
||||
self.graph_elem = graph_elem # type: sg.Graph
|
||||
|
||||
|
||||
def add_wall(self, pt_from, pt_to):
|
||||
body = pymunk.Body(body_type=pymunk.Body.STATIC)
|
||||
body = pymunk.Body(body_type=pymunk.Body.STATIC)
|
||||
ground_shape = pymunk.Segment(body, pt_from, pt_to, 0.0)
|
||||
ground_shape.friction = 0.8
|
||||
ground_shape.elasticity = .99
|
||||
|
@ -50,26 +52,35 @@ class Playfield():
|
|||
x = random.randint(0, 600)
|
||||
y = random.randint(0, 400)
|
||||
r = random.randint(1, 10)
|
||||
self.add_ball(x,y,r)
|
||||
self.add_ball(x, y, r)
|
||||
|
||||
def add_ball(self, x, y, r, fill_color='black', line_color='red'):
|
||||
ball = Ball(x, y, r, self.graph_elem)
|
||||
self.arena_balls.append(ball)
|
||||
area.space.add(ball.body, ball.shape)
|
||||
ball.gui_circle_figure = self.graph_elem.DrawCircle((x, y), r, fill_color=fill_color, line_color=line_color)
|
||||
ball.gui_circle_figure = self.graph_elem.draw_circle(
|
||||
(x, y), r, fill_color=fill_color, line_color=line_color)
|
||||
return ball
|
||||
|
||||
def shoot_a_ball(self, x, y, r, vector=(-10, 0), fill_color='black', line_color='red'):
|
||||
ball = self.add_ball(x,y,r, fill_color=fill_color, line_color=line_color )
|
||||
ball = self.add_ball(
|
||||
x, y, r, fill_color=fill_color, line_color=line_color)
|
||||
# ball.shape.surface_velocity=10
|
||||
ball.body.apply_impulse_at_local_point(100*pymunk.Vec2d(vector))
|
||||
|
||||
# ------------------- Build and show the GUI Window -------------------
|
||||
graph_elem = sg.Graph((600, 400), (0, 400), (600, 0), enable_events=True, key='_GRAPH_', background_color='lightblue')
|
||||
|
||||
layout = [[sg.Text('Ball Test'), sg.T('My IP {}'.format(socket.gethostbyname(socket.gethostname())))],
|
||||
# ------------------- Build and show the GUI Window -------------------
|
||||
graph_elem = sg.Graph((600, 400), (0, 400), (600, 0),
|
||||
enable_events=True,
|
||||
key='-GRAPH-',
|
||||
background_color='lightblue')
|
||||
|
||||
hostname = socket.gethostbyname(socket.gethostname())
|
||||
layout = [[sg.Text('Ball Test'), sg.Text('My IP {}'.format(hostname))],
|
||||
[graph_elem],
|
||||
[sg.B('Kick'), sg.B('Player 1 Shoot', size=(15,2)),sg.B('Player 2 Shoot', size=(15,2)), sg.Button('Exit')]]
|
||||
[sg.Button('Kick'), sg.Button('Player 1 Shoot', size=(15, 2)),
|
||||
sg.Button('Player 2 Shoot', size=(15, 2)), sg.Button('Exit')]
|
||||
]
|
||||
|
||||
window = sg.Window('Window Title', layout, disable_close=True)
|
||||
|
||||
|
@ -78,20 +89,23 @@ area = Playfield(graph_elem)
|
|||
|
||||
# ------------------- GUI Event Loop -------------------
|
||||
while True: # Event Loop
|
||||
event, values = window.Read(timeout=10)
|
||||
event, values = window.read(timeout=10)
|
||||
# print(event, values)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
area.space.step(0.01)
|
||||
|
||||
if event == 'Player 2 Shoot':
|
||||
area.shoot_a_ball(555, 200, 5, (-10,0), fill_color='green', line_color='green')
|
||||
area.shoot_a_ball(555, 200, 5, (-10, 0),
|
||||
fill_color='green', line_color='green')
|
||||
elif event == 'Player 1 Shoot':
|
||||
area.shoot_a_ball(10, 200, 5, (10,0))
|
||||
area.shoot_a_ball(10, 200, 5, (10, 0))
|
||||
|
||||
for ball in area.arena_balls:
|
||||
if event == 'Kick':
|
||||
ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(1,200)
|
||||
pos = ball.body.position[0], ball.body.position[1]-random.randint(1, 200)
|
||||
ball.body.position = pos
|
||||
ball.move()
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -19,20 +19,22 @@ layout = [[sg.Graph(
|
|||
key="-GRAPH-",
|
||||
change_submits=True, # mouse click events
|
||||
drag_submits=True),],
|
||||
[sg.Text("", key="info", size=(60, 1))]]
|
||||
[sg.Text(key='info', size=(60, 1))]]
|
||||
|
||||
window = sg.Window("draw rect on image", layout, finalize=True)
|
||||
# get the graph element for ease of use later
|
||||
graph = window["-GRAPH-"] # type: sg.Graph
|
||||
|
||||
graph.DrawImage(image_file, location=(0,0)) if image_file else None
|
||||
graph.draw_image(image_file, location=(0,0)) if image_file else None
|
||||
dragging = False
|
||||
start_point = end_point = prior_rect = None
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
if event is None:
|
||||
break # exit
|
||||
|
||||
if event == "-GRAPH-": # if there's a "Graph" event, then it's a mouse
|
||||
x, y = values["-GRAPH-"]
|
||||
if not dragging:
|
||||
|
@ -41,13 +43,15 @@ while True:
|
|||
else:
|
||||
end_point = (x, y)
|
||||
if prior_rect:
|
||||
graph.DeleteFigure(prior_rect)
|
||||
graph.delete_figure(prior_rect)
|
||||
if None not in (start_point, end_point):
|
||||
prior_rect = graph.DrawRectangle(start_point, end_point, line_color='red')
|
||||
prior_rect = graph.draw_rectangle(start_point, end_point, line_color='red')
|
||||
|
||||
elif event.endswith('+UP'): # The drawing has ended because mouse up
|
||||
info = window.Element("info")
|
||||
info.Update(value=f"grabbed rectangle from {start_point} to {end_point}")
|
||||
info = window["info"]
|
||||
info.update(value=f"grabbed rectangle from {start_point} to {end_point}")
|
||||
start_point, end_point = None, None # enable grabbing a new rect
|
||||
dragging = False
|
||||
|
||||
else:
|
||||
print("unhandled event", event, values)
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(0,0), graph_top_right=(400, 400), background_color='red', key='graph')],
|
||||
[sg.T('Change circle color to:'), sg.Button('Red'), sg.Button('Blue'), sg.Button('Move')]]
|
||||
# Usage of Graph element.
|
||||
|
||||
window = sg.Window('Graph test').Layout(layout).Finalize()
|
||||
layout = [[sg.Graph(canvas_size=(400, 400), graph_bottom_left=(0, 0), graph_top_right=(400, 400), background_color='red', key='graph')],
|
||||
[sg.Text('Change circle color to:'), sg.Button('Red'), sg.Button('Blue'), sg.Button('Move')]]
|
||||
|
||||
graph = window.FindElement('graph')
|
||||
circle =graph .DrawCircle((75,75), 25, fill_color='black',line_color='white')
|
||||
point = graph.DrawPoint((75,75), 10, color='green')
|
||||
oval = graph.DrawOval((25,300), (100,280), fill_color='purple', line_color='purple' )
|
||||
rectangle = graph.DrawRectangle((25,300), (100,280), line_color='purple' )
|
||||
line = graph.DrawLine((0,0), (100,100))
|
||||
arc = graph.DrawArc((0,0), (400,400), 160, 10, style='arc' ,arc_color='blue')
|
||||
window = sg.Window('Graph test', layout, finalize=True)
|
||||
|
||||
graph = window['graph']
|
||||
circle = graph.draw_circle((75, 75), 25, fill_color='black', line_color='white')
|
||||
point = graph.draw_point((75, 75), 10, color='green')
|
||||
oval = graph.draw_oval((25, 300), (100, 280), fill_color='purple', line_color='purple')
|
||||
rectangle = graph.draw_rectangle((25, 300), (100, 280), line_color='purple')
|
||||
line = graph.draw_line((0, 0), (100, 100))
|
||||
arc = graph.draw_arc((0, 0), (400, 400), 160, 10, style='arc', arc_color='blue')
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event is None:
|
||||
break
|
||||
if event in ('Blue', 'Red'):
|
||||
graph.TKCanvas.itemconfig(circle, fill=event)
|
||||
elif event == 'Move':
|
||||
graph.MoveFigure(point, 10,10)
|
||||
graph.MoveFigure(circle, 10,10)
|
||||
graph.MoveFigure(oval, 10,10)
|
||||
graph.MoveFigure(rectangle, 10,10)
|
||||
graph.MoveFigure(arc, 10,10)
|
||||
graph.MoveFigure(point, 10, 10)
|
||||
graph.MoveFigure(circle, 10, 10)
|
||||
graph.MoveFigure(oval, 10, 10)
|
||||
graph.MoveFigure(rectangle, 10, 10)
|
||||
graph.MoveFigure(arc, 10, 10)
|
||||
|
||||
window.close()
|
|
@ -1,27 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
import ping
|
||||
from threading import Thread
|
||||
import time
|
||||
|
||||
|
||||
STEP_SIZE=1
|
||||
STEP_SIZE = 1
|
||||
SAMPLES = 1000
|
||||
CANVAS_SIZE = (1000,500)
|
||||
CANVAS_SIZE = (1000, 500)
|
||||
|
||||
# globale used to communicate with thread.. yea yea... it's working fine
|
||||
g_exit = False
|
||||
g_response_time = None
|
||||
|
||||
|
||||
def ping_thread(args):
|
||||
global g_exit, g_response_time
|
||||
while not g_exit:
|
||||
g_response_time = ping.quiet_ping('google.com', timeout=1000)
|
||||
|
||||
|
||||
def main():
|
||||
global g_exit, g_response_time
|
||||
|
||||
|
@ -29,21 +27,27 @@ def main():
|
|||
thread = Thread(target=ping_thread, args=(None,))
|
||||
thread.start()
|
||||
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.SetOptions(element_padding=(0,0))
|
||||
sg.change_look_and_feel('Black')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [ [sg.T('Ping times to Google.com', font='Any 12'), sg.Quit(pad=((100,0), 0), button_color=('white', 'black'))],
|
||||
[sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,500),background_color='black', key='graph')],]
|
||||
layout = [
|
||||
[sg.Text('Ping times to Google.com', font='Any 12'),
|
||||
sg.Quit(pad=((100, 0), 0), button_color=('white', 'black'))],
|
||||
[sg.Graph(CANVAS_SIZE, (0, 0), (SAMPLES, 500),
|
||||
background_color='black', key='graph')]
|
||||
]
|
||||
|
||||
window = sg.Window('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False).Layout(layout)
|
||||
|
||||
graph = window.FindElement('graph')
|
||||
window = sg.Window('Canvas test', layout,
|
||||
grab_anywhere=True, background_color='black',
|
||||
no_titlebar=False, use_default_focus=False)
|
||||
|
||||
graph = window['graph']
|
||||
prev_response_time = None
|
||||
i=0
|
||||
prev_x, prev_y = 0, 0
|
||||
i = 0
|
||||
prev_x, prev_y = 0, 0
|
||||
|
||||
while True:
|
||||
event, values = window.Read(timeout=200)
|
||||
event, values = window.read(timeout=200)
|
||||
if event == 'Quit' or event is None:
|
||||
break
|
||||
if g_response_time is None or prev_response_time == g_response_time:
|
||||
|
@ -51,10 +55,10 @@ def main():
|
|||
new_x, new_y = i, g_response_time[0]
|
||||
prev_response_time = g_response_time
|
||||
if i >= SAMPLES:
|
||||
graph.Move(-STEP_SIZE,0)
|
||||
graph.move(-STEP_SIZE, 0)
|
||||
prev_x = prev_x - STEP_SIZE
|
||||
graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
# window.FindElement('graph').DrawPoint((new_x, new_y), color='red')
|
||||
graph.draw_line((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
# window['graph'].draw_point((new_x, new_y), color='red')
|
||||
prev_x, prev_y = new_x, new_y
|
||||
i += STEP_SIZE if i < SAMPLES else 0
|
||||
|
||||
|
@ -62,6 +66,8 @@ def main():
|
|||
g_exit = True
|
||||
thread.join()
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
import random
|
||||
|
||||
BAR_WIDTH = 50
|
||||
BAR_SPACING = 75
|
||||
EDGE_OFFSET = 3
|
||||
GRAPH_SIZE = (500,500)
|
||||
DATA_SIZE = (500,500)
|
||||
|
||||
graph = sg.Graph(GRAPH_SIZE, (0,0), DATA_SIZE)
|
||||
|
||||
layout = [[sg.Text('Bar graphs using PySimpleGUI')],
|
||||
[graph],
|
||||
[sg.Button('OK')]]
|
||||
|
||||
window = sg.Window('Window Title', layout)
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
graph.Erase()
|
||||
if event is None:
|
||||
break
|
||||
|
||||
for i in range(7):
|
||||
graph_value = random.randint(0, 400)
|
||||
graph.DrawRectangle(top_left=(i * BAR_SPACING + EDGE_OFFSET, graph_value),
|
||||
bottom_right=(i * BAR_SPACING + EDGE_OFFSET + BAR_WIDTH, 0), fill_color='blue')
|
||||
graph.DrawText(text=graph_value, location=(i*BAR_SPACING+EDGE_OFFSET+25, graph_value+10))
|
||||
window.Close()
|
|
@ -1,38 +1,42 @@
|
|||
# import PySimpleGUIWeb as sg
|
||||
# import PySimpleGUIQt as sg
|
||||
import PySimpleGUI as sg
|
||||
import math
|
||||
|
||||
# Yet another usage of Graph element.
|
||||
|
||||
SIZE_X = 200
|
||||
SIZE_Y = 100
|
||||
NUMBER_MARKER_FREQUENCY = 25
|
||||
|
||||
|
||||
def draw_axis():
|
||||
graph.draw_line((-SIZE_X,0), (SIZE_X, 0)) # axis lines
|
||||
graph.draw_line((0,-SIZE_Y), (0,SIZE_Y))
|
||||
graph.draw_line((-SIZE_X, 0), (SIZE_X, 0)) # axis lines
|
||||
graph.draw_line((0, -SIZE_Y), (0, SIZE_Y))
|
||||
|
||||
for x in range(-SIZE_X, SIZE_X+1, NUMBER_MARKER_FREQUENCY):
|
||||
graph.draw_line((x,-3), (x,3)) # tick marks
|
||||
graph.draw_line((x, -3), (x, 3)) # tick marks
|
||||
if x != 0:
|
||||
graph.draw_text( str(x), (x,-10), color='green', font='Algerian 15') # numeric labels
|
||||
# numeric labels
|
||||
graph.draw_text(str(x), (x, -10), color='green')
|
||||
|
||||
for y in range(-SIZE_Y, SIZE_Y+1, NUMBER_MARKER_FREQUENCY):
|
||||
graph.draw_line((-3,y), (3,y))
|
||||
graph.draw_line((-3, y), (3, y))
|
||||
if y != 0:
|
||||
graph.draw_text( str(y), (-10,y), color='blue')
|
||||
graph.draw_text(str(y), (-10, y), color='blue')
|
||||
|
||||
|
||||
# Create the graph that will be put into the window
|
||||
graph = sg.Graph(canvas_size=(400, 400),
|
||||
graph_bottom_left=(-(SIZE_X+5), -(SIZE_Y+5)),
|
||||
graph_top_right=(SIZE_X+5, SIZE_Y+5),
|
||||
background_color='white',
|
||||
key='graph')
|
||||
graph_bottom_left=(-(SIZE_X+5), -(SIZE_Y+5)),
|
||||
graph_top_right=(SIZE_X+5, SIZE_Y+5),
|
||||
background_color='white',
|
||||
key='graph')
|
||||
# Window layout
|
||||
layout = [[sg.Text('Example of Using Math with a Graph', justification='center', size=(50,1), relief=sg.RELIEF_SUNKEN)],
|
||||
layout = [[sg.Text('Example of Using Math with a Graph', justification='center', size=(50, 1), relief=sg.RELIEF_SUNKEN)],
|
||||
[graph],
|
||||
[sg.Text('y = sin(x / x2 * x1)', font='Algerian 18')],
|
||||
[sg.Text('x1'),sg.Slider((0,200), orientation='h', enable_events=True,key='_SLIDER_')],
|
||||
[sg.Text('x2'),sg.Slider((1,200), orientation='h', enable_events=True,key='_SLIDER2_')]]
|
||||
[sg.Text('y = sin(x / x2 * x1)', font='COURIER 18')],
|
||||
[sg.Text('x1'), sg.Slider((0, 200), orientation='h',
|
||||
enable_events=True, key='-SLIDER-')],
|
||||
[sg.Text('x2'), sg.Slider((1, 200), orientation='h', enable_events=True, key='-SLIDER2-')]]
|
||||
|
||||
window = sg.Window('Graph of Sine Function', layout)
|
||||
|
||||
|
@ -43,9 +47,11 @@ while True:
|
|||
graph.erase()
|
||||
draw_axis()
|
||||
prev_x = prev_y = None
|
||||
for x in range(-SIZE_X,SIZE_X):
|
||||
y = math.sin(x/int(values['_SLIDER2_']))*int(values['_SLIDER_'])
|
||||
|
||||
for x in range(-SIZE_X, SIZE_X):
|
||||
y = math.sin(x/int(values['-SLIDER2-']))*int(values['-SLIDER-'])
|
||||
if prev_x is not None:
|
||||
graph.draw_line((prev_x, prev_y), (x,y), color='red')
|
||||
graph.draw_line((prev_x, prev_y), (x, y), color='red')
|
||||
prev_x, prev_y = x, y
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,69 +1,76 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
import random
|
||||
import sys
|
||||
|
||||
STEP_SIZE=1
|
||||
'''
|
||||
Example of random line in Graph element.
|
||||
'''
|
||||
|
||||
STEP_SIZE = 1
|
||||
SAMPLES = 300
|
||||
SAMPLE_MAX = 300
|
||||
CANVAS_SIZE = (300,300)
|
||||
CANVAS_SIZE = (300, 300)
|
||||
|
||||
|
||||
def main():
|
||||
global g_exit, g_response_time
|
||||
|
||||
layout = [[sg.T('Enter width, height of graph')],
|
||||
[sg.In(size=(6, 1)), sg.In(size=(6, 1))],
|
||||
layout = [[sg.Text('Enter width, height of graph')],
|
||||
[sg.Input(size=(6, 1), key='w'), sg.Input(size=(6, 1), key='h')],
|
||||
[sg.Ok(), sg.Cancel()]]
|
||||
|
||||
window = sg.Window('Enter graph size').Layout(layout)
|
||||
b,v = window.Read()
|
||||
if b is None or b == 'Cancel':
|
||||
sys.exit(69)
|
||||
w, h = int(v[0]), int(v[1])
|
||||
CANVAS_SIZE = (w,h)
|
||||
window = sg.Window('Enter graph size', layout)
|
||||
event, values = window.read()
|
||||
if event is None or event == 'Cancel':
|
||||
return
|
||||
|
||||
CANVAS_SIZE = int(values['w']), int(values['h'])
|
||||
window.close()
|
||||
|
||||
# start ping measurement thread
|
||||
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.SetOptions(element_padding=(0,0))
|
||||
sg.change_look_and_feel('Black')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [ [sg.Button('Quit', button_color=('white','black'))],
|
||||
[sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,SAMPLE_MAX),background_color='black', key='graph')],]
|
||||
layout = [[sg.Button('Quit', button_color=('white', 'black'))],
|
||||
[sg.Graph(CANVAS_SIZE, (0, 0), (SAMPLES, SAMPLE_MAX)
|
||||
background_color='black', key='graph')], ]
|
||||
|
||||
window = sg.Window('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False).Layout(layout).Finalize()
|
||||
graph = window.FindElement('graph')
|
||||
window = sg.Window('Canvas test', layout, grab_anywhere=True,
|
||||
background_color='black', no_titlebar=False,
|
||||
use_default_focus=False, finalize=True)
|
||||
graph = window['graph']
|
||||
|
||||
prev_response_time = None
|
||||
i=0
|
||||
i = 0
|
||||
prev_x, prev_y = 0, 0
|
||||
graph_value = 250
|
||||
while True:
|
||||
# time.sleep(.2)
|
||||
event, values = window.Read(timeout=0)
|
||||
event, values = window.read(timeout=0)
|
||||
if event == 'Quit' or event is None:
|
||||
break
|
||||
|
||||
graph_offset = random.randint(-10, 10)
|
||||
graph_value = graph_value + graph_offset
|
||||
|
||||
if graph_value > SAMPLE_MAX:
|
||||
graph_value = SAMPLE_MAX
|
||||
if graph_value < 0:
|
||||
graph_value = 0
|
||||
|
||||
new_x, new_y = i, graph_value
|
||||
prev_value = graph_value
|
||||
|
||||
if i >= SAMPLES:
|
||||
graph.Move(-STEP_SIZE,0)
|
||||
graph.move(-STEP_SIZE, 0)
|
||||
prev_x = prev_x - STEP_SIZE
|
||||
graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
# window.FindElement('graph').DrawPoint((new_x, new_y), color='red')
|
||||
|
||||
graph.draw_line((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
prev_x, prev_y = new_x, new_y
|
||||
i += STEP_SIZE if i < SAMPLES else 0
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
import ping
|
||||
from threading import Thread
|
||||
import time
|
||||
import PySimpleGUI as sg
|
||||
from threading import Thread
|
||||
import ping
|
||||
import time
|
||||
|
||||
# Yet another usage of Graph element.
|
||||
|
||||
STEP_SIZE=1
|
||||
STEP_SIZE = 1
|
||||
SAMPLES = 6000
|
||||
CANVAS_SIZE = (6000,500)
|
||||
CANVAS_SIZE = (6000, 500)
|
||||
|
||||
# globale used to communicate with thread.. yea yea... it's working fine
|
||||
g_exit = False
|
||||
g_response_time = None
|
||||
|
||||
|
||||
def ping_thread(args):
|
||||
global g_exit, g_response_time
|
||||
while not g_exit:
|
||||
g_response_time = ping.quiet_ping('google.com', timeout=1000)
|
||||
|
||||
|
||||
def main():
|
||||
global g_exit, g_response_time
|
||||
|
||||
|
@ -23,21 +27,22 @@ def main():
|
|||
thread = Thread(target=ping_thread, args=(None,))
|
||||
thread.start()
|
||||
|
||||
sg.ChangeLookAndFeel('Black')
|
||||
sg.SetOptions(element_padding=(0,0))
|
||||
sg.change_look_and_feel('Black')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
layout = [ [sg.T('Ping times to Google.com', font='Any 12'), sg.Quit(pad=((100,0), 0), button_color=('white', 'black'))],
|
||||
[sg.Graph(CANVAS_SIZE, (0,0), (SAMPLES,500),background_color='black', key='graph')],]
|
||||
layout = [[sg.Text('Ping times to Google.com', font='Any 12'),
|
||||
sg.Quit(pad=((100, 0), 0), button_color=('white', 'black'))],
|
||||
[sg.Graph(CANVAS_SIZE, (0, 0), (SAMPLES, 500),
|
||||
background_color='black', key='graph')]
|
||||
]
|
||||
|
||||
form = sg.FlexForm('Canvas test', grab_anywhere=True, background_color='black', no_titlebar=False, use_default_focus=False)
|
||||
form.Layout(layout)
|
||||
|
||||
form.Finalize()
|
||||
graph = form.FindElement('graph')
|
||||
form = sg.FlexForm('Canvas test', layout, grab_anywhere=True, background_color='black',
|
||||
no_titlebar=False, use_default_focus=False, finalize=True)
|
||||
graph = form['graph']
|
||||
|
||||
prev_response_time = None
|
||||
i=0
|
||||
prev_x, prev_y = 0, 0
|
||||
i = 0
|
||||
prev_x, prev_y = 0, 0
|
||||
while True:
|
||||
time.sleep(.2)
|
||||
|
||||
|
@ -49,10 +54,10 @@ def main():
|
|||
new_x, new_y = i, g_response_time[0]
|
||||
prev_response_time = g_response_time
|
||||
if i >= SAMPLES:
|
||||
graph.Move(-STEP_SIZE,0)
|
||||
graph.move(-STEP_SIZE, 0)
|
||||
prev_x = prev_x - STEP_SIZE
|
||||
graph.DrawLine((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
# form.FindElement('graph').DrawPoint((new_x, new_y), color='red')
|
||||
graph.draw_line((prev_x, prev_y), (new_x, new_y), color='white')
|
||||
# form['graph'].draw_point((new_x, new_y), color='red')
|
||||
prev_x, prev_y = new_x, new_y
|
||||
i += STEP_SIZE if i < SAMPLES else 0
|
||||
|
||||
|
@ -63,4 +68,4 @@ def main():
|
|||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
exit(69)
|
||||
|
||||
|
|
|
@ -1,26 +1,32 @@
|
|||
import PySimpleGUIWeb as sg
|
||||
# import PySimpleGUI as sg
|
||||
import pymunk
|
||||
import random
|
||||
import socket
|
||||
|
||||
# Yet another usage of Graph element and physics from pymunk.
|
||||
|
||||
|
||||
"""
|
||||
Demo that shows integrating PySimpleGUI with the pymunk library. This combination
|
||||
of PySimpleGUI and pymunk could be used to build games.
|
||||
Note this exact same demo runs with PySimpleGUIWeb by changing the import statement
|
||||
"""
|
||||
|
||||
|
||||
class Ball():
|
||||
def __init__(self, x, y, r, *args, **kwargs):
|
||||
mass = 10
|
||||
self.body = pymunk.Body(mass,
|
||||
pymunk.moment_for_circle(mass, 0, r, (0, 0))) # Create a Body with mass and moment
|
||||
# Create a Body with mass and moment
|
||||
self.body = pymunk.Body(
|
||||
mass, pymunk.moment_for_circle(mass, 0, r, (0, 0)))
|
||||
self.body.position = x, y
|
||||
self.shape = pymunk.Circle(self.body, r, offset=(0, 0)) # Create a box shape and attach to body
|
||||
# Create a box shape and attach to body
|
||||
self.shape = pymunk.Circle(self.body, r, offset=(0, 0))
|
||||
self.shape.elasticity = 0.99999
|
||||
self.shape.friction = 0.8
|
||||
self.gui_circle_figure = None
|
||||
|
||||
|
||||
class Playfield():
|
||||
def __init__(self):
|
||||
self.space = pymunk.Space()
|
||||
|
@ -30,7 +36,7 @@ class Playfield():
|
|||
self.add_wall((600, 0), (600, 400)) # right side
|
||||
|
||||
def add_wall(self, pt_from, pt_to):
|
||||
body = pymunk.Body(body_type=pymunk.Body.STATIC)
|
||||
body = pymunk.Body(body_type=pymunk.Body.STATIC)
|
||||
ground_shape = pymunk.Segment(body, pt_from, pt_to, 0.0)
|
||||
ground_shape.friction = 0.8
|
||||
ground_shape.elasticity = .99
|
||||
|
@ -45,25 +51,28 @@ class Playfield():
|
|||
ball = Ball(x, y, r)
|
||||
self.arena_balls.append(ball)
|
||||
area.space.add(ball.body, ball.shape)
|
||||
ball.gui_circle_figure = graph_elem.DrawCircle((x, y), r, fill_color='black', line_color='red')
|
||||
ball.gui_circle_figure = graph_elem.draw_circle(
|
||||
(x, y), r, fill_color='black', line_color='red')
|
||||
|
||||
|
||||
# ------------------- Build and show the GUI Window -------------------
|
||||
graph_elem = sg.Graph((600, 400), (0, 400), (600, 0), enable_events=True, key='_GRAPH_', background_color='lightblue')
|
||||
graph_elem = sg.Graph((600, 400), (0, 400), (600, 0),
|
||||
enable_events=True, key='-GRAPH-', background_color='lightblue')
|
||||
|
||||
layout = [[sg.Text('Ball Test'), sg.T('My IP {}'.format(socket.gethostbyname(socket.gethostname())))],
|
||||
hostname = socket.gethostbyname(socket.gethostname())
|
||||
layout = [[sg.Text('Ball Test'), sg.Text('My IP '+hostname)],
|
||||
[graph_elem],
|
||||
# [sg.Up(), sg.Down()],
|
||||
[sg.B('Kick'), sg.Button('Exit')]]
|
||||
[sg.Button('Kick'), sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Window Title', layout, ).Finalize()
|
||||
window = sg.Window('Window Title', layout, finalize=True)
|
||||
|
||||
area = Playfield()
|
||||
area.add_balls()
|
||||
|
||||
# ------------------- GUI Event Loop -------------------
|
||||
while True: # Event Loop
|
||||
event, values = window.Read(timeout=0)
|
||||
event, values = window.read(timeout=0)
|
||||
# print(event, values)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
@ -71,7 +80,9 @@ while True: # Event Loop
|
|||
|
||||
for ball in area.arena_balls:
|
||||
if event == 'Kick':
|
||||
ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(1,200)
|
||||
graph_elem.RelocateFigure(ball.gui_circle_figure, ball.body.position[0], ball.body.position[1])
|
||||
ball.body.position = ball.body.position[0], ball.body.position[1]-random.randint(
|
||||
1, 200)
|
||||
graph_elem.RelocateFigure(
|
||||
ball.gui_circle_figure, ball.body.position[0], ball.body.position[1])
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
Oh yes, the classic "Hello World". The problem is that you
|
||||
Oh yes, the classic "Hello World". The problem is that you
|
||||
can do it so many ways using PySimpleGUI
|
||||
"""
|
||||
|
||||
sg.PopupNoButtons('Hello World') # the single line
|
||||
sg.popup_no_buttons('Hello World') # the single line
|
||||
|
||||
sg.Window('Hello world', [[sg.Text('Hello World')]]).Read() # single line using a real window
|
||||
# single line using a real window
|
||||
sg.Window('Hello world', [[sg.Text('Hello World')]]).read()
|
||||
|
||||
# This is a "Traditional" PySimpleGUI window code. First make a layout, then a window, the read it
|
||||
layout = [[sg.Text('Hello World')]]
|
||||
window = sg.Window('Hello world', layout)
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUIQt as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import subprocess
|
||||
|
||||
'''
|
||||
Famouns howdoi command in PSG
|
||||
'''
|
||||
|
||||
|
||||
# Test this command in a dos window if you are having trouble.
|
||||
HOW_DO_I_COMMAND = 'python -m howdoi.howdoi'
|
||||
HOW_DO_I_COMMAND = 'python -m howdoi.howdoi'
|
||||
|
||||
# if you want an icon on your taskbar for this gui, then change this line of code to point to the ICO file
|
||||
DEFAULT_ICON = 'E:\\TheRealMyDocs\\Icons\\QuestionMark.ico'
|
||||
|
||||
def HowDoI():
|
||||
'''
|
||||
|
@ -22,46 +20,59 @@ def HowDoI():
|
|||
:return: never returns
|
||||
'''
|
||||
# ------- Make a new Window ------- #
|
||||
sg.ChangeLookAndFeel('GreenTan') # give our form a spiffy set of colors
|
||||
# give our form a spiffy set of colors
|
||||
sg.change_look_and_feel('GreenTan')
|
||||
|
||||
layout = [
|
||||
[sg.Text('Ask and your answer will appear here....', size=(40, 1))],
|
||||
[sg.Output(size=(120, 30), font=('Helvetica 10'))],
|
||||
[ sg.Spin(values=(1, 2, 3, 4), initial_value=1, size=(2, 1), key='Num Answers', font='Helvetica 15'),
|
||||
sg.Text('Num Answers',font='Helvetica 15'), sg.Checkbox('Display Full Text', key='full text', font='Helvetica 15'),
|
||||
sg.T('Command History', font='Helvetica 15'), sg.T('', size=(40,3), text_color=sg.BLUES[0], key='history')],
|
||||
[sg.Multiline(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
|
||||
sg.Button('SEND', button_color=(sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
|
||||
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]
|
||||
]
|
||||
layout = [
|
||||
[sg.Text('Ask and your answer will appear here....', size=(40, 1))],
|
||||
[sg.Output(size=(120, 30), font=('Helvetica 10'))],
|
||||
[sg.Spin(values=(1, 2, 3, 4), initial_value=1, size=(2, 1), key='Num Answers', font='Helvetica 15'),
|
||||
sg.Text('Num Answers', font='Helvetica 15'), sg.CBox(
|
||||
'Display Full Text', key='full text', font='Helvetica 15'),
|
||||
sg.Text('Command History', font='Helvetica 15'), sg.Text('', size=(40, 3), text_color=sg.BLUES[0], key='history')],
|
||||
[sg.MLine(size=(85, 5), enter_submits=True, key='query', do_not_clear=False),
|
||||
sg.Button('SEND', button_color=(
|
||||
sg.YELLOWS[0], sg.BLUES[0]), bind_return_key=True),
|
||||
sg.Button('EXIT', button_color=(sg.YELLOWS[0], sg.GREENS[0]))]
|
||||
]
|
||||
|
||||
window = sg.Window('How Do I ??', default_element_size=(30, 2), icon=DEFAULT_ICON, font=('Helvetica',' 13'), default_button_element_size=(8,2), return_keyboard_events=True, no_titlebar=True, grab_anywhere=True)
|
||||
window.Layout(layout)
|
||||
window = sg.Window('How Do I ??', layout, default_element_size=(30, 2),
|
||||
font=('Helvetica', ' 13'),
|
||||
default_button_element_size=(8, 2),
|
||||
return_keyboard_events=True, no_titlebar=True,
|
||||
grab_anywhere=True)
|
||||
# ---===--- Loop taking in user input and using it to query HowDoI --- #
|
||||
command_history = []
|
||||
history_offset = 0
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event == 'SEND':
|
||||
query = values['query'].rstrip()
|
||||
# print(query)
|
||||
QueryHowDoI(query, values['Num Answers'], values['full text']) # send the string to HowDoI
|
||||
# send the string to HowDoI
|
||||
QueryHowDoI(query, values['Num Answers'], values['full text'])
|
||||
command_history.append(query)
|
||||
history_offset = len(command_history)-1
|
||||
window.FindElement('query').Update('') # manually clear input because keyboard events blocks clear
|
||||
window.FindElement('history').Update('\n'.join(command_history[-3:]))
|
||||
# manually clear input because keyboard events blocks clear
|
||||
window['query'].update('')
|
||||
window['history'].update('\n'.join(command_history[-3:]))
|
||||
elif event == None or event == 'EXIT': # if exit button or closed using X
|
||||
break
|
||||
elif 'Up' in event and len(command_history): # scroll back in history
|
||||
# scroll back in history
|
||||
elif 'Up' in event and len(command_history):
|
||||
command = command_history[history_offset]
|
||||
history_offset -= 1 * (history_offset > 0) # decrement is not zero
|
||||
window.FindElement('query').Update(command)
|
||||
elif 'Down' in event and len(command_history): # scroll forward in history
|
||||
history_offset += 1 * (history_offset < len(command_history)-1) # increment up to end of list
|
||||
# decrement is not zero
|
||||
history_offset -= 1 * (history_offset > 0)
|
||||
window['query'].update(command)
|
||||
# scroll forward in history
|
||||
elif 'Down' in event and len(command_history):
|
||||
# increment up to end of list
|
||||
history_offset += 1 * (history_offset < len(command_history)-1)
|
||||
command = command_history[history_offset]
|
||||
window.FindElement('query').Update(command)
|
||||
window['query'].update(command)
|
||||
elif 'Escape' in event: # clear currently line
|
||||
window.FindElement('query').Update('')
|
||||
window['query'].update('')
|
||||
window.close()
|
||||
|
||||
|
||||
def QueryHowDoI(Query, num_answers, full_text):
|
||||
|
@ -71,15 +82,15 @@ def QueryHowDoI(Query, num_answers, full_text):
|
|||
:param Query: text english question to ask the HowDoI web engine
|
||||
:return: nothing
|
||||
'''
|
||||
howdoi_command = HOW_DO_I_COMMAND
|
||||
full_text_option = ' -a' if full_text else ''
|
||||
t = subprocess.Popen(howdoi_command + ' \"'+ Query + '\" -n ' + str(num_answers)+full_text_option, stdout=subprocess.PIPE)
|
||||
t = subprocess.Popen(HOW_DO_I_COMMAND + ' \"' + Query + '\" -n ' +
|
||||
str(num_answers)+full_text_option, stdout=subprocess.PIPE)
|
||||
(output, err) = t.communicate()
|
||||
print('{:^88}'.format(Query.rstrip()))
|
||||
print('_'*60)
|
||||
print(output.decode("utf-8") )
|
||||
print(output.decode("utf-8"))
|
||||
exit_code = t.wait()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
HowDoI()
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
import PySimpleGUI as sg
|
||||
|
||||
'''
|
||||
IP Address entry window with digit validation and auto advance
|
||||
If not a digit or ., the ignored
|
||||
. will advance the focus to the next entry
|
||||
On the last input, once it's complete the focus moves to the OK button
|
||||
Pressing spacebar with focus on OK generates an _OK_ event
|
||||
'''
|
||||
|
||||
# create a short-cut element so don't have to type this in over and over
|
||||
InIp = lambda key: sg.Input(do_not_clear=True, size=(3, 1), key=key, pad=(0, 2))
|
||||
|
||||
layout = [[sg.Text('Your typed chars appear here:'), sg.Text('', key='_OUTPUT_')],
|
||||
[InIp(0), sg.T('.'), InIp(1), sg.T('.'), InIp(2), sg.T('.'), InIp(3)],
|
||||
[sg.Button('Ok', key='_OK_', bind_return_key=True), sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
print(event)
|
||||
if event is None or event == 'Exit':
|
||||
break
|
||||
elem = window.FindElementWithFocus()
|
||||
if elem is not None:
|
||||
key = elem.Key
|
||||
value = values[key] # get value of input field that has focus
|
||||
if event == '.' and key!= '_OK_': # if a ., then advance to next field
|
||||
elem.Update(value[:-1])
|
||||
value = value[:-1]
|
||||
next_elem = window.Element(key+1)
|
||||
next_elem.SetFocus()
|
||||
elif event not in '0123456789':
|
||||
elem.Update(value[:-1])
|
||||
elif len(value) > 2 and key < 3: # if 2 digits typed in, move on to next input
|
||||
next_elem = window.Element(key+1)
|
||||
next_elem.SetFocus()
|
||||
elif len(value)> 2 and key == 3:
|
||||
window.Element('_OK_').SetFocus()
|
||||
print('You entered IP Address {}.{}.{}.{}'.format(*values.values()))
|
||||
|
||||
window.Close()
|
|
@ -1,12 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import os
|
||||
from PIL import Image, ImageTk
|
||||
import io
|
||||
|
||||
"""
|
||||
Simple Image Browser based on PySimpleGUI
|
||||
--------------------------------------------
|
||||
|
@ -19,13 +16,14 @@ There are some improvements compared to the PNG browser of the repository:
|
|||
|
||||
Dependecies
|
||||
------------
|
||||
Python v3
|
||||
Python3
|
||||
PIL
|
||||
"""
|
||||
|
||||
# Get the folder containin:g the images from the user
|
||||
folder = sg.PopupGetFolder('Image folder to open', default_path='')
|
||||
folder = sg.popup_get_folder('Image folder to open', default_path='')
|
||||
if not folder:
|
||||
sg.PopupCancel('Cancelling')
|
||||
sg.popup_cancel('Cancelling')
|
||||
raise SystemExit()
|
||||
|
||||
# PIL supported image types
|
||||
|
@ -35,60 +33,59 @@ img_types = (".png", ".jpg", "jpeg", ".tiff", ".bmp")
|
|||
flist0 = os.listdir(folder)
|
||||
|
||||
# create sub list of image files (no sub folders, no wrong file types)
|
||||
fnames = [f for f in flist0 if os.path.isfile(os.path.join(folder,f)) and f.lower().endswith(img_types)]
|
||||
fnames = [f for f in flist0 if os.path.isfile(
|
||||
os.path.join(folder, f)) and f.lower().endswith(img_types)]
|
||||
|
||||
num_files = len(fnames) # number of iamges found
|
||||
if num_files == 0:
|
||||
sg.Popup('No files in folder')
|
||||
sg.popup('No files in folder')
|
||||
raise SystemExit()
|
||||
|
||||
del flist0 # no longer needed
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ------------------------------------------------------------------------------
|
||||
# use PIL to read data of one image
|
||||
#------------------------------------------------------------------------------
|
||||
def get_img_data(f, maxsize = (1200, 850), first = False):
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def get_img_data(f, maxsize=(1200, 850), first=False):
|
||||
"""Generate image data using PIL
|
||||
"""
|
||||
img = Image.open(f)
|
||||
img.thumbnail(maxsize)
|
||||
if first: # tkinter is inactive the first time
|
||||
bio = io.BytesIO()
|
||||
img.save(bio, format = "PNG")
|
||||
img.save(bio, format="PNG")
|
||||
del img
|
||||
return bio.getvalue()
|
||||
return ImageTk.PhotoImage(img)
|
||||
#------------------------------------------------------------------------------
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# create the form that also returns keyboard events
|
||||
window = sg.Window('Image Browser', return_keyboard_events=True,
|
||||
location=(0, 0), use_default_focus=False)
|
||||
|
||||
# make these 2 elements outside the layout as we want to "update" them later
|
||||
# initialize to the first file in the list
|
||||
filename = os.path.join(folder, fnames[0]) # name of first file in list
|
||||
image_elem = sg.Image(data = get_img_data(filename, first = True))
|
||||
image_elem = sg.Image(data=get_img_data(filename, first=True))
|
||||
filename_display_elem = sg.Text(filename, size=(80, 3))
|
||||
file_num_display_elem = sg.Text('File 1 of {}'.format(num_files), size=(15,1))
|
||||
file_num_display_elem = sg.Text('File 1 of {}'.format(num_files), size=(15, 1))
|
||||
|
||||
# define layout, show and read the form
|
||||
col = [[filename_display_elem],
|
||||
[image_elem]]
|
||||
[image_elem]]
|
||||
|
||||
col_files = [[sg.Listbox(values = fnames, change_submits=True, size=(60, 30), key='listbox')],
|
||||
[sg.Button('Next', size=(8,2)), sg.Button('Prev',
|
||||
size=(8,2)), file_num_display_elem]]
|
||||
col_files = [[sg.Listbox(values=fnames, change_submits=True, size=(60, 30), key='listbox')],
|
||||
[sg.Button('Next', size=(8, 2)), sg.Button('Prev', size=(8, 2)), file_num_display_elem]]
|
||||
|
||||
layout = [[sg.Column(col_files), sg.Column(col)]]
|
||||
layout = [[sg.Col(col_files), sg.Col(col)]]
|
||||
|
||||
window.Layout(layout) # Shows form on screen
|
||||
window = sg.Window('Image Browser', layout, return_keyboard_events=True,
|
||||
location=(0, 0), use_default_focus=False)
|
||||
|
||||
# loop reading the user input and displaying image, filename
|
||||
i=0
|
||||
i = 0
|
||||
while True:
|
||||
# read the form
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
print(event, values)
|
||||
# perform button and keyboard operations
|
||||
if event is None:
|
||||
|
@ -111,10 +108,10 @@ while True:
|
|||
filename = os.path.join(folder, fnames[i])
|
||||
|
||||
# update window with new image
|
||||
image_elem.Update(data=get_img_data(filename))
|
||||
image_elem.update(data=get_img_data(filename))
|
||||
# update window with filename
|
||||
filename_display_elem.Update(filename)
|
||||
filename_display_elem.update(filename)
|
||||
# update page display
|
||||
file_num_display_elem.Update('File {} of {}'.format(i+1, num_files))
|
||||
|
||||
file_num_display_elem.update('File {} of {}'.format(i+1, num_files))
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
import sys
|
||||
import PySimpleGUI as sg
|
||||
import re
|
||||
QT = True
|
||||
if QT:
|
||||
import PySimpleGUIQt as sg
|
||||
else:
|
||||
import PySimpleGUI as sg
|
||||
|
||||
def autocomplete_popup_show(text_list ):
|
||||
autocomplete_popup_layout = [[sg.Listbox(values=text_list,
|
||||
size=(100,20*len(text_list)) if QT else (15, len(text_list)),
|
||||
change_submits=True,
|
||||
bind_return_key=True,
|
||||
auto_size_text=True,
|
||||
key='_FLOATING_LISTBOX_', enable_events=True)]]
|
||||
'''
|
||||
Exampel of Input element features.
|
||||
'''
|
||||
|
||||
def autocomplete_popup_show(text_list):
|
||||
autocomplete_popup_layout = [
|
||||
[sg.Listbox(values=text_list,
|
||||
size=(15, len(text_list)),
|
||||
change_submits=True, bind_return_key=True,
|
||||
key='-FLOATING-LISTBOX-', enable_events=True)
|
||||
]
|
||||
]
|
||||
|
||||
autocomplete_popup = sg.Window("Borderless Window",
|
||||
autocomplete_popup_layout,
|
||||
default_element_size=(12, 1),
|
||||
auto_size_text=False,
|
||||
auto_size_buttons=False,
|
||||
no_titlebar=True,
|
||||
grab_anywhere=True,
|
||||
auto_size_text=False, keep_on_top=True,
|
||||
no_titlebar=True, grab_anywhere=True,
|
||||
return_keyboard_events=True,
|
||||
keep_on_top=True,
|
||||
auto_size_buttons=False,
|
||||
background_color='black',
|
||||
location=(1320,622),
|
||||
default_button_element_size=(12, 1))
|
||||
default_button_element_size=(12, 1),
|
||||
location=(1320, 622), finalize=True)
|
||||
|
||||
window = autocomplete_popup.Layout(autocomplete_popup_layout).Finalize()
|
||||
return window
|
||||
|
||||
|
||||
|
@ -34,57 +32,69 @@ def predict_text(input, lista):
|
|||
pattern = re.compile('.*' + input + '.*')
|
||||
return [w for w in lista if re.match(pattern, w)]
|
||||
|
||||
|
||||
choices = ['ABC' + str(i) for i in range(30)] # dummy data
|
||||
|
||||
layout = [ [sg.Text('Your typed chars appear here:')],
|
||||
[sg.In(key='_INPUT_', size=(10,1), do_not_clear=True)],
|
||||
[sg.Button('Show'), sg.Button('Exit')],]
|
||||
layout = [[sg.Text('Your typed chars appear here:')],
|
||||
[sg.Input(key='-INPUT-', size=(10, 1))],
|
||||
[sg.Button('Show'), sg.Button('Exit')], ]
|
||||
|
||||
window = sg.Window('Window Title', return_keyboard_events=True).Layout(layout)
|
||||
window = sg.Window('Window Title', layout, return_keyboard_events=True)
|
||||
|
||||
sel_item = -1
|
||||
skip_event = False
|
||||
while True: # Event Loop
|
||||
event, values = window.Read(timeout=500)
|
||||
if event is None or event == 'Exit':
|
||||
event, values = window.read(timeout=500)
|
||||
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
if event != sg.TIMEOUT_KEY:
|
||||
# print(f'ev1 {event}')
|
||||
in_val = values['_INPUT_']
|
||||
# print(f'event1 {event}')
|
||||
in_val = values['-INPUT-']
|
||||
prediction_list = predict_text(str(in_val), choices)
|
||||
if prediction_list:
|
||||
try:
|
||||
fwindow.Close()
|
||||
except: pass
|
||||
fwindow.close()
|
||||
except:
|
||||
pass
|
||||
fwindow = autocomplete_popup_show(prediction_list)
|
||||
list_elem = fwindow.Element('_FLOATING_LISTBOX_')
|
||||
list_elem = fwindow['-FLOATING-LISTBOX-']
|
||||
if event == '_COMBO_':
|
||||
sg.Popup('Chose', values['_COMBO_'])
|
||||
sg.popup('Chose', values['_COMBO_'])
|
||||
|
||||
if event.startswith('Down') or event.startswith('special 16777237'):
|
||||
sel_item = sel_item + (sel_item<len(prediction_list))
|
||||
list_elem.Update(set_to_index=sel_item)
|
||||
sel_item = sel_item + (sel_item < len(prediction_list))
|
||||
list_elem.update(set_to_index=sel_item)
|
||||
skip_event = True
|
||||
|
||||
elif event.startswith('Up') or event.startswith('special 16777235'):
|
||||
sel_item = sel_item - (sel_item>0)
|
||||
list_elem.Update(set_to_index=sel_item)
|
||||
sel_item = sel_item - (sel_item > 0)
|
||||
list_elem.update(set_to_index=sel_item)
|
||||
skip_event = True
|
||||
|
||||
if event == '\r' or event.startswith('special 16777220'):
|
||||
chosen = vals2['_FLOATING_LISTBOX_']
|
||||
window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True)
|
||||
fwindow.Close()
|
||||
chosen = values2['-FLOATING-LISTBOX-']
|
||||
window['-INPUT-'].update(values2['-FLOATING-LISTBOX-']
|
||||
[0], select=True)
|
||||
fwindow.close()
|
||||
sel_item = -1
|
||||
|
||||
if event.startswith('Escape') or event.startswith('special 16777216'):
|
||||
window.Element('_INPUT_').Update('')
|
||||
window['-INPUT-'].update('')
|
||||
|
||||
try:
|
||||
ev2, vals2 = fwindow.Read(timeout=10)
|
||||
if ev2 == '_FLOATING_LISTBOX_' and skip_event and QT:
|
||||
skip_event = False
|
||||
elif ev2 != sg.TIMEOUT_KEY and ev2 is not None:
|
||||
# print(f'ev2 {ev2}')
|
||||
fwindow.Close()
|
||||
window.Element('_INPUT_').Update(vals2['_FLOATING_LISTBOX_'][0], select=True)
|
||||
event2, values2 = fwindow.read(timeout=10)
|
||||
# if event2 == '-FLOATING-LISTBOX-' and skip_event and QT:
|
||||
# skip_event = False
|
||||
if event2 != sg.TIMEOUT_KEY and event2 is not None:
|
||||
# print(f'event2 {event2}')
|
||||
fwindow.close()
|
||||
window['-INPUT-'].update(values2['-FLOATING-LISTBOX-']
|
||||
[0], select=True)
|
||||
sel_item = -1
|
||||
fwindow = None
|
||||
except: pass
|
||||
window.Close()
|
||||
except:
|
||||
pass
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
"""
|
||||
Simple field validation
|
||||
|
@ -11,15 +7,18 @@ else:
|
|||
"""
|
||||
|
||||
layout = [[sg.Text('Enter digits:')],
|
||||
[sg.Input(do_not_clear=True, enable_events=True, key='_INPUT_')],
|
||||
[sg.Button('Ok', key='_OK_'),sg.Button('Exit')]]
|
||||
[sg.Input('', enable_events=True, key='-INPUT-')],
|
||||
[sg.Button('Ok', key='-OK-'), sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Window Title').Layout(layout)
|
||||
window = sg.Window('Window Title', layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
if event in (None, 'Exit'):
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
if len(values['_INPUT_']) and values['_INPUT_'][-1] not in ('0123456789'): # if last char entered not a digit
|
||||
window.Element('_INPUT_').Update(values['_INPUT_'][:-1]) # delete last char from input
|
||||
window.Close()
|
||||
# if last char entered not a digit
|
||||
if len(values['-INPUT-']) and values['-INPUT-'][-1] not in ('0123456789'):
|
||||
# delete last char from input
|
||||
window['-INPUT-'].update(values['-INPUT-'][:-1])
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -9,19 +9,19 @@ import PySimpleGUI as sg
|
|||
|
||||
"""
|
||||
|
||||
layout = [[sg.Column([[sg.Text('My Window')],[sg.Input(key='_IN_'), sg.B('My button', key='_OUT_')]], key='_COL_')],
|
||||
[sg.Button('Invisible'), sg.B('Visible'), sg.Button('Exit')]]
|
||||
layout = [[sg.Col([[sg.Text('My Window')], [sg.Input(key='-IN-'), sg.Button('My button', key='-OUT-')]], key='-COL-')],
|
||||
[sg.Button('Invisible'), sg.Button('Visible'), sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Window Title', layout)
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
print(event, values)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
if event == 'Invisible':
|
||||
window.Elem('_COL_').Update(visible=False)
|
||||
window['-COL-'].update(visible=False)
|
||||
elif event == 'Visible':
|
||||
window.Elem('_COL_').Update(visible=True)
|
||||
window['-COL-'].update(visible=True)
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# Recipe for getting keys, one at a time as they are released
|
||||
# If want to use the space bar, then be sure and disable the "default focus"
|
||||
|
||||
layout = [[sg.Text("Press a key or scroll mouse")],
|
||||
[sg.Text("", size=(18,1), key='text')],
|
||||
[sg.Text("", size=(18, 1), key='text')],
|
||||
[sg.Button("OK", key='OK')]]
|
||||
|
||||
window = sg.Window("Keyboard Test", return_keyboard_events=True, use_default_focus=False).Layout(layout)
|
||||
window = sg.Window("Keyboard Test", layout,
|
||||
return_keyboard_events=True, use_default_focus=False)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
text_elem = window.FindElement('text')
|
||||
event, values = window.read()
|
||||
text_elem = window['text']
|
||||
if event in ("OK", None):
|
||||
print(event, "exiting")
|
||||
break
|
||||
if len(event) == 1:
|
||||
text_elem.Update(value='%s - %s' % (event, ord(event)))
|
||||
text_elem.update(value='%s - %s' % (event, ord(event)))
|
||||
if event is not None:
|
||||
text_elem.Update(event)
|
||||
text_elem.update(event)
|
||||
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import PySimpleGUI as sg
|
||||
# import PySimpleGUIQt as sg
|
||||
|
||||
"""
|
||||
tkinter and Qt do not "activate" buttons by pressing the ENTER key with the button highlighted / in focus
|
||||
This demo will enable the application to click on a button if the button has focus (is highlighted) and the
|
||||
|
@ -18,29 +16,32 @@ import PySimpleGUI as sg
|
|||
|
||||
"""
|
||||
|
||||
QT_ENTER_KEY1 = 'special 16777220'
|
||||
QT_ENTER_KEY2 = 'special 16777221'
|
||||
QT_ENTER_KEY1 = 'special 16777220'
|
||||
QT_ENTER_KEY2 = 'special 16777221'
|
||||
|
||||
layout = [ [sg.T('Test of Enter Key use')],
|
||||
[sg.In(key='_IN_')],
|
||||
[sg.Button('Button 1', key='_1_')],
|
||||
[sg.Button('Button 2', key='_2_')],
|
||||
[sg.Button('Button 3', key='_3_')], ]
|
||||
layout = [[sg.Text('Test of Enter Key use')],
|
||||
[sg.Input(key='-IN-')],
|
||||
[sg.Button('Button 1', key='-1-')],
|
||||
[sg.Button('Button 2', key='-2-')],
|
||||
[sg.Button('Button 3', key='-3-')], ]
|
||||
|
||||
window = sg.Window('My new window', layout,
|
||||
return_keyboard_events=True)
|
||||
while True: # Event Loop
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event is None:
|
||||
break
|
||||
if event in ('\r', QT_ENTER_KEY1, QT_ENTER_KEY2): # Check for ENTER key
|
||||
elem = window.FindElementWithFocus() # go find element with Focus
|
||||
# go find element with Focus
|
||||
elem = window.find_element_with_focus()
|
||||
if elem is not None and elem.Type == sg.ELEM_TYPE_BUTTON: # if it's a button element, click it
|
||||
elem.Click()
|
||||
# check for buttons that have been clicked
|
||||
elif event == '_1_':
|
||||
elif event == '-1-':
|
||||
print('Button 1 clicked')
|
||||
elif event == '_2_':
|
||||
elif event == '-2-':
|
||||
print('Button 2 clicked')
|
||||
elif event == '_3_':
|
||||
print('Button 3 clicked')
|
||||
elif event == '-3-':
|
||||
print('Button 3 clicked')
|
||||
|
||||
window.close()
|
|
@ -1,17 +1,14 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
layout = [[sg.Text("Hold down a key")],
|
||||
[sg.Button("OK")]]
|
||||
|
||||
window = sg.Window("Realtime Keyboard Test", return_keyboard_events=True, use_default_focus=False).Layout(layout)
|
||||
window = sg.Window("Realtime Keyboard Test", layout, return_keyboard_events=True,
|
||||
use_default_focus=False)
|
||||
|
||||
while True:
|
||||
event, values = window.Read(timeout=0)
|
||||
event, values = window.read(timeout=0)
|
||||
|
||||
if event == "OK":
|
||||
print(event, values, "exiting")
|
||||
|
@ -23,3 +20,5 @@ while True:
|
|||
print(event)
|
||||
elif event is None:
|
||||
break
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,35 +1,34 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
|
||||
# Demonstrates a number of PySimpleGUI features including:
|
||||
# Default element size
|
||||
# auto_size_buttons
|
||||
# Button
|
||||
# Dictionary return values
|
||||
# Update of elements in form (Text, Input)
|
||||
# do_not_clear of Input elements
|
||||
|
||||
# update of elements in form (Text, Input)
|
||||
|
||||
|
||||
layout = [[sg.Text('Enter Your Passcode')],
|
||||
[sg.Input(size=(10, 1), do_not_clear=True, key='input')],
|
||||
[sg.Input('', size=(10, 1), key='input')],
|
||||
[sg.Button('1'), sg.Button('2'), sg.Button('3')],
|
||||
[sg.Button('4'), sg.Button('5'), sg.Button('6')],
|
||||
[sg.Button('7'), sg.Button('8'), sg.Button('9')],
|
||||
[sg.Button('Submit'), sg.Button('0'), sg.Button('Clear')],
|
||||
[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')],
|
||||
]
|
||||
|
||||
window = sg.Window('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False, grab_anywhere=False).Layout(layout)
|
||||
window = sg.Window('Keypad', layout,
|
||||
default_button_element_size=(5, 2),
|
||||
auto_size_buttons=False,
|
||||
grab_anywhere=False)
|
||||
|
||||
# Loop forever reading the form's values, updating the Input field
|
||||
keys_entered = ''
|
||||
while True:
|
||||
event, values = window.Read() # read the form
|
||||
event, values = window.read() # read the form
|
||||
if event is None: # if the X button clicked, just exit
|
||||
break
|
||||
if event == 'Clear': # clear keys if clear button
|
||||
|
@ -39,6 +38,8 @@ while True:
|
|||
keys_entered += event # add the new digit
|
||||
elif event == 'Submit':
|
||||
keys_entered = values['input']
|
||||
window.FindElement('out').Update(keys_entered) # output the final string
|
||||
window['out'].update(keys_entered) # output the final string
|
||||
|
||||
window.FindElement('input').Update(keys_entered) # change the form to reflect current key string
|
||||
# change the form to reflect current key string
|
||||
window['input'].update(keys_entered)
|
||||
window.close()
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,10 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import time
|
||||
import random
|
||||
|
||||
|
@ -23,9 +18,9 @@ def LEDIndicator(key=None, radius=30):
|
|||
pad=(0, 0), key=key)
|
||||
|
||||
def SetLED(window, key, color):
|
||||
graph = window.FindElement(key)
|
||||
graph.Erase()
|
||||
graph.DrawCircle((0, 0), 12, fill_color=color, line_color=color)
|
||||
graph = window[key]
|
||||
graph.erase()
|
||||
graph.draw_circle((0, 0), 12, fill_color=color, line_color=color)
|
||||
|
||||
|
||||
layout = [[sg.Text('My LED Status Indicators', size=(20,1))],
|
||||
|
@ -35,11 +30,11 @@ layout = [[sg.Text('My LED Status Indicators', size=(20,1))],
|
|||
[sg.Text('Server 1'), LEDIndicator('_server1_')],
|
||||
[sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('My new window', default_element_size=(12, 1), auto_size_text=False).Layout(layout).Finalize()
|
||||
window = sg.Window('My new window', layout, default_element_size=(12, 1), auto_size_text=False, finalize=True)
|
||||
|
||||
i = 0
|
||||
while True: # Event Loop
|
||||
event, value = window.Read(timeout=400)
|
||||
event, value = window.read(timeout=400)
|
||||
if event == 'Exit' or event is None:
|
||||
break
|
||||
if value is None:
|
||||
|
@ -49,3 +44,4 @@ while True: # Event Loop
|
|||
SetLED(window, '_ram_', 'green' if random.randint(1, 10) > 5 else 'red')
|
||||
SetLED(window, '_temp_', 'green' if random.randint(1, 10) > 5 else 'red')
|
||||
SetLED(window, '_server1_', 'green' if random.randint(1, 10) > 5 else 'red')
|
||||
window.close()
|
||||
|
|
|
@ -34,10 +34,11 @@ def layout0():
|
|||
|
||||
window = sg.Window('Generated Layouts', layout)
|
||||
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
Construct #1 - List comprehension to generate a Column of Buttons
|
||||
|
@ -46,15 +47,17 @@ def layout0():
|
|||
|
||||
"""
|
||||
|
||||
|
||||
def layout1():
|
||||
layout = [[sg.Button(i)] for i in range(4)] # a List of lists of buttons. Notice the ] after Button
|
||||
# a List of lists of buttons. Notice the ] after Button
|
||||
layout = [[sg.Button(i)] for i in range(4)]
|
||||
|
||||
window = sg.Window('Generated Layouts', layout)
|
||||
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -70,15 +73,17 @@ def layout1():
|
|||
See next Construct on how to not use a \ that also results in a VISUALLY similar to a norma layout
|
||||
"""
|
||||
|
||||
|
||||
def layout2():
|
||||
layout = [[sg.Button(i) for i in range(4)]] + [[sg.OK()]] # if want to split, can't add newline after + to do it
|
||||
# if want to split, can't add newline after + to do it
|
||||
layout = [[sg.Button(i) for i in range(4)]] + [[sg.OK()]]
|
||||
|
||||
window = sg.Window('Generated Layouts', layout)
|
||||
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -94,18 +99,21 @@ def layout2():
|
|||
use this way because it modifies the layout list directly.
|
||||
"""
|
||||
|
||||
|
||||
def layout3():
|
||||
# in terms of formatting, the layout to the RIGHT of the = sign looks like a 2-line GUI (ignore the layout +=
|
||||
layout = [[sg.Button(i) for i in range(4)]]
|
||||
layout += [[sg.OK()]] # this row is better than, but is the same as
|
||||
layout.append([sg.Cancel()]) # .. this row in that they both add a new ROW with a button on it
|
||||
layout = [[sg.Button(i) for i in range(4)]]
|
||||
# this row is better than, but is the same as
|
||||
layout += [[sg.OK()]]
|
||||
# .. this row in that they both add a new ROW with a button on it
|
||||
layout.append([sg.Cancel()])
|
||||
|
||||
window = sg.Window('Generated Layouts', layout)
|
||||
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -115,15 +123,16 @@ def layout3():
|
|||
items in one list are added to the items in another. That's true for all these contructs using +
|
||||
"""
|
||||
|
||||
|
||||
def layout4():
|
||||
layout = [[sg.Text('Enter some info')] + [sg.Input()] + [sg.Exit()]]
|
||||
layout = [[sg.Text('Enter some info')] + [sg.Input()] + [sg.Exit()]]
|
||||
|
||||
window = sg.Window('Generated Layouts', layout)
|
||||
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -147,20 +156,24 @@ def layout4():
|
|||
Works as long as the things you are adding together look like this [[ ]] (the famous double bracket layouts of PSG)
|
||||
"""
|
||||
|
||||
|
||||
def layout5():
|
||||
questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
|
||||
'Get along with people in your family?', 'Get along with people outside your family?',
|
||||
'Get along well in social situations?', 'Feel close to another person',
|
||||
'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
|
||||
|
||||
layout = [[sg.T(qnum + 1, size=(2, 2)), sg.T(q, size=(30, 2))] + [sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)] for qnum, q in enumerate(questions)]
|
||||
layout = [[sg.Text(qnum + 1, size=(2, 2)), sg.Text(q, size=(30, 2))] +
|
||||
[sg.Radio('', group_id=qnum, size=(7, 2),
|
||||
key=(qnum, col)) for col in range(5)]
|
||||
for qnum, q in enumerate(questions)]
|
||||
layout += [[sg.OK()]]
|
||||
|
||||
window = sg.Window('Computed Layout Questionnaire', layout)
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -181,20 +194,26 @@ def layout6():
|
|||
'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
|
||||
|
||||
layout = [[]]
|
||||
for qnum, question in enumerate(questions): # loop through questions
|
||||
row_layout = [sg.T(qnum + 1, size=(2, 2)), sg.T(question, size=(30, 2))] # rows start with # and question
|
||||
for radio_num in range(5): # loop through 5 radio buttons and add to row
|
||||
row_layout += [sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, radio_num))]
|
||||
layout += [row_layout] # after row is completed layout, tack it onto the end of final layout
|
||||
for qnum, question in enumerate(questions):
|
||||
# rows start with # and question
|
||||
row_layout = [sg.Text(qnum + 1, size=(2, 2)),
|
||||
sg.Text(question, size=(30, 2))]
|
||||
|
||||
layout += [[sg.OK()]] # and finally, add a row to the bottom that has an OK button
|
||||
# loop through 5 radio buttons and add to row
|
||||
for radio_num in range(5):
|
||||
row_layout += [sg.Radio('', group_id=qnum,
|
||||
size=(7, 2), key=(qnum, radio_num))]
|
||||
# after row is completed layout, tack it onto the end of final layout
|
||||
layout += [row_layout]
|
||||
|
||||
# and finally, add a row to the bottom that has an OK button
|
||||
layout += [[sg.OK()]]
|
||||
|
||||
window = sg.Window('Computed Layout Questionnaire', layout)
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -223,21 +242,24 @@ def layout6():
|
|||
variable number of rows and a variable number of columns in each row.
|
||||
"""
|
||||
|
||||
|
||||
def layout7():
|
||||
questions = ('Managing your day-to-day life', 'Coping with problems in your life?', 'Concentrating?',
|
||||
'Get along with people in your family?', 'Get along with people outside your family?',
|
||||
'Get along well in social situations?', 'Feel close to another person',
|
||||
'Feel like you had someone to turn to if you needed help?', 'Felt confident in yourself?')
|
||||
|
||||
layout = [[*[sg.T(qnum + 1, size=(2, 2)), sg.T(q, size=(30, 2))], # These are the question # and the question text
|
||||
*[sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)]] for qnum, q in enumerate(questions)] + [[sg.OK()]] # finally add an OK button at the very bottom by using the '+' operator
|
||||
# These are the question # and the question text
|
||||
layout = [[*[sg.Text(qnum + 1, size=(2, 2)), sg.Text(q, size=(30, 2))],
|
||||
# finally add an OK button at the very bottom by using the '+' operator
|
||||
*[sg.Radio('', group_id=qnum, size=(7, 2), key=(qnum, col)) for col in range(5)]] for qnum, q in enumerate(questions)] + [[sg.OK()]]
|
||||
|
||||
window = sg.Window('Questionnaire', layout)
|
||||
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
|
||||
print(event, values)
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
"""
|
||||
|
@ -249,20 +271,25 @@ def layout7():
|
|||
In this example we start with a "Header" Text element and build from there.
|
||||
"""
|
||||
|
||||
|
||||
def layout8():
|
||||
# The questions and answers
|
||||
q_and_a = [
|
||||
['1. What is the thing that makes light in our solar system', ['A. The Moon', 'B. Jupiter', 'C. I dunno']],
|
||||
['2. What is Pluto', ['A. The 9th planet', 'B. A dwarf-planet', 'C. The 8th planet', 'D. Goofies pet dog']],
|
||||
['1. What is the thing that makes light in our solar system',
|
||||
['A. The Moon', 'B. Jupiter', 'C. I dunno']],
|
||||
['2. What is Pluto', ['A. The 9th planet', 'B. A dwarf-planet',
|
||||
'C. The 8th planet', 'D. Goofies pet dog']],
|
||||
['3. When did man step foot on the moon', ['A. 1969', 'B. 1960', 'C. 1970', 'D. 1869']], ]
|
||||
|
||||
layout = [[sg.Text('Astronomy Quiz #1', font='ANY 15', size=(30, 2))]] # make Header larger
|
||||
# make Header larger
|
||||
layout = [[sg.Text('Astronomy Quiz #1', font='ANY 15', size=(30, 2))]]
|
||||
|
||||
# "generate" the layout for the window based on the Question and Answer information
|
||||
for qa in q_and_a:
|
||||
q = qa[0]
|
||||
a_list = qa[1]
|
||||
layout += [[sg.Text(q)]] + [[sg.Radio(a, group_id=q)] for a in a_list] + [[sg.Text('_' * 50)]]
|
||||
layout += [[sg.Text(q)]] + [[sg.Radio(a, group_id=q)]
|
||||
for a in a_list] + [[sg.Text('_' * 50)]]
|
||||
|
||||
layout += [[sg.Button('Submit Answers', key='SUBMIT')]]
|
||||
|
||||
|
@ -279,11 +306,11 @@ def layout8():
|
|||
# ------------------------- Call each of the Constructs -------------------------
|
||||
|
||||
layout0()
|
||||
layout1()
|
||||
layout2()
|
||||
layout3()
|
||||
layout4()
|
||||
layout5()
|
||||
layout6()
|
||||
layout7()
|
||||
layout8()
|
||||
# layout1()
|
||||
# layout2()
|
||||
# layout3()
|
||||
# layout4()
|
||||
# layout5()
|
||||
# layout6()
|
||||
# layout7()
|
||||
# layout8()
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
import PySimpleGUI as sg
|
||||
|
||||
names = ['Roberta', 'Kylie', 'Jenny', 'Helen',
|
||||
'Andrea', 'Meredith','Deborah','Pauline',
|
||||
'Belinda', 'Wendy']
|
||||
'Andrea', 'Meredith', 'Deborah', 'Pauline',
|
||||
'Belinda', 'Wendy']
|
||||
|
||||
layout = [ [sg.Text('Listbox with search')],
|
||||
[sg.Input(do_not_clear=True, size=(20,1),enable_events=True, key='_INPUT_')],
|
||||
[sg.Listbox(names, size=(20,4), enable_events=True, key='_LIST_')],
|
||||
[sg.Button('Chrome'), sg.Button('Exit')]]
|
||||
layout = [[sg.Text('Listbox with search')],
|
||||
[sg.Input(size=(20, 1), enable_events=True, key='-INPUT-')],
|
||||
[sg.Listbox(names, size=(20, 4), enable_events=True, key='-LIST-')],
|
||||
[sg.Button('Chrome'), sg.Button('Exit')]]
|
||||
|
||||
window = sg.Window('Listbox with Search').Layout(layout)
|
||||
window = sg.Window('Listbox with Search', layout)
|
||||
# Event Loop
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
if event is None or event == 'Exit': # always check for closed window
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'): # always check for closed window
|
||||
break
|
||||
if values['_INPUT_'] != '': # if a keystroke entered in search field
|
||||
search = values['_INPUT_']
|
||||
if values['-INPUT-'] != '': # if a keystroke entered in search field
|
||||
search = values['-INPUT-']
|
||||
new_values = [x for x in names if search in x] # do the filtering
|
||||
window.Element('_LIST_').Update(new_values) # display in the listbox
|
||||
window['-LIST-'].update(new_values) # display in the listbox
|
||||
else:
|
||||
window.Element('_LIST_').Update(names) # display original unfiltered list
|
||||
if event == '_LIST_' and len(values['_LIST_']): # if a list item is chosen
|
||||
sg.Popup('Selected ', values['_LIST_'])
|
||||
# display original unfiltered list
|
||||
window['-LIST-'].update(names)
|
||||
# if a list item is chosen
|
||||
if event == '-LIST-' and len(values['-LIST-']):
|
||||
sg.popup('Selected ', values['-LIST-'])
|
||||
|
||||
window.Close()
|
||||
window.close()
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
import os
|
||||
import mido
|
||||
import time
|
||||
import sys
|
||||
|
||||
PLAYER_COMMAND_NONE = 0
|
||||
PLAYER_COMMAND_EXIT = 1
|
||||
|
@ -18,6 +13,8 @@ PLAYER_COMMAND_RESTART_SONG = 4
|
|||
# ---------------------------------------------------------------------- #
|
||||
# PlayerGUI CLASS #
|
||||
# ---------------------------------------------------------------------- #
|
||||
|
||||
|
||||
class PlayerGUI():
|
||||
'''
|
||||
Class implementing GUI for both initial screen but the player itself
|
||||
|
@ -26,8 +23,10 @@ class PlayerGUI():
|
|||
def __init__(self):
|
||||
self.Window = None
|
||||
self.TextElem = None
|
||||
self.PortList = mido.get_output_names() # use to get the list of midi ports
|
||||
self.PortList = self.PortList[::-1] # reverse the list so the last one is first
|
||||
# use to get the list of midi ports
|
||||
self.PortList = mido.get_output_names()
|
||||
# reverse the list so the last one is first
|
||||
self.PortList = self.PortList[::-1]
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# PlayerChooseSongGUI #
|
||||
|
@ -37,20 +36,27 @@ class PlayerGUI():
|
|||
|
||||
# ---------------------- DEFINION OF CHOOSE WHAT TO PLAY GUI ----------------------------
|
||||
|
||||
layout = [[sg.Text('MIDI File Player', font=("Helvetica", 15), size=(20, 1), text_color='green')],
|
||||
[sg.Text('File Selection', font=("Helvetica", 15), size=(20, 1))],
|
||||
[sg.Text('Single File Playback', justification='right'), sg.InputText(size=(65, 1), key='midifile'), sg.FileBrowse(size=(10, 1), file_types=(("MIDI files", "*.mid"),))],
|
||||
[sg.Text('Or Batch Play From This Folder', auto_size_text=False, justification='right'), sg.InputText(size=(65, 1), key='folder'), sg.FolderBrowse(size=(10, 1))],
|
||||
helv = ("Helvetica", 15)
|
||||
layout = [[sg.Text('MIDI File Player', font=helv15, size=(20, 1), text_color='green')],
|
||||
[sg.Text('File Selection', font=helv15, size=(20, 1))],
|
||||
[sg.Text('Single File Playback', justification='right'),
|
||||
sg.InputText(size=(65, 1), key='midifile'),
|
||||
sg.FileBrowse(size=(10, 1), file_types=(("MIDI files", "*.mid"),))],
|
||||
[sg.Text('Or Batch Play From This Folder', auto_size_text=False, justification='right'),
|
||||
sg.InputText(size=(65, 1), key='folder'),
|
||||
sg.FolderBrowse(size=(10, 1))],
|
||||
[sg.Text('_' * 250, auto_size_text=False, size=(100, 1))],
|
||||
[sg.Text('Choose MIDI Output Device', size=(22, 1)),
|
||||
sg.Listbox(values=self.PortList, size=(30, len(self.PortList) + 1), key='device')],
|
||||
[sg.Text('_' * 250, auto_size_text=False, size=(100, 1))],
|
||||
[sg.SimpleButton('PLAY', size=(12, 2), button_color=('red', 'white'), font=("Helvetica", 15), bind_return_key=True), sg.Text(' ' * 2, size=(4, 1)), sg.Cancel(size=(8, 2), font=("Helvetica", 15))]]
|
||||
[sg.SimpleButton('PLAY', size=(12, 2), button_color=('red', 'white'), font=helv15, bind_return_key=True),
|
||||
sg.Text(' ' * 2, size=(4, 1)),
|
||||
sg.Cancel(size=(8, 2), font=helv15)]]
|
||||
|
||||
window = sg.Window('MIDI File Player', auto_size_text=False, default_element_size=(30, 1), font=("Helvetica", 12)).Layout(layout)
|
||||
window = sg.Window('MIDI File Player', layout, auto_size_text=False,
|
||||
default_element_size=(30, 1), font=helv)
|
||||
self.Window = window
|
||||
return window.Read()
|
||||
|
||||
return window.read()
|
||||
|
||||
def PlayerPlaybackGUIStart(self, NumFiles=1):
|
||||
# ------- Make a new FlexForm ------- #
|
||||
|
@ -60,37 +66,44 @@ class PlayerGUI():
|
|||
image_next = './ButtonGraphics/Next.png'
|
||||
image_exit = './ButtonGraphics/Exit.png'
|
||||
|
||||
self.TextElem = sg.T('Song loading....', size=(70, 5 + NumFiles), font=("Helvetica", 14), auto_size_text=False)
|
||||
self.SliderElem = sg.Slider(range=(1, 100), size=(50, 8), orientation='h', text_color='#f0f0f0')
|
||||
self.TextElem = sg.Text('Song loading....',
|
||||
size=(70, 5 + NumFiles),
|
||||
font=("Helvetica", 14), auto_size_text=False)
|
||||
self.SliderElem = sg.Slider(range=(1, 100),
|
||||
size=(50, 8),
|
||||
orientation='h', text_color='#f0f0f0')
|
||||
css = {
|
||||
'image_size': (50, 50),
|
||||
'image_subsample': 2,
|
||||
'border_width': 0,
|
||||
'button_color': sg.TRANSPARENT_BUTTON
|
||||
}
|
||||
layout = [
|
||||
[sg.T('MIDI File Player', size=(30, 1), font=("Helvetica", 25))],
|
||||
[self.TextElem],
|
||||
[self.SliderElem],
|
||||
[sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
|
||||
image_filename=image_pause, image_size=(50,50), image_subsample=2, border_width=0, key='PAUSE'), sg.T(' '),
|
||||
sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
|
||||
image_filename=image_next, image_size=(50,50), image_subsample=2, border_width=0, key='NEXT'), sg.T(' '),
|
||||
sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
|
||||
image_filename=image_restart, image_size=(50,50), image_subsample=2, border_width=0, key='Restart Song'), sg.T(' '),
|
||||
sg.Button('', button_color=sg.TRANSPARENT_BUTTON,
|
||||
image_filename=image_exit, image_size=(50,50), image_subsample=2, border_width=0,key='EXIT')]
|
||||
]
|
||||
[sg.Text('MIDI File Player', size=(30, 1), font=("Helvetica", 25))],
|
||||
[self.TextElem],
|
||||
[self.SliderElem],
|
||||
[sg.Button('', image_filename=image_pause, **css, key='PAUSE'), sg.Text(' '),
|
||||
sg.Button('', image_filename=image_next, **css, key='NEXT'), sg.Text(' '),
|
||||
sg.Button('', image_filename=image_restart, **css, key='Restart Song'), sg.Text(' '),
|
||||
sg.Button('', image_filename=image_exit, **css, key='EXIT')]
|
||||
]
|
||||
|
||||
window = sg.Window('MIDI File Player', default_element_size=(30, 1), font=("Helvetica", 25)).Layout(layout).Finalize()
|
||||
window = sg.Window('MIDI File Player', layout, default_element_size=(
|
||||
30, 1), font=("Helvetica", 25), finalize=True)
|
||||
self.Window = window
|
||||
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------- #
|
||||
# PlayerPlaybackGUIUpdate #
|
||||
# Refresh the GUI for the main playback interface (must call periodically #
|
||||
# ------------------------------------------------------------------------- #
|
||||
|
||||
def PlayerPlaybackGUIUpdate(self, DisplayString):
|
||||
window = self.Window
|
||||
if 'window' not in locals() or window is None: # if the widnow has been destoyed don't mess with it
|
||||
# if the widnow has been destoyed don't mess with it
|
||||
if 'window' not in locals() or window is None:
|
||||
return PLAYER_COMMAND_EXIT
|
||||
self.TextElem.Update(DisplayString)
|
||||
event, (values) = window.Read(timeout=0)
|
||||
self.TextElem.update(DisplayString)
|
||||
event, (values) = window.read(timeout=0)
|
||||
if event is None:
|
||||
return PLAYER_COMMAND_EXIT
|
||||
if event == 'PAUSE':
|
||||
|
@ -118,38 +131,42 @@ def main():
|
|||
'''
|
||||
return int(round(time.time() * 1000))
|
||||
|
||||
|
||||
pback = PlayerGUI()
|
||||
|
||||
button, values = pback.PlayerChooseSongGUI()
|
||||
if button != 'PLAY':
|
||||
sg.PopupCancel('Cancelled...\nAutoclose in 2 sec...', auto_close=True, auto_close_duration=2)
|
||||
sys.exit(69)
|
||||
sg.popup_cancel('Cancelled...\nAutoclose in 2 sec...',
|
||||
auto_close=True, auto_close_duration=2)
|
||||
return
|
||||
if values['device']:
|
||||
midi_port = values['device'][0]
|
||||
else:
|
||||
sg.PopupCancel('No devices found\nAutoclose in 2 sec...', auto_close=True, auto_close_duration=2)
|
||||
sg.popup_cancel('No devices found\nAutoclose in 2 sec...',
|
||||
auto_close=True, auto_close_duration=2)
|
||||
|
||||
batch_folder = values['folder']
|
||||
midi_filename = values['midifile']
|
||||
# ------ Build list of files to play --------------------------------------------------------- #
|
||||
if batch_folder:
|
||||
filelist = os.listdir(batch_folder)
|
||||
filelist = [batch_folder+'/'+f for f in filelist if f.endswith(('.mid', '.MID'))]
|
||||
filelist = [batch_folder+'/' +
|
||||
f for f in filelist if f.endswith(('.mid', '.MID'))]
|
||||
filetitles = [os.path.basename(f) for f in filelist]
|
||||
elif midi_filename: # an individual filename
|
||||
filelist = [midi_filename,]
|
||||
filetitles = [os.path.basename(midi_filename),]
|
||||
filelist = [midi_filename, ]
|
||||
filetitles = [os.path.basename(midi_filename), ]
|
||||
else:
|
||||
sg.PopupError('*** Error - No MIDI files specified ***')
|
||||
sys.exit(666)
|
||||
sg.popup_error('*** Error - No MIDI files specified ***')
|
||||
return
|
||||
|
||||
# ------ LOOP THROUGH MULTIPLE FILES --------------------------------------------------------- #
|
||||
pback.PlayerPlaybackGUIStart(NumFiles=len(filelist) if len(filelist) <=10 else 10)
|
||||
pback.PlayerPlaybackGUIStart(NumFiles=len(filelist) if len(filelist) <= 10 else 10)
|
||||
port = None
|
||||
|
||||
# Loop through the files in the filelist
|
||||
for now_playing_number, current_midi_filename in enumerate(filelist):
|
||||
display_string = 'Playing Local File...\n{} of {}\n{}'.format(now_playing_number+1, len(filelist), current_midi_filename)
|
||||
display_string = 'Playing Local File...\n{} of {}\n{}'.format(
|
||||
now_playing_number+1, len(filelist), current_midi_filename)
|
||||
midi_title = filetitles[now_playing_number]
|
||||
# --------------------------------- REFRESH THE GUI ----------------------------------------- #
|
||||
pback.PlayerPlaybackGUIUpdate(display_string)
|
||||
|
@ -164,16 +181,19 @@ def main():
|
|||
try:
|
||||
mid = mido.MidiFile(filename=midi_filename)
|
||||
except:
|
||||
print('****** Exception trying to play MidiFile filename = {}***************'.format(midi_filename))
|
||||
sg.PopupError('Exception trying to play MIDI file:', midi_filename, 'Skipping file')
|
||||
print(' Fail at playing Midi file = {}****'.format(midi_filename))
|
||||
sg.popup_error('Exception trying to play MIDI file:',
|
||||
midi_filename, 'Skipping file')
|
||||
continue
|
||||
|
||||
# Build list of data contained in MIDI File using only track 0
|
||||
midi_length_in_seconds = mid.length
|
||||
display_file_list = '>> ' + '\n'.join([f for i, f in enumerate(filetitles[now_playing_number:]) if i < 10])
|
||||
display_file_list = '>> ' + \
|
||||
'\n'.join([f for i, f in enumerate(
|
||||
filetitles[now_playing_number:]) if i < 10])
|
||||
paused = cancelled = next_file = False
|
||||
######################### Loop through MIDI Messages ###########################
|
||||
while(True):
|
||||
while True :
|
||||
start_playback_time = GetCurrentTime()
|
||||
port.reset()
|
||||
|
||||
|
@ -181,12 +201,14 @@ def main():
|
|||
#################### GUI - read values ##################
|
||||
if not midi_msg_number % 4: # update the GUI every 4 MIDI messages
|
||||
t = (GetCurrentTime() - start_playback_time)//1000
|
||||
display_midi_len = '{:02d}:{:02d}'.format(*divmod(int(midi_length_in_seconds),60))
|
||||
display_midi_len = '{:02d}:{:02d}'.format(
|
||||
*divmod(int(midi_length_in_seconds), 60))
|
||||
display_string = 'Now Playing {} of {}\n{}\n {:02d}:{:02d} of {}\nPlaylist:'.\
|
||||
format(now_playing_number+1, len(filelist), midi_title, *divmod(t, 60), display_midi_len)
|
||||
# display list of next 10 files to be played.
|
||||
pback.SliderElem.Update(t, range=(1,midi_length_in_seconds))
|
||||
rc = pback.PlayerPlaybackGUIUpdate(display_string + '\n' + display_file_list)
|
||||
# display list of next 10 files to be played.
|
||||
pback.SliderElem.update(t, range=(1, midi_length_in_seconds))
|
||||
rc = pback.PlayerPlaybackGUIUpdate(
|
||||
display_string + '\n' + display_file_list)
|
||||
else: # fake rest of code as if GUI did nothing
|
||||
rc = PLAYER_COMMAND_NONE
|
||||
if paused:
|
||||
|
@ -219,9 +241,9 @@ def main():
|
|||
if cancelled:
|
||||
break
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# LAUNCH POINT -- program starts and ends here #
|
||||
# ---------------------------------------------------------------------- #
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
|
@ -1,65 +1,75 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
|
||||
def MachineLearningGUI():
|
||||
sg.SetOptions(text_justification='right')
|
||||
sg.set_options(text_justification='right')
|
||||
|
||||
flags = [[sg.Checkbox('Normalize', size=(12, 1), default=True), sg.Checkbox('Verbose', size=(20, 1))],
|
||||
[sg.Checkbox('Cluster', size=(12, 1)), sg.Checkbox('Flush Output', size=(20, 1), default=True)],
|
||||
[sg.Checkbox('Write Results', size=(12, 1)), sg.Checkbox('Keep Intermediate Data', size=(20, 1))],
|
||||
[sg.Checkbox('Normalize', size=(12, 1), default=True), sg.Checkbox('Verbose', size=(20, 1))],
|
||||
[sg.Checkbox('Cluster', size=(12, 1)), sg.Checkbox('Flush Output', size=(20, 1), default=True)],
|
||||
[sg.Checkbox('Write Results', size=(12, 1)), sg.Checkbox('Keep Intermediate Data', size=(20, 1))],]
|
||||
flags = [[sg.CB('Normalize', size=(12, 1), default=True), sg.CB('Verbose', size=(20, 1))],
|
||||
[sg.CB('Cluster', size=(12, 1)), sg.CB(
|
||||
'Flush Output', size=(20, 1), default=True)],
|
||||
[sg.CB('Write Results', size=(12, 1)), sg.CB(
|
||||
'Keep Intermediate Data', size=(20, 1))],
|
||||
[sg.CB('Normalize', size=(12, 1), default=True),
|
||||
sg.CB('Verbose', size=(20, 1))],
|
||||
[sg.CB('Cluster', size=(12, 1)), sg.CB(
|
||||
'Flush Output', size=(20, 1), default=True)],
|
||||
[sg.CB('Write Results', size=(12, 1)), sg.CB('Keep Intermediate Data', size=(20, 1))], ]
|
||||
|
||||
loss_functions = [[sg.Radio('Cross-Entropy', 'loss', size=(12, 1)), sg.Radio('Logistic', 'loss', default=True, size=(12, 1))],
|
||||
[sg.Radio('Hinge', 'loss', size=(12, 1)), sg.Radio('Huber', 'loss', size=(12, 1))],
|
||||
[sg.Radio('Kullerback', 'loss', size=(12, 1)), sg.Radio('MAE(L1)', 'loss', size=(12, 1))],
|
||||
[sg.Radio('MSE(L2)', 'loss', size=(12, 1)), sg.Radio('MB(L0)', 'loss', size=(12, 1))],]
|
||||
loss_functions = [[sg.Rad('Cross-Entropy', 'loss', size=(12, 1)), sg.Rad('Logistic', 'loss', default=True, size=(12, 1))],
|
||||
[sg.Rad('Hinge', 'loss', size=(12, 1)),
|
||||
sg.Rad('Huber', 'loss', size=(12, 1))],
|
||||
[sg.Rad('Kullerback', 'loss', size=(12, 1)),
|
||||
sg.Rad('MAE(L1)', 'loss', size=(12, 1))],
|
||||
[sg.Rad('MSE(L2)', 'loss', size=(12, 1)), sg.Rad('MB(L0)', 'loss', size=(12, 1))], ]
|
||||
|
||||
command_line_parms = [[sg.Text('Passes', size=(8, 1)), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1)),
|
||||
sg.Text('Steps', size=(8, 1), pad=((7,3))), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1))],
|
||||
[sg.Text('ooa', size=(8, 1)), sg.In(default_text='6', size=(8, 1)), sg.Text('nn', size=(8, 1)),
|
||||
sg.In(default_text='10', size=(10, 1))],
|
||||
[sg.Text('q', size=(8, 1)), sg.In(default_text='ff', size=(8, 1)), sg.Text('ngram', size=(8, 1)),
|
||||
sg.In(default_text='5', size=(10, 1))],
|
||||
[sg.Text('l', size=(8, 1)), sg.In(default_text='0.4', size=(8, 1)), sg.Text('Layers', size=(8, 1)),
|
||||
sg.Drop(values=('BatchNorm', 'other'), auto_size_text=True)],]
|
||||
sg.Text('Steps', size=(8, 1), pad=((7, 3))), sg.Spin(values=[i for i in range(1, 1000)], initial_value=20, size=(6, 1))],
|
||||
[sg.Text('ooa', size=(8, 1)), sg.Input(default_text='6', size=(8, 1)), sg.Text('nn', size=(8, 1)),
|
||||
sg.Input(default_text='10', size=(10, 1))],
|
||||
[sg.Text('q', size=(8, 1)), sg.Input(default_text='ff', size=(8, 1)), sg.Text('ngram', size=(8, 1)),
|
||||
sg.Input(default_text='5', size=(10, 1))],
|
||||
[sg.Text('l', size=(8, 1)), sg.Input(default_text='0.4', size=(8, 1)), sg.Text('Layers', size=(8, 1)),
|
||||
sg.Drop(values=('BatchNorm', 'other'))], ]
|
||||
|
||||
layout = [[sg.Frame('Command Line Parameteres', command_line_parms, title_color='green', font='Any 12')],
|
||||
[sg.Frame('Flags', flags, font='Any 12', title_color='blue')],
|
||||
[sg.Frame('Loss Functions', loss_functions, font='Any 12', title_color='red')],
|
||||
[sg.Frame('Loss Functions', loss_functions,
|
||||
font='Any 12', title_color='red')],
|
||||
[sg.Submit(), sg.Cancel()]]
|
||||
|
||||
window = sg.Window('Machine Learning Front End', font=("Helvetica", 12)).Layout(layout)
|
||||
button, values = window.Read()
|
||||
sg.SetOptions(text_justification='left')
|
||||
sg.set_options(text_justification='left')
|
||||
|
||||
window = sg.Window('Machine Learning Front End',
|
||||
layout, font=("Helvetica", 12))
|
||||
button, values = window.read()
|
||||
window.close()
|
||||
print(button, values)
|
||||
|
||||
|
||||
def CustomMeter():
|
||||
# layout the form
|
||||
layout = [[sg.Text('A custom progress meter')],
|
||||
[sg.ProgressBar(1000, orientation='h', size=(20,20), key='progress')],
|
||||
[sg.ProgressBar(1000, orientation='h',
|
||||
size=(20, 20), key='progress')],
|
||||
[sg.Cancel()]]
|
||||
|
||||
# create the form`
|
||||
window = sg.Window('Custom Progress Meter').Layout(layout)
|
||||
progress_bar = window.FindElement('progress')
|
||||
window = sg.Window('Custom Progress Meter', layout)
|
||||
progress_bar = window['progress']
|
||||
# loop that would normally do something useful
|
||||
for i in range(1000):
|
||||
# check to see if the cancel button was clicked and exit loop if clicked
|
||||
event, values = window.Read(timeout=0, timeout_key='timeout')
|
||||
event, values = window.read(timeout=0, timeout_key='timeout')
|
||||
if event == 'Cancel' or event == None:
|
||||
break
|
||||
# update bar with loop value +1 so that bar eventually reaches the maximum
|
||||
progress_bar.UpdateBar(i+1)
|
||||
progress_bar.update_bar(i+1)
|
||||
# done with loop... need to destroy the window as it's still open
|
||||
window.CloseNonBlocking()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
CustomMeter()
|
||||
MachineLearningGUI()
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
from matplotlib.ticker import NullFormatter # useful for `logit` scale
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('TkAgg')
|
||||
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
|
||||
"""
|
||||
Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
|
||||
|
||||
|
@ -21,12 +22,7 @@ Basic steps are:
|
|||
"""
|
||||
|
||||
|
||||
#------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from matplotlib.ticker import NullFormatter # useful for `logit` scale
|
||||
# ------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
|
||||
|
||||
# Fixing random state for reproducibility
|
||||
np.random.seed(19680801)
|
||||
|
@ -75,9 +71,9 @@ plt.subplots_adjust(top=0.92, bottom=0.08, left=0.10, right=0.95, hspace=0.25,
|
|||
fig = plt.gcf() # if using Pyplot then get the figure from the plot
|
||||
figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
|
||||
|
||||
#------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
|
||||
# ------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
|
||||
|
||||
#------------------------------- Beginning of Matplotlib helper code -----------------------
|
||||
# ------------------------------- Beginning of Matplotlib helper code -----------------------
|
||||
|
||||
|
||||
def draw_figure(canvas, figure, loc=(0, 0)):
|
||||
|
@ -85,7 +81,8 @@ def draw_figure(canvas, figure, loc=(0, 0)):
|
|||
figure_canvas_agg.draw()
|
||||
figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
|
||||
return figure_canvas_agg
|
||||
#------------------------------- Beginning of GUI CODE -------------------------------
|
||||
# ------------------------------- Beginning of GUI CODE -------------------------------
|
||||
|
||||
|
||||
# define the window layout
|
||||
layout = [[sg.Text('Plot test', font='Any 18')],
|
||||
|
@ -93,9 +90,12 @@ layout = [[sg.Text('Plot test', font='Any 18')],
|
|||
[sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]]
|
||||
|
||||
# create the form and show it without the plot
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',
|
||||
layout, finalize=True)
|
||||
|
||||
# add the plot to the window
|
||||
fig_canvas_agg = draw_figure(window['canvas'].TKCanvas, fig)
|
||||
|
||||
event, values = window.read()
|
||||
|
||||
window.close()
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#!/usr/bin/env python
|
||||
import PySimpleGUI as sg
|
||||
|
||||
from random import randint
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
# Yet another usage of MatPlotLib with animations.
|
||||
|
||||
def draw_figure(canvas, figure, loc=(0, 0)):
|
||||
figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
|
||||
figure_canvas_agg.draw()
|
||||
|
@ -15,19 +16,23 @@ def main():
|
|||
|
||||
NUM_DATAPOINTS = 10000
|
||||
# define the form layout
|
||||
layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')],
|
||||
layout = [[sg.Text('Animated Matplotlib', size=(40, 1),
|
||||
justification='center', font='Helvetica 20')],
|
||||
[sg.Canvas(size=(640, 480), key='-CANVAS-')],
|
||||
[sg.Text('Progress through the data')],
|
||||
[sg.Slider(range=(0, NUM_DATAPOINTS), size=(60, 10), orientation='h', key='-SLIDER-')],
|
||||
[sg.Slider(range=(0, NUM_DATAPOINTS), size=(60, 10),
|
||||
orientation='h', key='-SLIDER-')],
|
||||
[sg.Text('Number of data points to display on screen')],
|
||||
[sg.Slider(range=(10, 500), default_value=40, size=(40, 10), orientation='h', key='-SLIDER-DATAPOINTS-')],
|
||||
[sg.Slider(range=(10, 500), default_value=40, size=(40, 10),
|
||||
orientation='h', key='-SLIDER-DATAPOINTS-')],
|
||||
[sg.Button('Exit', size=(10, 1), pad=((280, 0), 3), font='Helvetica 14')]]
|
||||
|
||||
# create the form and show it without the plot
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',
|
||||
layout, finalize=True)
|
||||
|
||||
canvas_elem = window.FindElement('-CANVAS-')
|
||||
slider_elem = window.FindElement('-SLIDER-')
|
||||
canvas_elem = window['-CANVAS-']
|
||||
slider_elem = window['-SLIDER-']
|
||||
canvas = canvas_elem.TKCanvas
|
||||
|
||||
# draw the initial plot in the window
|
||||
|
@ -41,16 +46,18 @@ def main():
|
|||
dpts = [randint(0, 10) for x in range(NUM_DATAPOINTS)]
|
||||
|
||||
for i in range(len(dpts)):
|
||||
event, values = window.Read(timeout=10)
|
||||
|
||||
event, values = window.read(timeout=10)
|
||||
if event in ('Exit', None):
|
||||
exit(69)
|
||||
slider_elem.Update(i) # slider shows "progress" through the data points
|
||||
slider_elem.update(i) # slider shows "progress" through the data points
|
||||
ax.cla() # clear the subplot
|
||||
ax.grid() # draw the grid
|
||||
data_points = int(values['-SLIDER-DATAPOINTS-']) # draw this many data points (on next line)
|
||||
ax.plot(range(data_points), dpts[i:i+data_points], color='purple')
|
||||
fig_agg.draw()
|
||||
|
||||
window.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
import PySimpleGUI as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
import matplotlib.pyplot as plt
|
||||
|
@ -12,9 +10,6 @@ def draw_figure(canvas, figure):
|
|||
figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
|
||||
return figure_canvas_agg
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
# define the form layout
|
||||
layout = [[sg.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')],
|
||||
|
@ -24,7 +19,7 @@ def main():
|
|||
# create the form and show it without the plot
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
|
||||
|
||||
canvas_elem = window.FindElement('-CANVAS-')
|
||||
canvas_elem = window['-CANVAS-']
|
||||
canvas = canvas_elem.TKCanvas
|
||||
# draw the intitial scatter plot
|
||||
fig, ax = plt.subplots()
|
||||
|
@ -32,7 +27,7 @@ def main():
|
|||
fig_agg = draw_figure(canvas, fig)
|
||||
|
||||
while True:
|
||||
event, values = window.Read(timeout=10)
|
||||
event, values = window.read(timeout=10)
|
||||
if event in ('Exit', None):
|
||||
exit(69)
|
||||
|
||||
|
@ -45,6 +40,7 @@ def main():
|
|||
ax.scatter(x, y, c=color, s=scale, label=color, alpha=0.3, edgecolors='none')
|
||||
ax.legend()
|
||||
fig_agg.draw()
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/env python
|
||||
import PySimpleGUI as sg
|
||||
import matplotlib
|
||||
matplotlib.use('TkAgg')
|
||||
import inspect
|
||||
matplotlib.use('TkAgg')
|
||||
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
|
||||
|
@ -846,17 +846,17 @@ fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'Py
|
|||
'Pyplot Scatter With Legend' :PyplotScatterWithLegend, 'Artist Customized Box Plots' : PyplotArtistBoxPlots,
|
||||
'Artist Customized Box Plots 2' : ArtistBoxplot2, 'Pyplot Histogram' : PyplotHistogram}
|
||||
|
||||
sg.ChangeLookAndFeel('LightGreen')
|
||||
sg.change_look_and_feel('LightGreen')
|
||||
|
||||
figure_w, figure_h = 650, 650
|
||||
# define the form layout
|
||||
listbox_values = list(fig_dict)
|
||||
col_listbox = [[sg.Listbox(values=listbox_values, enable_events=True, size=(28, len(listbox_values)), key='-LISTBOX-')],
|
||||
[sg.T(' ' * 12), sg.Exit(size=(5, 2))]]
|
||||
[sg.Text(' ' * 12), sg.Exit(size=(5, 2))]]
|
||||
|
||||
layout = [[sg.Text('Matplotlib Plot Test', font=('current 18'))],
|
||||
[sg.Column(col_listbox, pad=(5, (3, 330))), sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-') ,
|
||||
sg.Multiline(size=(70, 35), pad=(5, (3, 90)), key='-MULTILINE-')],]
|
||||
[sg.Col(col_listbox, pad=(5, (3, 330))), sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-') ,
|
||||
sg.MLine(size=(70, 35), pad=(5, (3, 90)), key='-MULTILINE-')],]
|
||||
|
||||
# create the form and show it without the plot
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI', layout, grab_anywhere=False, finalize=True)
|
||||
|
@ -872,7 +872,7 @@ while True:
|
|||
delete_figure_agg(figure_agg)
|
||||
choice = values['-LISTBOX-'][0] # get first listbox item chosen (returned as a list)
|
||||
func = fig_dict[choice] # get function to call from the dictionary
|
||||
window['-MULTILINE-'].Update(inspect.getsource(func)) # show source code to function in multiline
|
||||
window['-MULTILINE-'].update(inspect.getsource(func)) # show source code to function in multiline
|
||||
fig = func() # call function to get the figure
|
||||
figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig) # draw the figure
|
||||
window.close()
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import inspect
|
||||
import PySimpleGUI as sg
|
||||
import matplotlib
|
||||
matplotlib.use('TkAgg')
|
||||
import inspect
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
||||
|
||||
"""
|
||||
Demonstrates one way of embedding Matplotlib figures into a PySimpleGUI window.
|
||||
|
@ -20,11 +20,6 @@ Basic steps are:
|
|||
"""
|
||||
|
||||
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def PyplotSimple():
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
@ -38,6 +33,7 @@ def PyplotSimple():
|
|||
fig = plt.gcf() # get the figure to show
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotHistogram():
|
||||
"""
|
||||
=============================================================
|
||||
|
@ -87,6 +83,7 @@ def PyplotHistogram():
|
|||
fig.tight_layout()
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotArtistBoxPlots():
|
||||
"""
|
||||
=========================================
|
||||
|
@ -143,6 +140,7 @@ def PyplotArtistBoxPlots():
|
|||
fig.subplots_adjust(hspace=0.4)
|
||||
return fig
|
||||
|
||||
|
||||
def ArtistBoxplot2():
|
||||
|
||||
# fake data
|
||||
|
@ -189,6 +187,7 @@ def ArtistBoxplot2():
|
|||
fig.subplots_adjust(hspace=0.4)
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotScatterWithLegend():
|
||||
import matplotlib.pyplot as plt
|
||||
from numpy.random import rand
|
||||
|
@ -205,6 +204,7 @@ def PyplotScatterWithLegend():
|
|||
ax.grid(True)
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotLineStyles():
|
||||
"""
|
||||
==========
|
||||
|
@ -258,6 +258,7 @@ def PyplotLineStyles():
|
|||
plt.tight_layout()
|
||||
return plt.gcf()
|
||||
|
||||
|
||||
def PyplotLinePolyCollection():
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib import collections, colors, transforms
|
||||
|
@ -361,6 +362,7 @@ def PyplotLinePolyCollection():
|
|||
ax4.set_ylim(ax4.get_ylim()[::-1])
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotGGPlotSytleSheet():
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
@ -405,6 +407,7 @@ def PyplotGGPlotSytleSheet():
|
|||
fig = plt.gcf() # get the figure to show
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotBoxPlot():
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
@ -423,6 +426,7 @@ def PyplotBoxPlot():
|
|||
ax1.boxplot(data)
|
||||
return fig1
|
||||
|
||||
|
||||
def PyplotRadarChart():
|
||||
import numpy as np
|
||||
|
||||
|
@ -609,6 +613,7 @@ def PyplotRadarChart():
|
|||
size='large')
|
||||
return fig
|
||||
|
||||
|
||||
def DifferentScales():
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
@ -629,13 +634,15 @@ def DifferentScales():
|
|||
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
|
||||
|
||||
color = 'tab:blue'
|
||||
ax2.set_ylabel('sin', color=color) # we already handled the x-label with ax1
|
||||
# we already handled the x-label with ax1
|
||||
ax2.set_ylabel('sin', color=color)
|
||||
ax2.plot(t, data2, color=color)
|
||||
ax2.tick_params(axis='y', labelcolor=color)
|
||||
|
||||
fig.tight_layout() # otherwise the right y-label is slightly clipped
|
||||
return fig
|
||||
|
||||
|
||||
def ExploringNormalizations():
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.colors as mcolors
|
||||
|
@ -662,6 +669,7 @@ def ExploringNormalizations():
|
|||
fig.tight_layout()
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotFormatstr():
|
||||
|
||||
def f(t):
|
||||
|
@ -679,6 +687,7 @@ def PyplotFormatstr():
|
|||
fig = plt.gcf() # get the figure to show
|
||||
return fig
|
||||
|
||||
|
||||
def UnicodeMinus():
|
||||
import numpy as np
|
||||
import matplotlib
|
||||
|
@ -693,6 +702,7 @@ def UnicodeMinus():
|
|||
ax.set_title('Using hyphen instead of Unicode minus')
|
||||
return fig
|
||||
|
||||
|
||||
def Subplot3d():
|
||||
from mpl_toolkits.mplot3d.axes3d import Axes3D
|
||||
from matplotlib import cm
|
||||
|
@ -723,6 +733,7 @@ def Subplot3d():
|
|||
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
|
||||
return fig
|
||||
|
||||
|
||||
def PyplotScales():
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
@ -823,12 +834,15 @@ def AxesGrid():
|
|||
return plt.gcf()
|
||||
|
||||
# The magic function that makes it possible.... glues together tkinter and pyplot using Canvas Widget
|
||||
|
||||
|
||||
def draw_figure(canvas, figure):
|
||||
figure_canvas_agg = FigureCanvasTkAgg(figure, canvas)
|
||||
figure_canvas_agg.draw()
|
||||
figure_canvas_agg.get_tk_widget().pack(side='top', fill='both', expand=1)
|
||||
return figure_canvas_agg
|
||||
|
||||
|
||||
def delete_figure_agg(figure_agg):
|
||||
figure_agg.get_tk_widget().forget()
|
||||
plt.close('all')
|
||||
|
@ -842,48 +856,52 @@ def delete_figure_agg(figure_agg):
|
|||
# print(inspect.getsource(PyplotSimple))
|
||||
|
||||
|
||||
fig_dict = {'Pyplot Simple':PyplotSimple, 'Pyplot Formatstr':PyplotFormatstr,'PyPlot Three':Subplot3d,
|
||||
'Unicode Minus': UnicodeMinus, 'Pyplot Scales' : PyplotScales, 'Axes Grid' : AxesGrid,
|
||||
'Exploring Normalizations' : ExploringNormalizations, 'Different Scales' : DifferentScales,
|
||||
'Pyplot Box Plot' : PyplotBoxPlot, 'Pyplot ggplot Style Sheet' : PyplotGGPlotSytleSheet,
|
||||
'Pyplot Line Poly Collection' : PyplotLinePolyCollection, 'Pyplot Line Styles' : PyplotLineStyles,
|
||||
'Pyplot Scatter With Legend' :PyplotScatterWithLegend, 'Artist Customized Box Plots' : PyplotArtistBoxPlots,
|
||||
'Artist Customized Box Plots 2' : ArtistBoxplot2, 'Pyplot Histogram' : PyplotHistogram}
|
||||
fig_dict = {'Pyplot Simple': PyplotSimple, 'Pyplot Formatstr': PyplotFormatstr, 'PyPlot Three': Subplot3d,
|
||||
'Unicode Minus': UnicodeMinus, 'Pyplot Scales': PyplotScales, 'Axes Grid': AxesGrid,
|
||||
'Exploring Normalizations': ExploringNormalizations, 'Different Scales': DifferentScales,
|
||||
'Pyplot Box Plot': PyplotBoxPlot, 'Pyplot ggplot Style Sheet': PyplotGGPlotSytleSheet,
|
||||
'Pyplot Line Poly Collection': PyplotLinePolyCollection, 'Pyplot Line Styles': PyplotLineStyles,
|
||||
'Pyplot Scatter With Legend': PyplotScatterWithLegend, 'Artist Customized Box Plots': PyplotArtistBoxPlots,
|
||||
'Artist Customized Box Plots 2': ArtistBoxplot2, 'Pyplot Histogram': PyplotHistogram}
|
||||
|
||||
|
||||
sg.ChangeLookAndFeel('LightGreen')
|
||||
sg.change_look_and_feel('LightGreen')
|
||||
figure_w, figure_h = 650, 650
|
||||
# define the form layout
|
||||
listbox_values = list(fig_dict)
|
||||
col_listbox = [[sg.Listbox(values=listbox_values, change_submits=True, size=(28, len(listbox_values)), key='-LISTBOX-')],
|
||||
[sg.T(' ' * 12), sg.Exit(size=(5, 2))]]
|
||||
[sg.Text(' ' * 12), sg.Exit(size=(5, 2))]]
|
||||
|
||||
col_multiline = sg.Column([[sg.Multiline(size=(70, 35), key='-MULTILINE-')]])
|
||||
col_canvas = sg.Column([[ sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-')]])
|
||||
col_instructions = sg.Column([[sg.Pane([col_canvas, col_multiline], size=(800,600))],
|
||||
[sg.Text('Grab square above and slide upwards to view source code for graph')]])
|
||||
col_multiline = sg.Col([[sg.MLine(size=(70, 35), key='-MULTILINE-')]])
|
||||
col_canvas = sg.Col([[sg.Canvas(size=(figure_w, figure_h), key='-CANVAS-')]])
|
||||
col_instructions = sg.Col([[sg.Pane([col_canvas, col_multiline], size=(800, 600))],
|
||||
[sg.Text('Grab square above and slide upwards to view source code for graph')]])
|
||||
|
||||
layout = [[sg.Text('Matplotlib Plot Test', font=('ANY 18'))],
|
||||
[sg.Column(col_listbox), col_instructions],]
|
||||
[sg.Col(col_listbox), col_instructions], ]
|
||||
|
||||
# create the form and show it without the plot
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',layout, resizable=True, finalize=True)
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI',
|
||||
layout, resizable=True, finalize=True)
|
||||
|
||||
canvas_elem = window.FindElement('-CANVAS-')
|
||||
multiline_elem= window.FindElement('-MULTILINE-')
|
||||
canvas_elem = window['-CANVAS-']
|
||||
multiline_elem = window['-MULTILINE-']
|
||||
figure_agg = None
|
||||
|
||||
while True:
|
||||
event, values = window.Read()
|
||||
event, values = window.read()
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
|
||||
if figure_agg:
|
||||
# ** IMPORTANT ** Clean up previous drawing before drawing again
|
||||
delete_figure_agg(figure_agg)
|
||||
choice = values['-LISTBOX-'][0] # get first listbox item chosen (returned as a list)
|
||||
func = fig_dict[choice] # get function to call from the dictionary
|
||||
window['-MULTILINE-'].Update(inspect.getsource(func)) # show source code to function in multiline
|
||||
# get first listbox item chosen (returned as a list)
|
||||
choice = values['-LISTBOX-'][0]
|
||||
# get function to call from the dictionary
|
||||
func = fig_dict[choice]
|
||||
# show source code to function in multiline
|
||||
window['-MULTILINE-'].update(inspect.getsource(func))
|
||||
fig = func() # call function to get the figure
|
||||
figure_agg = draw_figure(window['-CANVAS-'].TKCanvas, fig) # draw the figure
|
||||
|
||||
figure_agg = draw_figure(
|
||||
window['-CANVAS-'].TKCanvas, fig) # draw the figure
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import matplotlib.pyplot as plt
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasAgg
|
||||
import matplotlib.backends.tkagg as tkagg
|
||||
import matplotlib.pyplot as plt
|
||||
import PySimpleGUI as sg
|
||||
import tkinter as tk
|
||||
|
||||
|
||||
"""
|
||||
A graph of time to ping Google.com
|
||||
Demonstrates Matploylib used in an animated way.
|
||||
|
@ -646,12 +641,15 @@ def main():
|
|||
global g_my_globals
|
||||
|
||||
# define the form layout
|
||||
layout = [[ sg.Canvas(size=SIZE, background_color='white',key='canvas') , sg.Button('Exit', pad=(0, (210, 0)))]]
|
||||
layout = [
|
||||
[ sg.Canvas(size=SIZE, background_color='white',key='canvas'),
|
||||
sg.Button('Exit', pad=(0, (210, 0)))]
|
||||
]
|
||||
|
||||
# create the form and show it without the plot
|
||||
window = sg.Window('Ping Graph', background_color='white', grab_anywhere=True).Layout(layout).Finalize()
|
||||
window = sg.Window('Ping Graph', layout, background_color='white', grab_anywhere=True, finalize=True)
|
||||
|
||||
canvas_elem = window.FindElement('canvas')
|
||||
canvas_elem = window['canvas']
|
||||
canvas = canvas_elem.TKCanvas
|
||||
|
||||
fig = plt.figure(figsize=(3.1, 2.25), tight_layout={'pad':0})
|
||||
|
@ -662,13 +660,14 @@ def main():
|
|||
plt.tight_layout()
|
||||
|
||||
while True:
|
||||
event, values = window.Read(timeout=0)
|
||||
event, values = window.read(timeout=0)
|
||||
if event in ('Exit', None):
|
||||
exit(0)
|
||||
break
|
||||
|
||||
run_a_ping_and_graph()
|
||||
photo = draw(fig, canvas)
|
||||
|
||||
|
||||
window.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import matplotlib.pyplot as plt
|
||||
import ping
|
||||
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg
|
||||
import matplotlib.backends.tkagg as tkagg
|
||||
import matplotlib.pyplot as plt
|
||||
import PySimpleGUI as sg
|
||||
import tkinter as tk
|
||||
import ping
|
||||
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
# Globals
|
||||
# These are needed because callback functions are used.
|
||||
# Need to retain state across calls
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
|
||||
|
||||
class MyGlobals:
|
||||
axis_pings = None
|
||||
ping_x_array = []
|
||||
ping_y_array = []
|
||||
|
||||
|
||||
g_my_globals = MyGlobals()
|
||||
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
# Performs *** PING! ***
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
|
||||
|
||||
def run_a_ping_and_graph():
|
||||
global g_my_globals # graphs are global so that can be retained across multiple calls to this callback
|
||||
# graphs are global so that can be retained across multiple calls to this callback
|
||||
global g_my_globals
|
||||
|
||||
#===================== Do the ping =====================#
|
||||
response = ping.quiet_ping('google.com',timeout=1000)
|
||||
response = ping.quiet_ping('google.com', timeout=1000)
|
||||
if response[0] == 0:
|
||||
ping_time = 1000
|
||||
else:
|
||||
|
@ -46,21 +48,26 @@ def run_a_ping_and_graph():
|
|||
y_array = g_my_globals.ping_y_array
|
||||
|
||||
# ===================== Call graphinc functions =====================#
|
||||
g_my_globals.axis_ping.clear() # clear before graphing
|
||||
g_my_globals.axis_ping.plot(x_array,y_array) # graph the ping values
|
||||
# clear before graphing
|
||||
g_my_globals.axis_ping.clear()
|
||||
# graph the ping values
|
||||
g_my_globals.axis_ping.plot(x_array, y_array)
|
||||
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
# Function: Set graph titles and Axis labels
|
||||
# Sets the text for the subplots
|
||||
# Have to do this in 2 places... initially when creating and when updating
|
||||
# So, putting into a function so don't have to duplicate code
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
|
||||
|
||||
def set_chart_labels():
|
||||
global g_my_globals
|
||||
|
||||
g_my_globals.axis_ping.set_xlabel('Time')
|
||||
g_my_globals.axis_ping.set_ylabel('Ping (ms)')
|
||||
g_my_globals.axis_ping.set_title('Current Ping Duration', fontsize = 12)
|
||||
g_my_globals.axis_ping.set_title('Current Ping Duration', fontsize=12)
|
||||
|
||||
|
||||
def draw(fig, canvas):
|
||||
# Magic code that draws the figure onto the Canvas Element's canvas
|
||||
|
@ -73,30 +80,34 @@ def draw(fig, canvas):
|
|||
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
|
||||
return photo
|
||||
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
# Function: MAIN
|
||||
#================================================================================
|
||||
# ================================================================================
|
||||
|
||||
|
||||
def main():
|
||||
global g_my_globals
|
||||
|
||||
# define the form layout
|
||||
layout = [[sg.Text('Animated Ping', size=(40, 1), justification='center', font='Helvetica 20')],
|
||||
layout = [[sg.Text('Animated Ping', size=(40, 1),
|
||||
justification='center', font='Helvetica 20')],
|
||||
[sg.Canvas(size=(640, 480), key='canvas')],
|
||||
[sg.Button('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]]
|
||||
|
||||
# create the form and show it without the plot
|
||||
window = sg.Window('Demo Application - Embedding Matplotlib In PySimpleGUI').Layout(layout).Finalize()
|
||||
window = sg.Window(
|
||||
'Demo Application - Embedding Matplotlib In PySimpleGUI', layout, finalize=True)
|
||||
|
||||
canvas_elem = window.FindElement('canvas')
|
||||
canvas_elem = window['canvas']
|
||||
canvas = canvas_elem.TKCanvas
|
||||
|
||||
fig = plt.figure()
|
||||
g_my_globals.axis_ping = fig.add_subplot(1,1,1)
|
||||
g_my_globals.axis_ping = fig.add_subplot(1, 1, 1)
|
||||
set_chart_labels()
|
||||
plt.tight_layout()
|
||||
|
||||
while True:
|
||||
event, values = window.Read(timeout=0)
|
||||
event, values = window.read(timeout=0)
|
||||
if event in ('Exit', None):
|
||||
break
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
# import PySimpleGUIQt as sg # portable to QT
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
#
|
||||
# An Async Demonstration of a media player
|
||||
|
@ -12,42 +7,39 @@ else:
|
|||
# See how it looks here:
|
||||
# https://user-images.githubusercontent.com/13696193/43159403-45c9726e-8f50-11e8-9da0-0d272e20c579.jpg
|
||||
#
|
||||
|
||||
|
||||
def MediaPlayerGUI():
|
||||
background = '#F0F0F0'
|
||||
# Set the backgrounds the same as the background on the buttons
|
||||
sg.SetOptions(background_color=background, element_background_color=background)
|
||||
# Images are located in a subfolder in the Demo Media Player.py folder
|
||||
image_pause = './ButtonGraphics/Pause.png'
|
||||
image_restart = './ButtonGraphics/Restart.png'
|
||||
image_next = './ButtonGraphics/Next.png'
|
||||
image_exit = './ButtonGraphics/Exit.png'
|
||||
sg.set_options(background_color=background,
|
||||
element_background_color=background)
|
||||
|
||||
# A text element that will be changed to display messages in the GUI
|
||||
|
||||
ImageButton = lambda image_filename, key:sg.Button('', button_color=(background,background), image_filename=image_filename, image_size=(50, 50), image_subsample=2, border_width=0, key=key)
|
||||
def ImageButton(title, key):
|
||||
return sg.Button(title, button_color=(background, background),
|
||||
border_width=0, key=key)
|
||||
|
||||
# define layout of the rows
|
||||
layout= [[sg.Text('Media File Player', font=("Helvetica", 25))],
|
||||
[sg.Text('', size=(15, 2), font=("Helvetica", 14), key='output')],
|
||||
[ImageButton(image_restart, key='Restart Song'), sg.Text(' ' * 2),
|
||||
ImageButton(image_pause, key='Pause'),
|
||||
sg.Text(' ' * 2),
|
||||
ImageButton(image_next, key='Next'),
|
||||
sg.Text(' ' * 2),
|
||||
sg.Text(' ' * 2),ImageButton(image_exit, key='Exit')],
|
||||
]
|
||||
layout = [[sg.Text('Media File Player', font=("Helvetica", 25))],
|
||||
[sg.Text('', size=(15, 2), font=("Helvetica", 14), key='output')],
|
||||
[ImageButton('restart', key='Restart Song'), sg.Text(' ' * 2),
|
||||
ImageButton('pause', key='Pause'), sg.Text(' ' * 2),
|
||||
ImageButton('next', key='Next'), sg.Text(' ' * 2),
|
||||
sg.Text(' ' * 2), ImageButton('exit', key='Exit')],
|
||||
]
|
||||
|
||||
# Open a form, note that context manager can't be used generally speaking for async forms
|
||||
window = sg.Window('Media File Player', auto_size_text=True, default_element_size=(20, 1),
|
||||
font=("Helvetica", 25)).Layout(layout)
|
||||
# Our event loop
|
||||
while(True):
|
||||
event, values = window.Read(timeout=100) # Poll every 100 ms
|
||||
window = sg.Window('Media File Player', layout,
|
||||
default_element_size=(20, 1),
|
||||
font=("Helvetica", 25))
|
||||
|
||||
while True:
|
||||
event, values = window.read(timeout=100)
|
||||
if event == 'Exit' or event is None:
|
||||
break
|
||||
# If a button was pressed, display it on the GUI by updating the text element
|
||||
if event != sg.TIMEOUT_KEY:
|
||||
window.FindElement('output').Update(event)
|
||||
window['output'].update(event)
|
||||
|
||||
window.close()
|
||||
|
||||
|
||||
MediaPlayerGUI()
|
||||
|
||||
|
|
|
@ -1,82 +1,73 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# Usage of icons as base64 string and toolbar
|
||||
|
||||
house64 = 'data:image/png;base64,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'
|
||||
timer64 = 'data:image/png;base64,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'
|
||||
close64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAE30lEQVRIiZ2VXYgdRRqGn6+quvucM/85iRoTNevMBJFEWY0GFQTBC1HBlaz/jMpoFFfXBdmFvdiLvRIEFRHFGBXMjUQhF/6Bol6sSNaIruCNir/R/Dlx5iRzck736e6qby/6JDlx9CIWFN10Ue/7vW+9X7XcDn8bryWPL2vERkNQQPj9Q72K7F3s7Hxb9bZ98L0bj91jt1y23kxNTxIEGUQ/aTYR6WW9cud/Prx01zf7/7FP5EHXHG7Y6bVTpBPLMSegCWKEEMKvkihgjEWDP+FbEjxTa1bjv9l/CsIKF3ypHhUDSFGACCKC956iKKjV6/hfkCjgUNK0TW1oCA3h+EJk8UUBYFCsQaSyRajArUWLnEONcTrT68nTLtZaEKmmMTiUlsREGy9HO0dgcL1y6lgtZrAsEYFexhwxq2buYfru+1mcOo+828UYg4rgUH7OSkY3zbDq1lkaV1yFP9TqEyy18jiBCMF7DjYmOOu+hxifnCSKItZuvp/F6fPJ05TEwE+dHhN33MfpGy4iFAVjf7qF8etvBV9y1IilBApGIMt6TExOM372JKqKqhLFMdOz93Jk6jx+bHVoztzLyj9eiHqP2Gq7O3UlGAuq1RwYDlUwhoChMdSAz3ZxaEeD8T/fBggaAnGtxpqZWdKFBSbOPLMCCQGJItJPdrHw4lOYRgNsBM6dSCDGErIuodtGkhoyPEr68U5svcbI1ZsQY0CV2vAw9ZGRKjEiSBTR/fQjDm9/AddcjqoSul182kYHVDhJauRffUH7wD7ilatxzVOwI6PM7XiJLO2x4rob0CgGVTSEKigidD94j/ltW9Dg0b0/4BfmyQ8ewKUdWLZ6wCIB9SXFXJvQ+hLkc6QeEznHf199jY1rpjh1w0ZUFTGm7z18/tSj2Hffor5shKLdhhJCADMcw7IlKRIkAqkJRIa4LPl6d5c/PPJkBd5vpArcArD+ue101l1Md08bFxuIBUlOyOUggUIAVIl94Kv5wKqtz7L+7r/0bRHEmApcFbwnHhljw6tv0b3kEtK5gDWmj/GbfQAWZbdaztjyPOfP3oN6D8GDCO133uDAvx9CyxKsRX1JMjbBBa+8Rnbl5RSpR35RfXUGfVLnYGFBcTfdwLo77yLkPYy14CLa773JngfuoNy7QOh2WPnw09WVkufUm8s598G/s+eT9wmBJZ1m+sVTFNBc4Wi8vJ3v//kAJk7AOhbf3MGezTfjWwuYCcv8s1s58K+/okWOxDGdjz5g7+YZtKRSoL+igCp5FKVntGk48sTTzDWb1C+4mB833wgETD2CELBjEfNbtyAjo4xdcz27N11L6B5GGoZQhN+26KiSoII9LebnJx9BkggzNIQkyfEdItiRQGvbM7S2bQHJMGN1NO8ds2dQhBORYBCjAFEE1kFSw0QxuAiTJCAGce64vz4gviTkOTJcErIMMRbyDIxg7bHTFnc47clcmpdj43VkeBRJEkytgdTqSL2OiRMkSRDroH9t4EtCUaBZhmYpIUurZ9pFfVnuX+w62xfjeq3D3/6vbifXrT1XkzgWdREmipA4RlwMUYRY21cg/X+lJ5gSbIHGOVovCHmOCSX7DrbMx599icIhVI2cA5c5mC1gbGnITm4oqAOr0PoOXs9g51HAGiITyCDByXDp4KuiaoESmP8/YC0Y5GajmEsAAAAASUVORK5CYII='
|
||||
psg64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABlbkiVhkyZikyFjmShjkyhlly1mli5nlylnmS5olyppnC5qmi5rmzBpmDBpmTFqmDFqmTFqmjNrmzFrnDNsmzJsnDJtnTFunjNvnzRsmTRtmzVunTVunjVvnzZwnjlxny5toDFvozJwoTNzpjVwoDRzpDRzqDd4rThyojp0ozl1pTt2pjt3pz11ozt4qDl4qTp6rTl6rzx4qD55qTx5qj97qz17rT58rD98rT9+rz5+sEB3pEF9rkB+r0F+sEF/sT2AtD6AtT6Btk+Aqk2CrEOBs0GBtEKCtEGCtUSBskWBs0SCtEWDtUaEtkWFt0aGt0KFuUCEukOGu0eFuEWHu0eJvEiGuUiHukiIuUiIukmJu0uKvEyKvFCAp1CCqlODrVKCrl2Kr1OEs1KGsFWGsFaIsVaPvFqKsl6NsmKNsWeTuG6YvHadvlySwV6UxF+YxW+bxW6dxnKewHGex3SdwHSfx3egwXGizHmgwHqkxnyjxHio0f/RMf7QMv/TMf/SMv3SNf7UOv7UO//UPP/UPf/UPv/VP//WPP/XPv/VQ//WQv7XQ//WRP/XRf/WR//YRv/YSP/YSf/YSv/ZS//aS//ZTf/aTP7aTf7aTv7bT//cT//bUP/cUP7cUv/cU/7cVf/eVf/fVv/eV/7dWP/eWP/eWf/fWv/fW//fYvzcaf/hW//gXP/gXv/gX//hYP/hYf/hY//iYP/jY//gZf/iZP7iZf/jZv/iZ//lZv/jaf/kav7ka//maf/ma//kbf/lbv7mbP/mbv/mb//id//mcP/ncv/nc//ld//ndv/meP/ocf/ocv/oc//odP/odf/odv/peP/pff/qfY+11ZSzz5G41qC81aW/1P/jgf/qiv/qjv7qoMnZ5szb587d6eDm2+fo1+7v3e/x3vXw1fHx3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJblQd8AAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAABcQAAAXEAEYYRHbAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjFjKpxLAAABzUlEQVQoU2P4jwNAJZIEuLJA9M2u/iNgAaiEELOgIFPc//+r6puaalvAQmAJdg4pPj4h5oT/2+raWtqaGmAS/PxC/IJAGdbEB7saW5pb20AyQAkFNiFhUSEgkGZNfjizua29u70XJJHr8j+eV0RGVkRMTJb56u2mvt7eSR0gCT2gPsbMGzbi8hJyPDl3OidPnDRlwhagRHbG/zTXe5WSqqqqmpzXb/VMmz5jztSVIDtSWFLvl3Jrampq8ZY8WThj1tx586ZCXFV9t1xRR1tbR6Lw0f6ZC+YvWDAb6tz/xUom+rrGymWPD8xaunjZ0oUgMZBEsYqZqampWsnTY/PWLF+xZhFIHCRRpW5raWFhUPT/3IJ1a9euW/H//5oTYAlDezs7Kwvv//+XbN6wcev6//+3/z8FltDwcrC3N8/7v3rHtu07Nv3/vxVo0CWQhJGPm5ubdf7/TXt279699//JnTA70j38fH19wv//33b00OGj+w6fPXz5KMRVTiH+/gHuFf//7zl+5szZs2fO7YPo+H/FOSIyPMqz5v//g+dAMocvQCX+XwsMjYmNdgSy9p0/d/bgRZAYWOL//4LgoDAwY+++02AaJoEJcEj8/w8A4UqG4COjF7gAAAAASUVORK5CYII='
|
||||
cpu64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAFi0lEQVRIiZ1WS2wbRRj+/5l92O6u7WycTW03xLEd6uBUjVO1hfbSByLQEwhxoIhbCwcuvApUiEOFhAQVEiAOvK4gqoojSEhtgUNApaJKG5qkdWpa1JfcZL3teu3sZmeGQ9ZVGhIJ8Z/+2Vn93//45psBWMMqlcoXxWLxEACAaZpju3btOkkIoZRSsnv37hOmaY4BABSLxUOVSuXzteJIq32klMqyLBuqqhoAAKqqGpTSpKIoSUQESZK6OnuKohiKohiUUpkxtvivWCvWBABEOp1+sr+//5V169ZtnJub+6FUKh3Rdf3hVqv1l6Zp5Ww2ezASifQ0Go3fhoaGjsZisYdardaM4zjTiEgAQHQC4j0HkQghAAC4oiiJRCKxBQBIs9m8oOt6iRASa7VaVwEAYrFYP+e85TjOpXg8PiyE4LZtn/F93wYAgogghOD3AYS+UFW1q1AovGoYxp4wGxIEgS2EEIQQCQCAcx7gkslCCB8AwLbt07Va7SPP8xqdWPdmIElSxDTNfZZlncrn828MDg6+VavVPvF9fy4Wi/X19fUdWJHMfSaEYJlMZgwRpVqtdtQwjD31ev2HIAgWpJGRkS8VRTEMw9g9OTm5v7u7+9GpqamXq9XqxwAAmzZt+oBzjpzzYC0QIQRDRJpIJLanUqmdw8PDX1mW9ZPv+5bkOM5FVVVTiURia1i24rruDQCAUqn09sDAwCHGGEdEadnwlgOJZT5BRMIYc5rN5iXP8+ax0y9N04qc84Vt27aduHjx4uuEED46Ovo95xxEOH1ExKWEhQh9DPe4JEl0fn7+14mJiecQUWo2m7MAgNQ0zb3d3d3bhoaGjrTb7Wld1x/p6uoa2bBhw4uyLGsAEFBKKSIi51xQSjFcIiICIQRDAhDXdWue502Vy+X3hRALqqr2SoODg2/KsmzE4/GNlNJ1nPOF9evXPxYEAbiue7lWq72rKIphmub+GzdufBeNRg1d14cZYx4hhBJClFQqNRbOQlBKo8lkcms+n48vLi5a0vj4+OOKoiTT6fQzjuNcJYRIQRCALMswOzv7LSEk0tPT85TjOBeCIKi12+1rtm3/ruv6FgDgAMB7e3vHgiAAQgh1HOfquXPnXr958+Zx3/dtshopltp7nyEiUtd1rxuG8URfX99B13Un2+32rKIo3ZzztRgMdOfOnT/mcrkX+vv79zcajVOapm3XNC3HGINoNNpnWdZJz/P+TiQSOzRNK6bT6WcjkUh/q9WaQUTIZrMHEFEjhECz2fzL9/2ZkZGRz0zT3JfNZp+WqtXq+5FIJJXL5V5kjLVDdgDnnMVisYFyufxVSFHgnO9gjDFElIvF4jth34ExxgCAIiIyxtq2bZ+5cuXK5wsLC3NSvV4/BQDCsqw/hBBBLpeTO+WF/KdhC0TIHAoAIggCjogYMnjpEBAi27Z96ezZsy90aCoVCoXXVFVNZbPZ/TMzMy9xzr1ljSdhYLHicN0DCkFYWKFnGMamUqn06fXr17/xPG9e0nV9Y6jnWqiAPCydrTm5laxY+pcCABdCcEqprmnag4qiWNLExMTBZWI3Ho/Hd2Qymb1CCBpm+V8AQJZluHPnzum5ubnx8+fPH+iI3apync/nX04mk9vDXihCiMX/K9drXTjJZDK5FRHJ3bt3/9R1/cH/e+Esb0FnkKK3t3ff5s2bv+7p6Rm7devWsXK5/GGhUDjsOM5kNBp9oFKpfKNp2kC9Xv9xdHT0eCaTed513fPhlYmd4CsBOiDQarVmu7q6KpZl/XLt2rVjQggvHo8PTE9PH242m1PpdPrRy5cvf3L79u2fo9GoyRi7U61W3wsDL5fv1V8VjLFF3/ct3/ctAADP86wgCBq+7zcAABljtud5FgCA7/uWLMvWai8KAIB/ACsf4Gh+DNwbAAAAAElFTkSuQmCC'
|
||||
camera64 = 'data:image/png;base64,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'
|
||||
checkmark64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAD2ElEQVRIibWVe4hUVRzHP+feuTOz82gfrqwu5gM0zTQpS1yfoGQPyc3IjOwlYRElPcDICEP6Q6i/IvojCCIpTA0tSlSqJSvbTLZE0dbWxz4nXWdnxrk7M/feOY/+sHyEa7pt57/z45zP53x/B84R/B/jzeNLgeXADDHE4IeBV2Ihpo6LK1rzNqEhAW9oGw18UhelYeWUGHFL0tx5lqPZyBAI3mi9o8YRm16cWTlsVFLQVwjY2+4SSI2W+j8KXj+ybmwytO69xjo7Wyqzr8sldbaE60ksIdBlhTVo+KuHXppY5azftKzeNsbQkurntOuTKQQobYhFbCgPNsGaA5NDWm94ZlYV7fmAX3pcenIlTucDAqlJRENUxcJQLgwiwfMtYcpq4503JMJjq8M0d+XpyBRJnfUpBpJwyKYqFqbCcSCQg0gQyCeq4qHp90yr5Pd0kY6+ImnXJ1CaeDhEdSJCTSJKzLEHLXhu4oQEuWKZ79uzZAoX2hKPhOn+I6DtuEdfLriC4NE9L4CYhzEP8dH84Hz9kT0NBHLqvMlJmo5nyBQDylITj4RwM5rmw70orcEA0AL8Q/DgN8OBr/DltL8q64G1F52+obomwr6US7boE0hNhRPiVIdHx7H+EvA2sJ0tC3/+e8uFS27c/SS+7ElGrGkbnp5EfV0UArmGxt0Lzq/x5YzKWocz/T4FXyGEINvj0XE410QgJ7Fl4dqL4ecS3PVlJYgdllKzx04ZxqolY8h4mkm315JPl+z+nP8Bd++4hZ2LM/hyuokLCr7Eti28TJnOA5ndGLOUnYtLl+u2YMHnJ4BxY2bWsWj2SA72eoBBG4PnBvy2qwvpq81gVjhJp1Q7q9axLIFVMqSaz3ytfLWEpsbLwgFs6pc1o/R9+e7+eK9joSMWvjR4gSLA4FSGKLS7UyirUmRkbJFTG0VI6N17+oR0/bl8d/+A8HMJAG7bPB7BTmGL8TVz64mMiKGNQSuN0hqvq59CS59Kzq2zo8MrcH/s1V6qMIf9y5uvBL8gALj54xpgG5aYH589klB9BdoYjDY0XJ9k9HURPj2aRZ/ycL/tfouDK17+N/ilAoAbP6wAsRGLB8INI7BGJUAYLGEhLAtLCApfnDymc95NtD4eDMC8ZNiXzNKfSdLbt5K8N6o68nNMwoHqKCAwlkVwKI06ln2MtpWtVwMHBnjspHyNQO1Xe7pRbTmUEchCGbk/laKsdl0tfGBB51OKQM0hUD/ppk7kkTTy11NQku/TuUpdi+DKn/7wdyuAHzDcii0Uykwg/ezJoRMAVL9TCWwFjpJdvfpa4AB/Akx4zQw8GDagAAAAAElFTkSuQmCC'
|
||||
cookbook64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAAAsSAAALEgHS3X78AAADMUlEQVQ4jY1UQUgCWxS9782M5hQzle3NTRGEQdBipCKKECoEg4JaJAqCmyBsYauEaNOqjQtXLSKINuFiKMiwIMtF1iLK2kWRZLUoDRxo5s37ixfSt4+/u7xzz51z7r3nwc7Ojt1uBwCEEPwtWKXL5eIvLy+HhoYIIYIgCIJAKa0Do5RyHPfy8nJycnJ1dcUjhJxOZygUOj09zefzFoulDp5SihCKRqPLy8vJZBI4jgOAo6Mjj8cDABjj/6WdTqdDoRAAfJeyFn8MQohhGADAY4xFUSyVSpIkAYBpmgih+soRQmxm2GazbW5u7u7ujoyMKIrCmP+ePMdxv9nhSqXi8/lmZmb29vay2Syrs1gs8EM/QogQQgipBWOMOzs7397eWlpabDYbAMiyHAwGu7u7mQTWzu/3R6PRxsZG+HERvNVqjcVix8fHfX19Nzc3T09PHo+HUjo1NVUulx8fHwFgbW0tEolQSguFwtbWVpU/rlQqs7Ozc3NzqqrmcjmXy9Xe3m61WgcGBubn5wGgo6NjYWEBAEql0t3dHQBUx8ljjNva2orFYnNzM8/zBwcHFoslGo329/cXCgUA6OnpwRh/fHwsLS3lcjm2qm9wQ0NDPB7f398fHBx8eHjIZrOqqhaLRUmSwuFwPB53OBw+ny+dTn9+ftYujed5AEilUhMTE9U9saTX66WUJhKJmv0dHh4Gg0FgF4YxJoQwANNjGIaiKLFYbHp62ul0Li4umqb5H5crSVIymQwEAolEwu12s6SiKNfX15OTkwDgcDguLi4ikUgVUv0zCIJgs9lUVWWlrP3q6qrf72dfAaCrq2tjY0OW5RowTynVNM1qteq6XqW9srJiGAZCSNd1hNDt7W04HGZm+NeFiaKYTCa3t7fHx8fdbjez+9fXV7UR87Cu66Zp1oI1TQsEAl6vN51Os9smhCCEfpbWmMw0TZbBpmm+v7+3traWy2VKKdP825I/M7Isi6IIAFxTU9P6+nomk+nt7X19fX1+fsYY1/ez0+k8Pz+/v7/nMMblcnl4eDifz5+dnWmaVgfGolQq2e32sbGx7wcok8mMjo7C396wVCpFKSWE/ANWXYLwO0+V8wAAAABJRU5ErkJggg=='
|
||||
download64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAEl0lEQVRIia2WS2hdZRDHf/Odc+7NvbZpYky1Gk2rEbRa26pt8UWLitYHIqigCD426kIQxCfWhYu68U0RBBERXCq+WrXoorYIFWpbEY0lpk0NTWKtuUlzn+d834yLm5smqQspzurMcM785j+c+eYTTtUcESAzvhIAm/+azHacA4FodszAVNFTrUPm+Q6iecmUyJkEna5OiDCCXCtvJ2cnV+Ep+9R7/VIfQhmeryKeySywok+SSMMKMwqAihDXPIcPDDMURUQCgiPWjJCck6x87ZXXV3cXu3XTO5tkYOvAHbnIfZipTpghLdAMIEngi1cXvtlzwfrHpG0x5ismzsvo0E9D9z7z++M799s2EcSm67OUkAs5cpbzkkoMtPtAAzdXQ9zqjHkt1Ol5SHofx0KWYRUxrdiS3FlLtzz51wd7+v2OQl7qHnPtorUXS3ZxPRUKUT5x4mTDWu559LbCNS+9X9v025Duc4KoYdMAA7A4Mk92EMp/JFIZwR/rx9dL1teVdC2/Qe8yzQg+pS0JvLUzx3hjioPVQamGGlcu47KNq6qrPj+fsd+GeAEYA2SmRQiCNSJKP1Ad3IVaG0nnlWRxKqkkVlYxJxGZwhmFIo34U/fh0Hv4v6YYrY+ihYtkorDUNj+298GPvzv6ZRrkMzA/oyCXh9rEMOOHfiLfcx+5zhXkOnppswxEpJHVxdTjs0CycDHy9XcMlwc5a0E3EoTconOls/dyBsb6lYRLY4m/9T6blDgi8oHw3rPx83fesubl4oVPWFvXBUKoQzqB92Xitpite77n/k/epaN7AZO1CTIROtZ14fJC6ccS9ndGUhRLK0Eum1h2YGpH5eFfD47sjluzcFo+f+vp655F03alNhZhASMjloA1qtzedzab125kiw2QLhHaQ0zIFM2MztUdkBcqx1Lp+0o59NGRP49OVQs0Z3d6nEyMUMP8OGgVtAJaA19CagP4xn4e6DPuPhox1V9HTRFr/h9mRmWkwbJtGSsHK4xXq4cQGQDCDABM0ClEy6DlJiA9DLV90BgktirFzhrPXX0mT6Y9lAaqkAhRItRKGT3bjetTYd2aYM7JYcwm5wwaAP44hDyQYukokg5jliICZoFIoNjZ4Ol1HdhueOPgCLlFjt7twvo63HwztGuipml20lEBBlrGfBXzR5BsDGjOPBrAAkJKRKBwuuepNUXyP5/HN7tKXFGvcuMGY/3qhAO/NLCTJ7kFmIT0OPgjmAhiYKYIASFgGoCUyAILu+o8ckng0jSwsF1YuzxP0hYwm3tizwIIpKPQOIY4BXUYCiiYYWSIKYYHMoRAV1fKTddFxJKQOA/mmW9zFWRjoCmYw6R1lrcg2kxgAfCIeRxKMa+YBSw0Vc7fOScAZuAnMXWYE8yaIUFBDFSbS8sCgscsayZWD3jMAmhT7b8CnDPIeZw6RGTOLmwWFRALMA3BZvkamoBcwM3Zh7MA9Yb5I3v/YKoKTlr9sROKZVrlTGDWsylmkMTGxCQ4h0ObGaT1aRJzHsbtwJJmWSet0/9kIpB69gPbgersJA4oMm/pn6JlQI1/uWX87/YP06p9rkZQnAYAAAAASUVORK5CYII='
|
||||
github64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAADAwMDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhyjGAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdUAAA3VAT3WWPEAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAABzSURBVChTbYxRFoAgDMPQ+98Z1zbIeJqPbU3RMRfDECqyGpjMg6ivT6NBbKTw5WySq0jKt/sHrXiJ8PwpAAVIgQGkwABSYAApMIAUGEAalFmK9UJ24dC1i7qdj6IO5F+xnxfLu0jS0c7kqxd3Dk+JY8/5AKFrLuM7mfCAAAAAAElFTkSuQmCC'
|
||||
run64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAszD0iAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdUAAA3VAT3WWPEAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAABqSURBVChTpY5JDsAwCMTy/09TMGvFpVF9aAZPRHpkcXC7OIodPg0uCjPq+MwCrWRGKkiIvLyTqzw3aqoI73eqUNAoXBXlg4zudxF+NONfPIVvbSZPgww5oW0Vz8T4Lgbt/xbjia+rahR5AEYEg4vdzh2JAAAAAElFTkSuQmCC'
|
||||
storage64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABwcHDQ0NDg4ODw8PFxcXGRkZGhoaGxsbHh4eIyMjJSUlJiYmJycnKCgoMTExMjIyNTU1NjY2Nzc3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAouNksgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdQAAA3UAe+RuhUAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAC5SURBVChTfZLbDsMgDEPpbb3TDv7/W7PYuAztYUeqhO2QAGowkXIMIeYkaSU4QsNBi4GcyhNINpTglmq4GWSphvy/ldkuLXZ4HmAxy3NmFJaA4guKGCwsjClfV05+fWdhYBtFw+amB292aygW3M7fsPTwjmadZkCvHEtWaAYTViBqVwgTA3tJVnB6D/xhaimItDhjMBvlhtFsaIafnEtOaAY/twAw/eslK70CbX8obUvgJNw9Jv0+Zh8D4s5+VAm/LwAAAABJRU5ErkJggg=='
|
||||
|
||||
|
||||
def ShowMeTheButtons():
|
||||
# ------ Menu Definition ------ #
|
||||
menu_def = [['&File', ['&Open', '&Save', '&Properties', 'E&xit' ]],
|
||||
['&Edit', ['&Paste', ['Special', 'Normal',], 'Undo'],],
|
||||
['&Toolbar', ['---', 'Command &1', 'Command &2', '---', 'Command &3', 'Command &4']],
|
||||
['&Help', '&About...'],]
|
||||
menu_def = [['&File', ['&Open', '&Save', '&Properties', 'E&xit']],
|
||||
['&Edit', ['&Paste', ['Special', 'Normal', ], 'Undo'], ],
|
||||
['&Toolbar', ['---', 'Command &1', 'Command &2',
|
||||
'---', 'Command &3', 'Command &4']],
|
||||
['&Help', '&About...'], ]
|
||||
|
||||
sg.SetOptions(auto_size_buttons=True, margins=(0,0), button_color=sg.COLOR_SYSTEM_DEFAULT)
|
||||
sg.set_options(auto_size_buttons=True,
|
||||
margins=(0, 0),
|
||||
button_color=sg.COLOR_SYSTEM_DEFAULT)
|
||||
|
||||
toolbar_buttons = [[sg.Button('', image_data=close64[22:],button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0,0), key='-close-'),
|
||||
sg.Button('', image_data=timer64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-timer-'),
|
||||
sg.Button('', image_data=house64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-house-'),
|
||||
sg.Button('', image_data=cpu64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-cpu-'),
|
||||
sg.Button('', image_data=camera64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-camera-'),
|
||||
sg.Button('', image_data=checkmark64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-checkmark-'),
|
||||
sg.Button('', image_data=cookbook64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-cookbook-'),
|
||||
sg.Button('', image_data=download64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-download-'),
|
||||
sg.Button('', image_data=github64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-github-'),
|
||||
sg.Button('', image_data=psg64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-psg-'),
|
||||
sg.Button('', image_data=run64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-run-'),
|
||||
sg.Button('', image_data=storage64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='-storage-'),
|
||||
]]
|
||||
|
||||
toolbar_buttons = [[sg.Button('', image_data=close64[22:],button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0,0), key='_close_'),
|
||||
sg.Button('', image_data=timer64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_timer_'),
|
||||
sg.Button('', image_data=house64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_house_'),
|
||||
sg.Button('', image_data=cpu64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_cpu_'),
|
||||
sg.Button('', image_data=camera64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_camera_'),
|
||||
sg.Button('', image_data=checkmark64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_checkmark_'),
|
||||
sg.Button('', image_data=cookbook64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_cookbook_'),
|
||||
sg.Button('', image_data=download64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_download_'),
|
||||
sg.Button('', image_data=github64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_github_'),
|
||||
sg.Button('', image_data=psg64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_psg_'),
|
||||
sg.Button('', image_data=run64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_run_'),
|
||||
sg.Button('', image_data=storage64[22:], button_color=('white', sg.COLOR_SYSTEM_DEFAULT), pad=(0, 0), key='_storage_'),
|
||||
]]
|
||||
|
||||
# layout = toolbar_buttons
|
||||
# ------ GUI Defintion ------ #
|
||||
layout = [ [sg.Menu(menu_def, )],
|
||||
[sg.Frame('', toolbar_buttons,title_color='white', background_color=sg.COLOR_SYSTEM_DEFAULT, pad=(0,0))],
|
||||
[sg.Text('', size=(20,8))],
|
||||
[sg.Text('Status Bar', relief=sg.RELIEF_SUNKEN, size=(55, 1), pad=(0, 3), key='_status_')]
|
||||
]
|
||||
layout = [[sg.Menu(menu_def, )],
|
||||
[sg.Frame('', toolbar_buttons, title_color='white',
|
||||
background_color=sg.COLOR_SYSTEM_DEFAULT, pad=(0, 0))],
|
||||
[sg.Text('', size=(20, 8))],
|
||||
[sg.Text('Status Bar', relief=sg.RELIEF_SUNKEN,
|
||||
size=(55, 1), pad=(0, 3), key='-status-')]
|
||||
]
|
||||
|
||||
window = sg.Window('Toolbar').Layout(layout)
|
||||
window = sg.Window('Toolbar', layout)
|
||||
|
||||
# ---===--- Loop taking in user input --- #
|
||||
while True:
|
||||
button, value = window.Read()
|
||||
button, value = window.read()
|
||||
print(button)
|
||||
if button in ('_close_', 'Exit') or button is None:
|
||||
if button in ('-close-', 'Exit') or button is None:
|
||||
break # exit button clicked
|
||||
elif button == '_timer_':
|
||||
elif button == '-timer-':
|
||||
pass # add your call to launch a timer program
|
||||
elif button == '_cpu_':
|
||||
elif button == '-cpu-':
|
||||
pass # add your call to launch a CPU measuring utility
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
house64 = 'data:image/png;base64,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'
|
||||
|
||||
timer64 = 'data:image/png;base64,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'
|
||||
|
||||
close64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAE30lEQVRIiZ2VXYgdRRqGn6+quvucM/85iRoTNevMBJFEWY0GFQTBC1HBlaz/jMpoFFfXBdmFvdiLvRIEFRHFGBXMjUQhF/6Bol6sSNaIruCNir/R/Dlx5iRzck736e6qby/6JDlx9CIWFN10Ue/7vW+9X7XcDn8bryWPL2vERkNQQPj9Q72K7F3s7Hxb9bZ98L0bj91jt1y23kxNTxIEGUQ/aTYR6WW9cud/Prx01zf7/7FP5EHXHG7Y6bVTpBPLMSegCWKEEMKvkihgjEWDP+FbEjxTa1bjv9l/CsIKF3ypHhUDSFGACCKC956iKKjV6/hfkCjgUNK0TW1oCA3h+EJk8UUBYFCsQaSyRajArUWLnEONcTrT68nTLtZaEKmmMTiUlsREGy9HO0dgcL1y6lgtZrAsEYFexhwxq2buYfru+1mcOo+828UYg4rgUH7OSkY3zbDq1lkaV1yFP9TqEyy18jiBCMF7DjYmOOu+hxifnCSKItZuvp/F6fPJ05TEwE+dHhN33MfpGy4iFAVjf7qF8etvBV9y1IilBApGIMt6TExOM372JKqKqhLFMdOz93Jk6jx+bHVoztzLyj9eiHqP2Gq7O3UlGAuq1RwYDlUwhoChMdSAz3ZxaEeD8T/fBggaAnGtxpqZWdKFBSbOPLMCCQGJItJPdrHw4lOYRgNsBM6dSCDGErIuodtGkhoyPEr68U5svcbI1ZsQY0CV2vAw9ZGRKjEiSBTR/fQjDm9/AddcjqoSul182kYHVDhJauRffUH7wD7ilatxzVOwI6PM7XiJLO2x4rob0CgGVTSEKigidD94j/ltW9Dg0b0/4BfmyQ8ewKUdWLZ6wCIB9SXFXJvQ+hLkc6QeEznHf199jY1rpjh1w0ZUFTGm7z18/tSj2Hffor5shKLdhhJCADMcw7IlKRIkAqkJRIa4LPl6d5c/PPJkBd5vpArcArD+ue101l1Md08bFxuIBUlOyOUggUIAVIl94Kv5wKqtz7L+7r/0bRHEmApcFbwnHhljw6tv0b3kEtK5gDWmj/GbfQAWZbdaztjyPOfP3oN6D8GDCO133uDAvx9CyxKsRX1JMjbBBa+8Rnbl5RSpR35RfXUGfVLnYGFBcTfdwLo77yLkPYy14CLa773JngfuoNy7QOh2WPnw09WVkufUm8s598G/s+eT9wmBJZ1m+sVTFNBc4Wi8vJ3v//kAJk7AOhbf3MGezTfjWwuYCcv8s1s58K+/okWOxDGdjz5g7+YZtKRSoL+igCp5FKVntGk48sTTzDWb1C+4mB833wgETD2CELBjEfNbtyAjo4xdcz27N11L6B5GGoZQhN+26KiSoII9LebnJx9BkggzNIQkyfEdItiRQGvbM7S2bQHJMGN1NO8ds2dQhBORYBCjAFEE1kFSw0QxuAiTJCAGce64vz4gviTkOTJcErIMMRbyDIxg7bHTFnc47clcmpdj43VkeBRJEkytgdTqSL2OiRMkSRDroH9t4EtCUaBZhmYpIUurZ9pFfVnuX+w62xfjeq3D3/6vbifXrT1XkzgWdREmipA4RlwMUYRY21cg/X+lJ5gSbIHGOVovCHmOCSX7DrbMx599icIhVI2cA5c5mC1gbGnITm4oqAOr0PoOXs9g51HAGiITyCDByXDp4KuiaoESmP8/YC0Y5GajmEsAAAAASUVORK5CYII='
|
||||
|
||||
psg64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAABlbkiVhkyZikyFjmShjkyhlly1mli5nlylnmS5olyppnC5qmi5rmzBpmDBpmTFqmDFqmTFqmjNrmzFrnDNsmzJsnDJtnTFunjNvnzRsmTRtmzVunTVunjVvnzZwnjlxny5toDFvozJwoTNzpjVwoDRzpDRzqDd4rThyojp0ozl1pTt2pjt3pz11ozt4qDl4qTp6rTl6rzx4qD55qTx5qj97qz17rT58rD98rT9+rz5+sEB3pEF9rkB+r0F+sEF/sT2AtD6AtT6Btk+Aqk2CrEOBs0GBtEKCtEGCtUSBskWBs0SCtEWDtUaEtkWFt0aGt0KFuUCEukOGu0eFuEWHu0eJvEiGuUiHukiIuUiIukmJu0uKvEyKvFCAp1CCqlODrVKCrl2Kr1OEs1KGsFWGsFaIsVaPvFqKsl6NsmKNsWeTuG6YvHadvlySwV6UxF+YxW+bxW6dxnKewHGex3SdwHSfx3egwXGizHmgwHqkxnyjxHio0f/RMf7QMv/TMf/SMv3SNf7UOv7UO//UPP/UPf/UPv/VP//WPP/XPv/VQ//WQv7XQ//WRP/XRf/WR//YRv/YSP/YSf/YSv/ZS//aS//ZTf/aTP7aTf7aTv7bT//cT//bUP/cUP7cUv/cU/7cVf/eVf/fVv/eV/7dWP/eWP/eWf/fWv/fW//fYvzcaf/hW//gXP/gXv/gX//hYP/hYf/hY//iYP/jY//gZf/iZP7iZf/jZv/iZ//lZv/jaf/kav7ka//maf/ma//kbf/lbv7mbP/mbv/mb//id//mcP/ncv/nc//ld//ndv/meP/ocf/ocv/oc//odP/odf/odv/peP/pff/qfY+11ZSzz5G41qC81aW/1P/jgf/qiv/qjv7qoMnZ5szb587d6eDm2+fo1+7v3e/x3vXw1fHx3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJblQd8AAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAABcQAAAXEAEYYRHbAAAAGHRFWHRTb2Z0d2FyZQBwYWludC5uZXQgNC4xLjFjKpxLAAABzUlEQVQoU2P4jwNAJZIEuLJA9M2u/iNgAaiEELOgIFPc//+r6puaalvAQmAJdg4pPj4h5oT/2+raWtqaGmAS/PxC/IJAGdbEB7saW5pb20AyQAkFNiFhUSEgkGZNfjizua29u70XJJHr8j+eV0RGVkRMTJb56u2mvt7eSR0gCT2gPsbMGzbi8hJyPDl3OidPnDRlwhagRHbG/zTXe5WSqqqqmpzXb/VMmz5jztSVIDtSWFLvl3Jrampq8ZY8WThj1tx586ZCXFV9t1xRR1tbR6Lw0f6ZC+YvWDAb6tz/xUom+rrGymWPD8xaunjZ0oUgMZBEsYqZqampWsnTY/PWLF+xZhFIHCRRpW5raWFhUPT/3IJ1a9euW/H//5oTYAlDezs7Kwvv//+XbN6wcev6//+3/z8FltDwcrC3N8/7v3rHtu07Nv3/vxVo0CWQhJGPm5ubdf7/TXt279699//JnTA70j38fH19wv//33b00OGj+w6fPXz5KMRVTiH+/gHuFf//7zl+5szZs2fO7YPo+H/FOSIyPMqz5v//g+dAMocvQCX+XwsMjYmNdgSy9p0/d/bgRZAYWOL//4LgoDAwY+++02AaJoEJcEj8/w8A4UqG4COjF7gAAAAASUVORK5CYII='
|
||||
|
||||
cpu64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAFi0lEQVRIiZ1WS2wbRRj+/5l92O6u7WycTW03xLEd6uBUjVO1hfbSByLQEwhxoIhbCwcuvApUiEOFhAQVEiAOvK4gqoojSEhtgUNApaJKG5qkdWpa1JfcZL3teu3sZmeGQ9ZVGhIJ8Z/+2Vn93//45psBWMMqlcoXxWLxEACAaZpju3btOkkIoZRSsnv37hOmaY4BABSLxUOVSuXzteJIq32klMqyLBuqqhoAAKqqGpTSpKIoSUQESZK6OnuKohiKohiUUpkxtvivWCvWBABEOp1+sr+//5V169ZtnJub+6FUKh3Rdf3hVqv1l6Zp5Ww2ezASifQ0Go3fhoaGjsZisYdardaM4zjTiEgAQHQC4j0HkQghAAC4oiiJRCKxBQBIs9m8oOt6iRASa7VaVwEAYrFYP+e85TjOpXg8PiyE4LZtn/F93wYAgogghOD3AYS+UFW1q1AovGoYxp4wGxIEgS2EEIQQCQCAcx7gkslCCB8AwLbt07Va7SPP8xqdWPdmIElSxDTNfZZlncrn828MDg6+VavVPvF9fy4Wi/X19fUdWJHMfSaEYJlMZgwRpVqtdtQwjD31ev2HIAgWpJGRkS8VRTEMw9g9OTm5v7u7+9GpqamXq9XqxwAAmzZt+oBzjpzzYC0QIQRDRJpIJLanUqmdw8PDX1mW9ZPv+5bkOM5FVVVTiURia1i24rruDQCAUqn09sDAwCHGGEdEadnwlgOJZT5BRMIYc5rN5iXP8+ax0y9N04qc84Vt27aduHjx4uuEED46Ovo95xxEOH1ExKWEhQh9DPe4JEl0fn7+14mJiecQUWo2m7MAgNQ0zb3d3d3bhoaGjrTb7Wld1x/p6uoa2bBhw4uyLGsAEFBKKSIi51xQSjFcIiICIQRDAhDXdWue502Vy+X3hRALqqr2SoODg2/KsmzE4/GNlNJ1nPOF9evXPxYEAbiue7lWq72rKIphmub+GzdufBeNRg1d14cZYx4hhBJClFQqNRbOQlBKo8lkcms+n48vLi5a0vj4+OOKoiTT6fQzjuNcJYRIQRCALMswOzv7LSEk0tPT85TjOBeCIKi12+1rtm3/ruv6FgDgAMB7e3vHgiAAQgh1HOfquXPnXr958+Zx3/dtshopltp7nyEiUtd1rxuG8URfX99B13Un2+32rKIo3ZzztRgMdOfOnT/mcrkX+vv79zcajVOapm3XNC3HGINoNNpnWdZJz/P+TiQSOzRNK6bT6WcjkUh/q9WaQUTIZrMHEFEjhECz2fzL9/2ZkZGRz0zT3JfNZp+WqtXq+5FIJJXL5V5kjLVDdgDnnMVisYFyufxVSFHgnO9gjDFElIvF4jth34ExxgCAIiIyxtq2bZ+5cuXK5wsLC3NSvV4/BQDCsqw/hBBBLpeTO+WF/KdhC0TIHAoAIggCjogYMnjpEBAi27Z96ezZsy90aCoVCoXXVFVNZbPZ/TMzMy9xzr1ljSdhYLHicN0DCkFYWKFnGMamUqn06fXr17/xPG9e0nV9Y6jnWqiAPCydrTm5laxY+pcCABdCcEqprmnag4qiWNLExMTBZWI3Ho/Hd2Qymb1CCBpm+V8AQJZluHPnzum5ubnx8+fPH+iI3apync/nX04mk9vDXihCiMX/K9drXTjJZDK5FRHJ3bt3/9R1/cH/e+Esb0FnkKK3t3ff5s2bv+7p6Rm7devWsXK5/GGhUDjsOM5kNBp9oFKpfKNp2kC9Xv9xdHT0eCaTed513fPhlYmd4CsBOiDQarVmu7q6KpZl/XLt2rVjQggvHo8PTE9PH242m1PpdPrRy5cvf3L79u2fo9GoyRi7U61W3wsDL5fv1V8VjLFF3/ct3/ctAADP86wgCBq+7zcAABljtud5FgCA7/uWLMvWai8KAIB/ACsf4Gh+DNwbAAAAAElFTkSuQmCC'
|
||||
|
||||
camera64 = 'data:image/png;base64,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'
|
||||
|
||||
checkmark64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAD2ElEQVRIibWVe4hUVRzHP+feuTOz82gfrqwu5gM0zTQpS1yfoGQPyc3IjOwlYRElPcDICEP6Q6i/IvojCCIpTA0tSlSqJSvbTLZE0dbWxz4nXWdnxrk7M/feOY/+sHyEa7pt57/z45zP53x/B84R/B/jzeNLgeXADDHE4IeBV2Ihpo6LK1rzNqEhAW9oGw18UhelYeWUGHFL0tx5lqPZyBAI3mi9o8YRm16cWTlsVFLQVwjY2+4SSI2W+j8KXj+ybmwytO69xjo7Wyqzr8sldbaE60ksIdBlhTVo+KuHXppY5azftKzeNsbQkurntOuTKQQobYhFbCgPNsGaA5NDWm94ZlYV7fmAX3pcenIlTucDAqlJRENUxcJQLgwiwfMtYcpq4503JMJjq8M0d+XpyBRJnfUpBpJwyKYqFqbCcSCQg0gQyCeq4qHp90yr5Pd0kY6+ImnXJ1CaeDhEdSJCTSJKzLEHLXhu4oQEuWKZ79uzZAoX2hKPhOn+I6DtuEdfLriC4NE9L4CYhzEP8dH84Hz9kT0NBHLqvMlJmo5nyBQDylITj4RwM5rmw70orcEA0AL8Q/DgN8OBr/DltL8q64G1F52+obomwr6US7boE0hNhRPiVIdHx7H+EvA2sJ0tC3/+e8uFS27c/SS+7ElGrGkbnp5EfV0UArmGxt0Lzq/x5YzKWocz/T4FXyGEINvj0XE410QgJ7Fl4dqL4ecS3PVlJYgdllKzx04ZxqolY8h4mkm315JPl+z+nP8Bd++4hZ2LM/hyuokLCr7Eti28TJnOA5ndGLOUnYtLl+u2YMHnJ4BxY2bWsWj2SA72eoBBG4PnBvy2qwvpq81gVjhJp1Q7q9axLIFVMqSaz3ytfLWEpsbLwgFs6pc1o/R9+e7+eK9joSMWvjR4gSLA4FSGKLS7UyirUmRkbJFTG0VI6N17+oR0/bl8d/+A8HMJAG7bPB7BTmGL8TVz64mMiKGNQSuN0hqvq59CS59Kzq2zo8MrcH/s1V6qMIf9y5uvBL8gALj54xpgG5aYH589klB9BdoYjDY0XJ9k9HURPj2aRZ/ycL/tfouDK17+N/ilAoAbP6wAsRGLB8INI7BGJUAYLGEhLAtLCApfnDymc95NtD4eDMC8ZNiXzNKfSdLbt5K8N6o68nNMwoHqKCAwlkVwKI06ln2MtpWtVwMHBnjspHyNQO1Xe7pRbTmUEchCGbk/laKsdl0tfGBB51OKQM0hUD/ppk7kkTTy11NQku/TuUpdi+DKn/7wdyuAHzDcii0Uykwg/ezJoRMAVL9TCWwFjpJdvfpa4AB/Akx4zQw8GDagAAAAAElFTkSuQmCC'
|
||||
|
||||
cookbook64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAAAsSAAALEgHS3X78AAADMUlEQVQ4jY1UQUgCWxS9782M5hQzle3NTRGEQdBipCKKECoEg4JaJAqCmyBsYauEaNOqjQtXLSKINuFiKMiwIMtF1iLK2kWRZLUoDRxo5s37ixfSt4+/u7xzz51z7r3nwc7Ojt1uBwCEEPwtWKXL5eIvLy+HhoYIIYIgCIJAKa0Do5RyHPfy8nJycnJ1dcUjhJxOZygUOj09zefzFoulDp5SihCKRqPLy8vJZBI4jgOAo6Mjj8cDABjj/6WdTqdDoRAAfJeyFn8MQohhGADAY4xFUSyVSpIkAYBpmgih+soRQmxm2GazbW5u7u7ujoyMKIrCmP+ePMdxv9nhSqXi8/lmZmb29vay2Syrs1gs8EM/QogQQgipBWOMOzs7397eWlpabDYbAMiyHAwGu7u7mQTWzu/3R6PRxsZG+HERvNVqjcVix8fHfX19Nzc3T09PHo+HUjo1NVUulx8fHwFgbW0tEolQSguFwtbWVpU/rlQqs7Ozc3NzqqrmcjmXy9Xe3m61WgcGBubn5wGgo6NjYWEBAEql0t3dHQBUx8ljjNva2orFYnNzM8/zBwcHFoslGo329/cXCgUA6OnpwRh/fHwsLS3lcjm2qm9wQ0NDPB7f398fHBx8eHjIZrOqqhaLRUmSwuFwPB53OBw+ny+dTn9+ftYujed5AEilUhMTE9U9saTX66WUJhKJmv0dHh4Gg0FgF4YxJoQwANNjGIaiKLFYbHp62ul0Li4umqb5H5crSVIymQwEAolEwu12s6SiKNfX15OTkwDgcDguLi4ikUgVUv0zCIJgs9lUVWWlrP3q6qrf72dfAaCrq2tjY0OW5RowTynVNM1qteq6XqW9srJiGAZCSNd1hNDt7W04HGZm+NeFiaKYTCa3t7fHx8fdbjez+9fXV7UR87Cu66Zp1oI1TQsEAl6vN51Os9smhCCEfpbWmMw0TZbBpmm+v7+3traWy2VKKdP825I/M7Isi6IIAFxTU9P6+nomk+nt7X19fX1+fsYY1/ez0+k8Pz+/v7/nMMblcnl4eDifz5+dnWmaVgfGolQq2e32sbGx7wcok8mMjo7C396wVCpFKSWE/ANWXYLwO0+V8wAAAABJRU5ErkJggg=='
|
||||
|
||||
download64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAACXBIWXMAAAsSAAALEgHS3X78AAAEl0lEQVRIia2WS2hdZRDHf/Odc+7NvbZpYky1Gk2rEbRa26pt8UWLitYHIqigCD426kIQxCfWhYu68U0RBBERXCq+WrXoorYIFWpbEY0lpk0NTWKtuUlzn+d834yLm5smqQspzurMcM785j+c+eYTTtUcESAzvhIAm/+azHacA4FodszAVNFTrUPm+Q6iecmUyJkEna5OiDCCXCtvJ2cnV+Ep+9R7/VIfQhmeryKeySywok+SSMMKMwqAihDXPIcPDDMURUQCgiPWjJCck6x87ZXXV3cXu3XTO5tkYOvAHbnIfZipTpghLdAMIEngi1cXvtlzwfrHpG0x5ismzsvo0E9D9z7z++M799s2EcSm67OUkAs5cpbzkkoMtPtAAzdXQ9zqjHkt1Ol5SHofx0KWYRUxrdiS3FlLtzz51wd7+v2OQl7qHnPtorUXS3ZxPRUKUT5x4mTDWu559LbCNS+9X9v025Duc4KoYdMAA7A4Mk92EMp/JFIZwR/rx9dL1teVdC2/Qe8yzQg+pS0JvLUzx3hjioPVQamGGlcu47KNq6qrPj+fsd+GeAEYA2SmRQiCNSJKP1Ad3IVaG0nnlWRxKqkkVlYxJxGZwhmFIo34U/fh0Hv4v6YYrY+ihYtkorDUNj+298GPvzv6ZRrkMzA/oyCXh9rEMOOHfiLfcx+5zhXkOnppswxEpJHVxdTjs0CycDHy9XcMlwc5a0E3EoTconOls/dyBsb6lYRLY4m/9T6blDgi8oHw3rPx83fesubl4oVPWFvXBUKoQzqB92Xitpite77n/k/epaN7AZO1CTIROtZ14fJC6ccS9ndGUhRLK0Eum1h2YGpH5eFfD47sjluzcFo+f+vp655F03alNhZhASMjloA1qtzedzab125kiw2QLhHaQ0zIFM2MztUdkBcqx1Lp+0o59NGRP49OVQs0Z3d6nEyMUMP8OGgVtAJaA19CagP4xn4e6DPuPhox1V9HTRFr/h9mRmWkwbJtGSsHK4xXq4cQGQDCDABM0ClEy6DlJiA9DLV90BgktirFzhrPXX0mT6Y9lAaqkAhRItRKGT3bjetTYd2aYM7JYcwm5wwaAP44hDyQYukokg5jliICZoFIoNjZ4Ol1HdhueOPgCLlFjt7twvo63HwztGuipml20lEBBlrGfBXzR5BsDGjOPBrAAkJKRKBwuuepNUXyP5/HN7tKXFGvcuMGY/3qhAO/NLCTJ7kFmIT0OPgjmAhiYKYIASFgGoCUyAILu+o8ckng0jSwsF1YuzxP0hYwm3tizwIIpKPQOIY4BXUYCiiYYWSIKYYHMoRAV1fKTddFxJKQOA/mmW9zFWRjoCmYw6R1lrcg2kxgAfCIeRxKMa+YBSw0Vc7fOScAZuAnMXWYE8yaIUFBDFSbS8sCgscsayZWD3jMAmhT7b8CnDPIeZw6RGTOLmwWFRALMA3BZvkamoBcwM3Zh7MA9Yb5I3v/YKoKTlr9sROKZVrlTGDWsylmkMTGxCQ4h0ObGaT1aRJzHsbtwJJmWSet0/9kIpB69gPbgersJA4oMm/pn6JlQI1/uWX87/YP06p9rkZQnAYAAAAASUVORK5CYII='
|
||||
|
||||
github64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAADAwMDQ0NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhyjGAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdUAAA3VAT3WWPEAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAABzSURBVChTbYxRFoAgDMPQ+98Z1zbIeJqPbU3RMRfDECqyGpjMg6ivT6NBbKTw5WySq0jKt/sHrXiJ8PwpAAVIgQGkwABSYAApMIAUGEAalFmK9UJ24dC1i7qdj6IO5F+xnxfLu0jS0c7kqxd3Dk+JY8/5AKFrLuM7mfCAAAAAAElFTkSuQmCC'
|
||||
|
||||
|
||||
run64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAszD0iAAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdUAAA3VAT3WWPEAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAABqSURBVChTpY5JDsAwCMTy/09TMGvFpVF9aAZPRHpkcXC7OIodPg0uCjPq+MwCrWRGKkiIvLyTqzw3aqoI73eqUNAoXBXlg4zudxF+NONfPIVvbSZPgww5oW0Vz8T4Lgbt/xbjia+rahR5AEYEg4vdzh2JAAAAAElFTkSuQmCC'
|
||||
|
||||
storage64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAABwcHDQ0NDg4ODw8PFxcXGRkZGhoaGxsbHh4eIyMjJSUlJiYmJycnKCgoMTExMjIyNTU1NjY2Nzc3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAouNksgAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAADdQAAA3UAe+RuhUAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAC5SURBVChTfZLbDsMgDEPpbb3TDv7/W7PYuAztYUeqhO2QAGowkXIMIeYkaSU4QsNBi4GcyhNINpTglmq4GWSphvy/ldkuLXZ4HmAxy3NmFJaA4guKGCwsjClfV05+fWdhYBtFw+amB292aygW3M7fsPTwjmadZkCvHEtWaAYTViBqVwgTA3tJVnB6D/xhaimItDhjMBvlhtFsaIafnEtOaAY/twAw/eslK70CbX8obUvgJNw9Jv0+Zh8D4s5+VAm/LwAAAABJRU5ErkJggg=='
|
||||
|
||||
ShowMeTheButtons()
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import PySimpleGUI as sg
|
|||
Check out the variable menu_def for a hint on how to
|
||||
define menus
|
||||
"""
|
||||
|
||||
|
||||
def second_window():
|
||||
|
||||
layout = [[sg.Text('The second form is small \nHere to show that opening a window using a window works')],
|
||||
|
@ -15,23 +17,24 @@ def second_window():
|
|||
event, values = window.read()
|
||||
window.close()
|
||||
|
||||
def test_menus():
|
||||
|
||||
def test_menus():
|
||||
|
||||
sg.change_look_and_feel('LightGreen')
|
||||
sg.set_options(element_padding=(0, 0))
|
||||
|
||||
# ------ Menu Definition ------ #
|
||||
menu_def = [['&File', ['&Open', '&Save', '&Properties', 'E&xit' ]],
|
||||
['&Edit', ['&Paste', ['Special', 'Normal',], 'Undo'],],
|
||||
['&Toolbar', ['---', 'Command &1', 'Command &2', '---', 'Command &3', 'Command &4']],
|
||||
['&Help', '&About...'],]
|
||||
menu_def = [['&File', ['&Open', '&Save', '&Properties', 'E&xit']],
|
||||
['&Edit', ['&Paste', ['Special', 'Normal', ], 'Undo'], ],
|
||||
['&Toolbar', ['---', 'Command &1', 'Command &2',
|
||||
'---', 'Command &3', 'Command &4']],
|
||||
['&Help', '&About...'], ]
|
||||
|
||||
# ------ GUI Defintion ------ #
|
||||
layout = [
|
||||
[sg.Menu(menu_def, tearoff=False, pad=(20,1))],
|
||||
[sg.Output(size=(60,20))],
|
||||
]
|
||||
[sg.Menu(menu_def, tearoff=False, pad=(20, 1))],
|
||||
[sg.Output(size=(60, 20))],
|
||||
]
|
||||
|
||||
window = sg.Window("Windows-like program",
|
||||
layout,
|
||||
|
@ -43,13 +46,14 @@ def test_menus():
|
|||
# ------ Loop & Process button menu choices ------ #
|
||||
while True:
|
||||
event, values = window.read()
|
||||
if event is None or event == 'Exit':
|
||||
if event in (None, 'Exit'):
|
||||
return
|
||||
print('Event = ', event)
|
||||
# ------ Process menu choices ------ #
|
||||
if event == 'About...':
|
||||
window.disappear()
|
||||
sg.popup('About this program','Version 1.0', 'PySimpleGUI rocks...', grab_anywhere=True)
|
||||
sg.popup('About this program', 'Version 1.0',
|
||||
'PySimpleGUI rocks...', grab_anywhere=True)
|
||||
window.reappear()
|
||||
elif event == 'Open':
|
||||
filename = sg.popup_get_file('file to open', no_window=True)
|
||||
|
@ -57,4 +61,7 @@ def test_menus():
|
|||
elif event == 'Properties':
|
||||
second_window()
|
||||
|
||||
test_menus()
|
||||
window.close()
|
||||
|
||||
|
||||
test_menus()
|
||||
|
|
|
@ -1,46 +1,50 @@
|
|||
#!/usr/bin/env python
|
||||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUI as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
import PySimpleGUI as sg
|
||||
|
||||
'''
|
||||
Parallel windows executing.
|
||||
'''
|
||||
|
||||
layout1 = [[ sg.Text('Window 1') ],
|
||||
[sg.Input(do_not_clear=True)],
|
||||
[sg.Input('')],
|
||||
[ sg.Button('Read')]]
|
||||
|
||||
window1 = sg.Window('My new window', location=(800,500)).Layout(layout1)
|
||||
window1 = sg.Window('My new window', layout1, location=(800,500))
|
||||
|
||||
|
||||
layout2 = [[ sg.Text('Window 2') ],
|
||||
[sg.Input(do_not_clear=True)],
|
||||
[sg.Input('')],
|
||||
[ sg.Button('Read')]]
|
||||
|
||||
window2 = sg.Window('My new window', location=(800, 625), return_keyboard_events=True).Layout(layout2)
|
||||
window2 = sg.Window('My new window', layout2, location=(800, 625), return_keyboard_events=True)
|
||||
|
||||
|
||||
layout3 = [[ sg.Text('Window 3') ],
|
||||
[sg.Input(do_not_clear=False)],
|
||||
[ sg.Button('Read')]]
|
||||
|
||||
window3 = sg.Window('My new window', location=(800,750), return_keyboard_events=True).Layout(layout3)
|
||||
window3 = sg.Window('My new window', layout3, location=(800,750), return_keyboard_events=True)
|
||||
|
||||
|
||||
while True: # Event Loop
|
||||
event, values = window1.Read(timeout=50)
|
||||
event, values = window1.read(timeout=0)
|
||||
if event is None:
|
||||
break
|
||||
elif event != '__timeout__':
|
||||
print(event, values)
|
||||
|
||||
event, values = window2.Read(timeout=0)
|
||||
event, values = window2.read(timeout=0)
|
||||
if event is None:
|
||||
break
|
||||
elif event != '__timeout__':
|
||||
print(event, values)
|
||||
|
||||
event, values = window3.Read(timeout=0)
|
||||
event, values = window3.read(timeout=0)
|
||||
if event is None:
|
||||
break
|
||||
elif event != '__timeout__':
|
||||
print(event, values)
|
||||
|
||||
window1.close()
|
||||
window2.close()
|
||||
window3.close()
|
|
@ -1,9 +1,4 @@
|
|||
import sys
|
||||
if sys.version_info[0] >= 3:
|
||||
import PySimpleGUIQt as sg
|
||||
else:
|
||||
import PySimpleGUI27 as sg
|
||||
|
||||
import PySimpleGUI as sg
|
||||
import queue
|
||||
import logging
|
||||
import threading
|
||||
|
@ -49,15 +44,18 @@ class QueueHandler(logging.Handler):
|
|||
|
||||
|
||||
def main():
|
||||
window = sg.FlexForm('Log window', default_element_size=(30, 2), font=('Helvetica', ' 10'), default_button_element_size=(8, 2), return_keyboard_events=True)
|
||||
|
||||
layout = \
|
||||
[
|
||||
[sg.Multiline(size=(50, 15), key='Log')],
|
||||
[sg.Button('Start', bind_return_key=True, key='_START_'), sg.Button('Exit')]
|
||||
layout = [
|
||||
[sg.MLine(size=(50, 15), key='Log')],
|
||||
[sg.Button('Start', bind_return_key=True, key='-START-'), sg.Button('Exit')]
|
||||
]
|
||||
|
||||
window.Layout(layout).Read(timeout=0)
|
||||
window = sg.FlexForm('Log window', layout,
|
||||
default_element_size=(30, 2),
|
||||
font=('Helvetica', ' 10'),
|
||||
default_button_element_size=(8, 2),
|
||||
return_keyboard_events=True)
|
||||
window.read(timeout=0)
|
||||
appStarted = False
|
||||
|
||||
# Setup logging and start app
|
||||
|
@ -70,13 +68,13 @@ def main():
|
|||
# Loop taking in user input and querying queue
|
||||
while True:
|
||||
# Wake every 100ms and look for work
|
||||
event, values = window.Read(timeout=100)
|
||||
event, values = window.read(timeout=100)
|
||||
|
||||
if event == '_START_':
|
||||
if event == '-START-':
|
||||
if appStarted is False:
|
||||
threadedApp.start()
|
||||
logger.debug('App started')
|
||||
window.FindElement('_START_').Update(disabled=True)
|
||||
window['-START-'].update(disabled=True)
|
||||
appStarted = True
|
||||
elif event in (None, 'Exit'):
|
||||
break
|
||||
|
@ -88,10 +86,9 @@ def main():
|
|||
pass
|
||||
else:
|
||||
msg = queue_handler.format(record)
|
||||
window.FindElement('Log').Update(msg+'\n', append=True)
|
||||
window['Log'].update(msg+'\n', append=True)
|
||||
|
||||
window.Close()
|
||||
exit()
|
||||
window.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import queue
|
||||
import threading
|
||||
import time
|
||||
import PySimpleGUI as sg
|
||||
|
||||
# This program has been tested on all flavors of PySimpleGUI and it works with no problems at all
|
||||
# To try something other than tkinter version, just comment out the first import and uncomment the one you want
|
||||
import PySimpleGUI as sg
|
||||
# import PySimpleGUIQt as sg
|
||||
# import PySimpleGUIWx as sg
|
||||
# import PySimpleGUIWeb as sg
|
||||
|
||||
"""
|
||||
DESIGN PATTERN - Multithreaded Long Tasks GUI
|
||||
|
@ -41,14 +37,6 @@ def long_operation_thread(seconds, gui_queue):
|
|||
gui_queue.put('** Done **') # put a message into queue for GUI
|
||||
|
||||
|
||||
###### ## ## ####
|
||||
## ## ## ## ##
|
||||
## ## ## ##
|
||||
## #### ## ## ##
|
||||
## ## ## ## ##
|
||||
## ## ## ## ##
|
||||
###### ####### ####
|
||||
|
||||
def the_gui():
|
||||
"""
|
||||
Starts and executes the GUI
|
||||
|
@ -60,23 +48,27 @@ def the_gui():
|
|||
|
||||
layout = [[sg.Text('Long task to perform example')],
|
||||
[sg.Output(size=(70, 12))],
|
||||
[sg.Text('Number of seconds your task will take'),sg.Input(key='_SECONDS_', size=(5,1)), sg.Button('Do Long Task', bind_return_key=True)],
|
||||
[sg.Text('Number of seconds your task will take'),
|
||||
sg.Input(key='-SECONDS-', size=(5, 1)),
|
||||
sg.Button('Do Long Task', bind_return_key=True)],
|
||||
[sg.Button('Click Me'), sg.Button('Exit')], ]
|
||||
|
||||
window = sg.Window('Multithreaded Window').Layout(layout)
|
||||
window = sg.Window('Multithreaded Window', layout)
|
||||
|
||||
# --------------------- EVENT LOOP ---------------------
|
||||
while True:
|
||||
event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
|
||||
if event is None or event == 'Exit':
|
||||
event, values = window.read(timeout=100)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
elif event.startswith('Do'):
|
||||
try:
|
||||
seconds = int(values['_SECONDS_'])
|
||||
print('Starting thread to do long work....sending value of {} seconds'.format(seconds))
|
||||
threading.Thread(target=long_operation_thread, args=(seconds , gui_queue,), daemon=True).start()
|
||||
seconds = int(values['-SECONDS-'])
|
||||
print('Thread ALIVE! Long work....sending value of {} seconds'.format(seconds))
|
||||
threading.Thread(target=long_operation_thread,
|
||||
args=(seconds, gui_queue,), daemon=True).start()
|
||||
except Exception as e:
|
||||
print('Error starting work thread. Did you input a valid # of seconds? You entered: %s' % values['_SECONDS_'])
|
||||
print('Error starting work thread. Bad seconds input: "%s"' %
|
||||
values['-SECONDS-'])
|
||||
elif event == 'Click Me':
|
||||
print('Your GUI is alive and well')
|
||||
# --------------- Check for incoming messages from threads ---------------
|
||||
|
@ -90,17 +82,8 @@ def the_gui():
|
|||
print('Got a message back from the thread: ', message)
|
||||
|
||||
# if user exits the window, then close the window and exit the GUI func
|
||||
window.Close()
|
||||
|
||||
|
||||
## ## ### #### ## ##
|
||||
### ### ## ## ## ### ##
|
||||
#### #### ## ## ## #### ##
|
||||
## ### ## ## ## ## ## ## ##
|
||||
## ## ######### ## ## ####
|
||||
## ## ## ## ## ## ###
|
||||
## ## ## ## #### ## ##
|
||||
window.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
the_gui()
|
||||
print('Exiting Program')
|
||||
print('Exiting Program')
|
||||
|
|
|
@ -8,13 +8,7 @@ import queue
|
|||
import threading
|
||||
import time
|
||||
import itertools
|
||||
|
||||
# This program has been tested on all flavors of PySimpleGUI and it works with no problems at all
|
||||
# To try something other than tkinter version, just comment out the first import and uncomment the one you want
|
||||
import PySimpleGUI as sg
|
||||
# import PySimpleGUIQt as sg
|
||||
# import PySimpleGUIWx as sg
|
||||
# import PySimpleGUIWeb as sg
|
||||
|
||||
"""
|
||||
DESIGN PATTERN - Multithreaded GUI
|
||||
|
@ -33,13 +27,13 @@ import PySimpleGUI as sg
|
|||
"""
|
||||
|
||||
|
||||
######## ## ## ######## ######## ### ########
|
||||
## ## ## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ## ## ## ## ##
|
||||
## ######### ######## ###### ## ## ## ##
|
||||
## ## ## ## ## ## ######### ## ##
|
||||
## ## ## ## ## ## ## ## ## ##
|
||||
## ## ## ## ## ######## ## ## ########
|
||||
# ######## ## ## ######## ######## ### ########
|
||||
# ## ## ## ## ## ## ## ## ## ##
|
||||
# ## ## ## ## ## ## ## ## ## ##
|
||||
# ## ######### ######## ###### ## ## ## ##
|
||||
# ## ## ## ## ## ## ######### ## ##
|
||||
# ## ## ## ## ## ## ## ## ## ##
|
||||
# ## ## ## ## ## ######## ## ## ########
|
||||
|
||||
def worker_thread(thread_name, run_freq, gui_queue):
|
||||
"""
|
||||
|
@ -54,15 +48,17 @@ def worker_thread(thread_name, run_freq, gui_queue):
|
|||
print('Starting thread - {} that runs every {} ms'.format(thread_name, run_freq))
|
||||
for i in itertools.count(): # loop forever, keeping count in i as it loops
|
||||
time.sleep(run_freq/1000) # sleep for a while
|
||||
gui_queue.put('{} - {}'.format(thread_name, i)) # put a message into queue for GUI
|
||||
# put a message into queue for GUI
|
||||
gui_queue.put('{} - {}'.format(thread_name, i))
|
||||
|
||||
# ###### ## ## ####
|
||||
# ## ## ## ## ##
|
||||
# ## ## ## ##
|
||||
# ## #### ## ## ##
|
||||
# ## ## ## ## ##
|
||||
# ## ## ## ## ##
|
||||
# ###### ####### ####
|
||||
|
||||
###### ## ## ####
|
||||
## ## ## ## ##
|
||||
## ## ## ##
|
||||
## #### ## ## ##
|
||||
## ## ## ## ##
|
||||
## ## ## ## ##
|
||||
###### ####### ####
|
||||
|
||||
def the_gui(gui_queue):
|
||||
"""
|
||||
|
@ -73,18 +69,19 @@ def the_gui(gui_queue):
|
|||
:param gui_queue: Queue the GUI should read from
|
||||
:return:
|
||||
"""
|
||||
layout = [ [sg.Text('Multithreaded Window Example')],
|
||||
[sg.Text('', size=(15,1), key='_OUTPUT_')],
|
||||
[sg.Output(size=(40,6))],
|
||||
[sg.Button('Exit')],]
|
||||
layout = [[sg.Text('Multithreaded Window Example')],
|
||||
[sg.Text('', size=(15, 1), key='-OUTPUT-')],
|
||||
[sg.Output(size=(40, 6))],
|
||||
[sg.Button('Exit')], ]
|
||||
|
||||
window = sg.Window('Multithreaded Window').Layout(layout)
|
||||
window = sg.Window('Multithreaded Window', layout)
|
||||
# --------------------- EVENT LOOP ---------------------
|
||||
while True:
|
||||
event, values = window.Read(timeout=100) # wait for up to 100 ms for a GUI event
|
||||
if event is None or event == 'Exit':
|
||||
# wait for up to 100 ms for a GUI event
|
||||
event, values = window.read(timeout=100)
|
||||
if event in (None, 'Exit'):
|
||||
break
|
||||
#--------------- Loop through all messages coming in from threads ---------------
|
||||
# --------------- Loop through all messages coming in from threads ---------------
|
||||
while True: # loop executes until runs out of messages in Queue
|
||||
try: # see if something has been posted to Queue
|
||||
message = gui_queue.get_nowait()
|
||||
|
@ -92,11 +89,12 @@ def the_gui(gui_queue):
|
|||
break # break from the loop if no more messages are queued up
|
||||
# if message received from queue, display the message in the Window
|
||||
if message:
|
||||
window.Element('_OUTPUT_').Update(message)
|
||||
window.Refresh() # do a refresh because could be showing multiple messages before next Read
|
||||
window['-OUTPUT-'].update(message)
|
||||
# do a refresh because could be showing multiple messages before next Read
|
||||
window.refresh()
|
||||
print(message)
|
||||
# if user exits the window, then close the window and exit the GUI func
|
||||
window.Close()
|
||||
window.close()
|
||||
|
||||
|
||||
## ## ### #### ## ##
|
||||
|
@ -108,12 +106,16 @@ def the_gui(gui_queue):
|
|||
## ## ## ## #### ## ##
|
||||
|
||||
if __name__ == '__main__':
|
||||
#-- Create a Queue to communicate with GUI --
|
||||
gui_queue = queue.Queue() # queue used to communicate between the gui and the threads
|
||||
#-- Start worker threads, one runs twice as often as the other
|
||||
threading.Thread(target=worker_thread, args=('Thread 1', 500, gui_queue,), daemon=True).start()
|
||||
threading.Thread(target=worker_thread, args=('Thread 2', 200, gui_queue,), daemon=True).start()
|
||||
threading.Thread(target=worker_thread, args=('Thread 3', 1000, gui_queue,), daemon=True).start()
|
||||
#-- Start the GUI passing in the Queue --
|
||||
# -- Create a Queue to communicate with GUI --
|
||||
# queue used to communicate between the gui and the threads
|
||||
gui_queue = queue.Queue()
|
||||
# -- Start worker threads, one runs twice as often as the other
|
||||
threading.Thread(target=worker_thread, args=(
|
||||
'Thread 1', 500, gui_queue,), daemon=True).start()
|
||||
threading.Thread(target=worker_thread, args=(
|
||||
'Thread 2', 200, gui_queue,), daemon=True).start()
|
||||
threading.Thread(target=worker_thread, args=(
|
||||
'Thread 3', 1000, gui_queue,), daemon=True).start()
|
||||
# -- Start the GUI passing in the Queue --
|
||||
the_gui(gui_queue)
|
||||
print('Exiting Program')
|
||||
print('Exiting Program')
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue