Merge pull request #196 from MikeTheWatchGuy/Dev-latest

Added Enable/Disable to all input elements!  Refresh of many Demo pro…
This commit is contained in:
MikeTheWatchGuy 2018-09-11 08:39:19 -04:00 committed by GitHub
commit fe5c02f684
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 389 additions and 302 deletions

View File

@ -8,15 +8,13 @@ states for buttons and changes the text color to show greyed-out (disabled) butt
sg.ChangeLookAndFeel('Dark')
sg.SetOptions(element_padding=(0,0))
StartButton = sg.ReadFormButton('Start', button_color=('white', 'black'))
StopButton = sg.ReadFormButton('Stop', button_color=('gray34','black'))
ResetButton = sg.ReadFormButton('Reset', button_color=('gray','firebrick3'))
SubmitButton = sg.ReadFormButton('Submit', button_color=('gray34','springgreen4'))
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')],
[StartButton, StopButton, ResetButton, SubmitButton]
[sg.ReadFormButton('Start', button_color=('white', 'black'), key='start'),
sg.ReadFormButton('Stop', button_color=('gray34', 'black'), key='stop'),
sg.ReadFormButton('Reset', button_color=('gray', 'firebrick3'), key='reset'),
sg.ReadFormButton('Submit', button_color=('gray34', 'springgreen4'), key='submit')]
]
form = sg.FlexForm("Time Tracker", default_element_size=(12,1), text_justification='r', auto_size_text=False, auto_size_buttons=False,
@ -28,27 +26,27 @@ while True:
if button is None:
exit(69)
if button is 'Start':
StartButton.Update(button_color=('gray34','black'))
StopButton.Update(button_color=('white', 'black'))
ResetButton.Update(button_color=('white', 'firebrick3'))
form.FindElement('start').Update(button_color=('gray34','black'))
form.FindElement('stop').Update(button_color=('white', 'black'))
form.FindElement('reset').Update(button_color=('white', 'firebrick3'))
recording = True
elif button is 'Stop' and recording:
StopButton.Update(button_color=('gray34','black'))
StartButton.Update(button_color=('white', 'black'))
SubmitButton.Update(button_color=('white', 'springgreen4'))
form.FindElement('stop').Update(button_color=('gray34','black'))
form.FindElement('start').Update(button_color=('white', 'black'))
form.FindElement('submit').Update(button_color=('white', 'springgreen4'))
recording = False
have_data = True
elif button is 'Reset':
StopButton.Update(button_color=('gray34','black'))
StartButton.Update(button_color=('white', 'black'))
SubmitButton.Update(button_color=('gray34', 'springgreen4'))
ResetButton.Update(button_color=('gray34', 'firebrick3'))
form.FindElement('stop').Update(button_color=('gray34','black'))
form.FindElement('start').Update(button_color=('white', 'black'))
form.FindElement('submit').Update(button_color=('gray34', 'springgreen4'))
form.FindElement('reset').Update(button_color=('gray34', 'firebrick3'))
recording = False
have_data = False
elif button is 'Submit' and have_data:
StopButton.Update(button_color=('gray34','black'))
StartButton.Update(button_color=('white', 'black'))
SubmitButton.Update(button_color=('gray34', 'springgreen4'))
ResetButton.Update(button_color=('gray34', 'firebrick3'))
form.FindElement('stop').Update(button_color=('gray34','black'))
form.FindElement('start').Update(button_color=('white', 'black'))
form.FindElement('submit').Update(button_color=('gray34', 'springgreen4'))
form.FindElement('reset').Update(button_color=('gray34', 'firebrick3'))
recording = False

View File

@ -109,25 +109,34 @@ def AllWidgetsWithContext():
# sg.ChangeLookAndFeel('GreenTan')
with sg.FlexForm('Everything bagel', default_element_size=(40, 1), grab_anywhere=False) as form:
column1 = [[sg.Text('Column 1', background_color='#F7F3EC', 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 3')]]
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()],
[sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)],
[sg.InputText('This is my text')],
[sg.Checkbox('Checkbox'), sg.Checkbox('My second checkbox!', default=True)],
[sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")],
[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, 3)),
[sg.InputCombo(('Combobox 1', 'Combobox 2'), size=(20, 1)),
sg.Slider(range=(1, 100), orientation='h', size=(34, 20), default_value=85)],
[sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3', 'Listbox 4'), size=(30, 3)),
[sg.InputOptionMenu(('Menu Option 1', 'Menu Option 2', 'Menu Option 3'))],
[sg.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=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.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],
sg.Column(column1, background_color='#F7F3EC')],
[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'), sg.FolderBrowse()],
[sg.Submit(), sg.Cancel(), sg.SimpleButton('Customized', button_color=('black', '#EDE5B7'))]]
[sg.Submit(), sg.Cancel()]
]
button, values = form.LayoutAndRead(layout)
@ -137,30 +146,36 @@ def AllWidgetsNoContext():
"""
import PySimpleGUI as sg
# Green & tan color scheme
sg.ChangeLookAndFeel('GreenTan')
form = sg.FlexForm('Everything bagel', default_element_size=(40, 1), grab_anywhere=False)
column1 = [[sg.Text('Column 1', background_color='#F7F3EC', 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 3')]]
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')],
[sg.Checkbox('My first checkbox!'), sg.Checkbox('My second checkbox!', default=True)],
[sg.Checkbox('Checkbox'), sg.Checkbox('My second checkbox!', default=True)],
[sg.Radio('My first Radio! ', "RADIO1", default=True), sg.Radio('My second Radio!', "RADIO1")],
[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, 3)),
[sg.InputCombo(('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.Listbox(values=('Listbox 1', 'Listbox 2', 'Listbox 3'), size=(30, 3)),
sg.Slider(range=(1, 100), orientation='v', size=(5, 20), default_value=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.Spin(values=('Spin Box 1', '2', '3'), initial_value='Spin Box 1')],
sg.Column(column1, background_color='#F7F3EC')],
[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'), sg.FolderBrowse()],
[sg.Submit(), sg.Cancel(), sg.SimpleButton('Customized', button_color=('white', '#7E6C92'))]
[sg.Submit(), sg.Cancel()]
]
button, values = form.LayoutAndRead(layout)
@ -175,10 +190,9 @@ def NonBlockingWithUpdates():
form = sg.FlexForm('Running Timer')
# create a text element that will be updated periodically
text_element = sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center')
form_rows = [[sg.Text('Stopwatch', size=(20,2), justification='center')],
[text_element],
[ sg.Text('', size=(10, 2), font=('Helvetica', 20), justification='center', key='output')],
[sg.T(' ' * 5), sg.ReadFormButton('Start/Stop', focus=True), sg.Quit()]]
form.LayoutAndRead(form_rows, non_blocking=True)
@ -193,7 +207,7 @@ def NonBlockingWithUpdates():
break
elif button == 'Start/Stop':
timer_running = not timer_running
text_element.Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
form.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
time.sleep(.01)
# if the loop finished then need to close the form for the user
@ -208,14 +222,13 @@ def NonBlockingWithContext():
import time
with sg.FlexForm('Running Timer') as form:
text_element = sg.Text('', size=(10, 2), font=('Helvetica', 20), text_color='red', justification='center')
layout = [[sg.Text('Non blocking GUI with updates', justification='center')],
[text_element],
[sg.Text('', size=(10, 2), font=('Helvetica', 20), text_color='red', justification='center', key='output')],
[sg.T(' ' * 15), sg.Quit()]]
form.LayoutAndRead(layout, non_blocking=True)
for i in range(1, 500):
text_element.Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
form.FindElement('output').Update('{:02d}:{:02d}.{:02d}'.format((i // 100) // 60, (i // 100) % 60, i % 100))
button, values = form.ReadNonBlocking()
if values is None or button == 'Quit': # if user closed the window using X
break
@ -451,16 +464,7 @@ def MachineLearning():
"""
import PySimpleGUI as sg
# Green & tan color scheme
sg.SetOptions(background_color='#9FB8AD',
text_element_background_color='#9FB8AD',
element_background_color='#9FB8AD',
input_elements_background_color='#F7F3EC',
button_color=('white', '#475841'),
border_width=0,
slider_border_width=0,
progress_meter_border_depth=0,
scrollbar_color='#F7F3EC')
sg.ChangeLookAndFeel('LightGreen')
sg.SetOptions(text_justification='right')
@ -645,8 +649,6 @@ def InputElementUpdate():
"""
import PySimpleGUI as g
# g.SetOptions(button_color=g.COLOR_SYSTEM_DEFAULT) # because some people like gray buttons
# Demonstrates a number of PySimpleGUI features including:
# Default element size
# auto_size_buttons
@ -655,17 +657,13 @@ def InputElementUpdate():
# Update of elements in form (Text, Input)
# do_not_clear of Input elements
# create the 2 Elements we want to control outside the form
out_elem = g.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red')
in_elem = g.Input(size=(10, 1), do_not_clear=True, key='input')
layout = [[g.Text('Enter Your Passcode')],
[in_elem],
[g.Input(size=(10, 1), do_not_clear=True, key='input')],
[g.ReadFormButton('1'), g.ReadFormButton('2'), g.ReadFormButton('3')],
[g.ReadFormButton('4'), g.ReadFormButton('5'), g.ReadFormButton('6')],
[g.ReadFormButton('7'), g.ReadFormButton('8'), g.ReadFormButton('9')],
[g.ReadFormButton('Submit'), g.ReadFormButton('0'), g.ReadFormButton('Clear')],
[out_elem],
[ g.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='output')],
]
form = g.FlexForm('Keypad', default_element_size=(5, 2), auto_size_buttons=False)
@ -684,9 +682,9 @@ def InputElementUpdate():
keys_entered += button # add the new digit
elif button is 'Submit':
keys_entered = values['input']
out_elem.Update(keys_entered) # output the final string
form.FindElement('outpput').Update(keys_entered) # output the final string
in_elem.Update(keys_entered) # change the form to reflect current key string
form.FindElement('input').Update(keys_entered) # change the form to reflect current key string
def TableSimulation():
@ -751,13 +749,12 @@ fig_dict = {'Simple Data Entry':SimpleDataEntry, 'Simple Entry Return Data as Di
'Table Simulation':TableSimulation, 'Tight Layout':TightLayout}
# multiline_elem = sg.Multiline(size=(70,35),pad=(5,(3,90)))
# define the form layout
listbox_values = [key for key in fig_dict.keys()]
while True:
# sg.ChangeLookAndFeel('Dark')
# sg.SetOptions(element_padding=(0,0))
sg.ChangeLookAndFeel('Dark')
sg.SetOptions(element_padding=(0,0))
col_listbox = [[sg.Listbox(values=listbox_values, size=(max(len(x) for x in listbox_values),min(len(listbox_values), 20)), change_submits=False, key='func')],
[sg.ReadFormButton('Run', pad=(0,0)), sg.ReadFormButton('Show Code', button_color=('white', 'gray25'), pad=(0,0)), sg.Exit(button_color=('white', 'firebrick4'), pad=(0,0))]]

View File

@ -13,47 +13,48 @@ import time
invalid command name "1616802625480StopMove"
"""
def Timer():
# ---------------- Create Form ----------------
sg.ChangeLookAndFeel('Black')
sg.SetOptions(element_padding=(0,0))
# Make a form, but don't use context manager
# Create the form layout
form_rows = [[sg.Text('')],
# ---------------- Create Form ----------------
sg.ChangeLookAndFeel('Black')
sg.SetOptions(element_padding=(0, 0))
# Make a form, but don't use context manager
# Create the form layout
form_rows = [[sg.Text('')],
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
[sg.ReadFormButton('Pause', key='button', button_color=('white', '#001480')), sg.ReadFormButton('Reset', button_color=('white', '#007339')), sg.Exit(button_color=('white','firebrick4'))]]
# Layout the rows of the form and perform a read. Indicate the form is non-blocking!
form = sg.FlexForm('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True)
form.Layout(form_rows)
#
# ---------------- main loop ----------------
current_time = 0
paused = False
start_time = int(round(time.time()*100))
while (True):
[sg.ReadFormButton('Pause', key='button', button_color=('white', '#001480')),
sg.ReadFormButton('Reset', button_color=('white', '#007339')),
sg.Exit(button_color=('white', 'firebrick4'))]]
# Layout the rows of the form and perform a read. Indicate the form is non-blocking!
form = sg.FlexForm('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True)
form.Layout(form_rows)
#
# ---------------- main loop ----------------
current_time = 0
paused = False
start_time = int(round(time.time() * 100))
while (True):
# --------- Read and update window --------
if not paused:
button, values = form.ReadNonBlocking()
current_time = int(round(time.time()*100)) - start_time
current_time = int(round(time.time() * 100)) - start_time
else:
button, values = form.Read()
# --------- Do Button Operations --------
if values is None or button == 'Exit':
break
if button is 'Reset':
start_time = int(round(time.time()*100))
start_time = int(round(time.time() * 100))
current_time = 0
paused_time = start_time
elif button == 'Pause':
paused = True
paused_time = int(round(time.time()*100))
paused_time = int(round(time.time() * 100))
element = form.FindElement('button')
element.Update(new_text='Run')
element.Update(text='Run')
elif button == 'Run':
paused = False
start_time = start_time + int(round(time.time()*100)) - paused_time
start_time = start_time + int(round(time.time() * 100)) - paused_time
element = form.FindElement('button')
element.Update(new_text='Pause')
element.Update(text='Pause')
# --------- Display timer in window --------
form.FindElement('text').Update('{:02d}:{:02d}.{:02d}'.format((current_time // 100) // 60,
@ -61,9 +62,7 @@ def Timer():
current_time % 100))
time.sleep(.01)
# --------- After loop --------
# --------- After loop --------
# Broke out of main loop. Close the window.
form.CloseNonBlockingForm()
Timer()
# Broke out of main loop. Close the window.
form.CloseNonBlockingForm()

View File

@ -18,7 +18,7 @@ with sg.FlexForm("Keyboard Test", return_keyboard_events=True, use_default_focus
print(button, "exiting")
break
if len(button) == 1:
text_elem.Update(new_value='%s - %s'%(button, ord(button)))
text_elem.Update(value='%s - %s' % (button, ord(button)))
if button is not None:
text_elem.Update(button)

View File

@ -1,43 +1,56 @@
import PySimpleGUI as sg
# g.SetOptions(button_color=g.COLOR_SYSTEM_DEFAULT) # because some people like gray buttons
# Demonstrates a number of PySimpleGUI features including:
# Default element size
# auto_size_buttons
# ReadFormButton
# Dictionary return values
# Update of elements in form (Text, Input)
# do_not_clear of Input elements
from tkinter import *
from random import randint
import PySimpleGUI as g
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, FigureCanvasAgg
from matplotlib.figure import Figure
import matplotlib.backends.tkagg as tkagg
import tkinter as Tk
# create the 2 Elements we want to control outside the form
def main():
fig = Figure()
layout = [[sg.Text('Enter Your Passcode')],
[sg.Input(size=(10, 1), do_not_clear=True, key='input')],
[sg.ReadFormButton('1'), sg.ReadFormButton('2'), sg.ReadFormButton('3')],
[sg.ReadFormButton('4'), sg.ReadFormButton('5'), sg.ReadFormButton('6')],
[sg.ReadFormButton('7'), sg.ReadFormButton('8'), sg.ReadFormButton('9')],
[sg.ReadFormButton('Submit'), sg.ReadFormButton('0'), sg.ReadFormButton('Clear')],
[sg.Text('', size=(15, 1), font=('Helvetica', 18), text_color='red', key='out')],
]
ax = fig.add_subplot(111)
ax.set_xlabel("X axis")
ax.set_ylabel("Y axis")
ax.grid()
form = sg.FlexForm('Keypad', default_button_element_size=(5, 2), auto_size_buttons=False)
form.Layout(layout)
layout = [[g.Text('Animated Matplotlib', size=(40, 1), justification='center', font='Helvetica 20')],
[g.Canvas(size=(640, 480), key='canvas')],
[g.ReadFormButton('Exit', size=(10, 2), pad=((280, 0), 3), font='Helvetica 14')]]
# Loop forever reading the form's values, updating the Input field
keys_entered = ''
while True:
button, values = form.Read() # read the form
if button is None: # if the X button clicked, just exit
break
if button is 'Clear': # clear keys if clear button
keys_entered = ''
elif button in '1234567890':
keys_entered = values['input'] # get what's been entered so far
keys_entered += button # add the new digit
elif button is 'Submit':
keys_entered = values['input']
form.FindElement('out').Update(keys_entered) # output the final string
# create the form and show it without the plot
form = g.FlexForm('Demo Application - Embedding Matplotlib In PySimpleGUI')
form.Layout(layout)
form.ReadNonBlocking()
form.FindElement('input').Update(keys_entered) # change the form to reflect current key string
canvas_elem = form.FindElement('canvas')
graph = FigureCanvasTkAgg(fig, master=canvas_elem.TKCanvas)
canvas = canvas_elem.TKCanvas
dpts = [randint(0, 10) for x in range(10000)]
for i in range(len(dpts)):
button, values = form.ReadNonBlocking()
if button is 'Exit' or values is None:
exit(69)
ax.cla()
ax.grid()
ax.plot(range(20), dpts[i:i + 20], color='purple')
graph.draw()
figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
figure_w, figure_h = int(figure_w), int(figure_h)
photo = Tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
canvas.create_image(640 / 2, 480 / 2, image=photo)
figure_canvas_agg = FigureCanvasAgg(fig)
figure_canvas_agg.draw()
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
# time.sleep(.1)
if __name__ == '__main__':
main()

View File

@ -645,7 +645,7 @@ def main():
layout = [[canvas_elem, sg.ReadFormButton('Exit', pad=(0, (210, 0)))]]
# create the form and show it without the plot
form = sg.FlexForm('Ping Graph', background_color='white')
form = sg.FlexForm('Ping Graph', background_color='white', grab_anywhere=True)
form.Layout(layout)
form.ReadNonBlocking()

View File

@ -4,9 +4,9 @@ import os
# Simple Image Browser based on PySimpleGUI
# Get the folder containing the images from the user
rc, folder = sg.GetPathBox('Image Browser', 'Image folder to open', default_path='')
if rc is False or folder is '':
sg.MsgBoxCancel('Cancelling')
folder = sg.PopupGetFolder('Image folder to open')
if folder is None:
sg.PopupCancel('Cancelling')
exit(0)
# get list of PNG files in folder
@ -14,52 +14,62 @@ png_files = [folder + '\\' + f for f in os.listdir(folder) if '.png' in f]
filenames_only = [f for f in os.listdir(folder) if '.png' in f]
if len(png_files) == 0:
sg.MsgBox('No PNG images in folder')
sg.Popup('No PNG images in folder')
exit(0)
# define menu layout
menu = [['File', ['Open Folder', 'Exit']], ['Help', ['About',]]]
# create the form that also returns keyboard events
form = sg.FlexForm('Image Browser', return_keyboard_events=True, location=(0,0), use_default_focus=False )
# make these 2 elements outside the layout because want to "update" them later
# initialize to the first PNG file in the list
image_elem = sg.Image(filename=png_files[0])
filename_display_elem = sg.Text(png_files[0], size=(80, 3))
file_num_display_elem = sg.Text('File 1 of {}'.format(len(png_files)), size=(15,1))
# define layout, show and read the form
col = [[filename_display_elem],
[image_elem],
[sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2)), file_num_display_elem]]
col = [[sg.Text(png_files[0], size=(80, 3), key='filename')],
[sg.Image(filename=png_files[0], key='image')],
[sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2)),
sg.Text('File 1 of {}'.format(len(png_files)), size=(15,1), key='filenum')]]
col_files = [[sg.Listbox(values=filenames_only, size=(60,30), key='listbox')],
[sg.ReadFormButton('Read')]]
layout = [[sg.Column(col_files), sg.Column(col)]]
layout = [[sg.Menu(menu)], [sg.Column(col_files), sg.Column(col)]]
button, values = form.LayoutAndRead(layout) # Shows form on screen
# loop reading the user input and displaying image, filename
i=0
while True:
# perform button and keyboard operations
# --------------------- Button & Keyboard ---------------------
if button is None:
break
elif button in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34') and i < len(png_files)-1:
i += 1
elif button in ('Prev', 'MouseWheel:Up', 'Up:38', 'Prior:33') and i > 0:
i -= 1
elif button == 'Exit':
exit(69)
if button == 'Read':
filename = folder + '\\' + values['listbox'][0]
# print(filename)
else:
filename = png_files[i]
filename = folder + '/' + values['listbox'][0] if button == 'Read' else png_files[i]
# ----------------- Menu choices -----------------
if button == 'Open Folder':
newfolder = sg.PopupGetFolder('New folder', no_window=True)
if newfolder is None:
continue
folder = newfolder
png_files = [folder + '/' + f for f in os.listdir(folder) if '.png' in f]
filenames_only = [f for f in os.listdir(folder) if '.png' in f]
form.FindElement('listbox').Update(values=filenames_only)
form.Refresh()
i = 0
elif button == 'About':
sg.Popup('Demo PNG Viewer Program', 'Please give PySimpleGUI a try!')
# update window with new image
image_elem.Update(filename=filename)
form.FindElement('image').Update(filename=filename)
# update window with filename
filename_display_elem.Update(filename)
form.FindElement('filename').Update(filename)
# update page display
file_num_display_elem.Update('File {} of {}'.format(i+1, len(png_files)))
form.FindElement('filenum').Update('File {} of {}'.format(i+1, len(png_files)))
# read the form
button, values = form.Read()

View File

@ -9,6 +9,8 @@ import hashlib
3. Type password into the GUI
4. Copy and paste hash code form GUI into variable named login_password_hash
5. Run program again and test your login!
6. Are you paying attention? The first person that can post an issue on GitHub with the
matching password to the hash code in this example gets a $5 PayPal payment
"""
# Use this GUI to get your password's hash code
@ -47,7 +49,7 @@ def PasswordMatches(password, hash):
return password_hash == hash
login_password_hash = '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'
login_password_hash = 'e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4'
password = sg.PopupGetText('Password', password_char='*')
if password == 'gui': # Remove when pasting into your program
HashGeneratorGUI() # Remove when pasting into your program

View File

@ -13,19 +13,4 @@ layout = [
button, values = form.LayoutAndRead(layout)
print(button, values, values['name'], values['address'], values['phone'])
form = sg.FlexForm('Simple data entry form') # begin with a blank form
layout = [
[sg.Text('Please enter your Name, Address, Phone')],
[sg.Text('Name', size=(15, 1)), sg.InputText('name')],
[sg.Text('Address', size=(15, 1)), sg.InputText('address')],
[sg.Text('Phone', size=(15, 1)), sg.InputText('phone')],
[sg.Ok(), sg.Cancel()]
]
button, values = form.LayoutAndRead(layout)
print(values)
name, address, phone = values
sg.MsgBox(button, values[0], values[1], values[2])
sg.Popup(button, values, values['name'], values['address'], values['phone'])

View File

@ -1,30 +1,68 @@
import csv
import PySimpleGUI as sg
def TableSimulation():
"""
Display data in a table format
"""
# sg.ChangeLookAndFeel('Dark')
sg.SetOptions(element_padding=(0,0))
layout = [[sg.T('Table Using Combos and Input Elements', font='Any 18')],
[sg.T('Row, Cal to change'),
menu_def = [['File', ['Open', 'Save', 'Exit']],
['Edit', ['Paste', ['Special', 'Normal',], 'Undo'],],
['Help', 'About...'],]
columm_layout = [[]]
MAX_ROWS = 60
MAX_COL = 10
for i in range(MAX_ROWS):
inputs = [sg.T('{}'.format(i), size=(4,1), justification='right')] + [sg.In(size=(10, 1), pad=(1, 1), justification='right', key=(i,j), do_not_clear=True) for j in range(MAX_COL)]
columm_layout.append(inputs)
layout = [ [sg.Menu(menu_def)],
[sg.T('Table Using Combos and Input Elements', font='Any 18')],
[sg.T('Type in a row, column and value. The form will update the values in realtime as you type'),
sg.In(key='inputrow', justification='right', size=(8,1), pad=(1,1), do_not_clear=True),
sg.In(key='inputcol', size=(8,1), pad=(1,1), justification='right', do_not_clear=True),
sg.In(key='value', size=(8,1), pad=(1,1), justification='right', do_not_clear=True)]]
for i in range(20):
inputs = [sg.In('{}{}'.format(i,j), size=(8, 1), pad=(1, 1), justification='right', key=(i,j), do_not_clear=True) for j in range(10)]
line = [sg.Combo(('Customer ID', 'Customer Name', 'Customer Info'))]
line.append(inputs)
layout.append(inputs)
sg.In(key='value', size=(8,1), pad=(1,1), justification='right', do_not_clear=True)],
[sg.Column(columm_layout, size=(815,600), scrollable=True)]]
form = sg.FlexForm('Table', return_keyboard_events=True, grab_anywhere=False)
form.Layout(layout)
while True:
button, values = form.Read()
if button is None:
# --- Process buttons --- #
if button is None or button == 'Exit':
break
elif button == 'About...':
sg.Popup('Demo of table capabilities')
elif button == 'Open':
filename = sg.PopupGetFile('filename to open', no_window=True, file_types=(("CSV Files","*.csv"),))
# --- populate table with file contents --- #
if filename is not None:
with open(filename, "r") as infile:
reader = csv.reader(infile)
try:
data = list(reader) # read everything else into a list of rows
except:
sg.PopupError('Error reading file')
continue
# clear the table
[form.FindElement((i,j)).Update('') for j in range(MAX_COL) for i in range(MAX_ROWS)]
for i, row in enumerate(data):
for j, item in enumerate(row):
location = (i,j)
try: # try the best we can at reading and filling the table
target_element = form.FindElement(location)
new_value = item
if target_element is not None and new_value != '':
target_element.Update(new_value)
except:
pass
# if a valid table location entered, change that location's value
try:
location = (int(values['inputrow']), int(values['inputcol']))
target_element = form.FindElement(location)

View File

@ -282,11 +282,16 @@ class InputText(Element):
super().__init__(ELEM_TYPE_INPUT_TEXT, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=fg, key=key, pad=pad)
def Update(self, new_value):
def Update(self, value=None, disable=None):
if disable is True:
self.TKEntry['state'] = 'disabled'
elif disable is False:
self.TKEntry['state'] = 'normal'
if value is not None:
try:
self.TKStringVar.set(new_value)
self.TKStringVar.set(value)
except: pass
self.DefaultText = new_value
self.DefaultText = value
def Get(self):
return self.TKStringVar.get()
@ -317,16 +322,13 @@ class InputCombo(Element):
super().__init__(ELEM_TYPE_INPUT_COMBO, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=fg, key=key, pad=pad)
def Update(self, value=None, values=None, disabled=False):
def Update(self, value=None, values=None, disable=None):
if values is not None:
try:
self.TKCombo['values'] = values
self.TKCombo.current(0)
except: pass
self.Values = values
self.TKCombo['state'] = 'disable' if disabled else 'enable'
for index, v in enumerate(self.Values):
if v == value:
try:
@ -334,6 +336,10 @@ class InputCombo(Element):
except: pass
self.DefaultValue = value
break
if disable == True:
self.TKCombo['state'] = 'disable'
elif disable == False:
self.TKCombo['state'] = 'enable'
def __del__(self):
@ -365,7 +371,10 @@ class InputOptionMenu(Element):
super().__init__(ELEM_TYPE_INPUT_OPTION_MENU, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=fg, key=key, pad=pad)
def Update(self, value):
def Update(self, value=None, values=None, disable=None):
if values is not None:
self.Values = values
if self.Values is not None:
for index, v in enumerate(self.Values):
if v == value:
try:
@ -373,6 +382,10 @@ class InputOptionMenu(Element):
except: pass
self.DefaultValue = value
break
if disable == True:
self.TKOptionMenu['state'] = 'disabled'
elif disable == False:
self.TKOptionMenu['state'] = 'normal'
def __del__(self):
@ -415,13 +428,20 @@ class Listbox(Element):
super().__init__(ELEM_TYPE_INPUT_LISTBOX, scale=scale, size=size, auto_size_text=auto_size_text, font=font, background_color=bg, text_color=fg, key=key, pad=pad)
def Update(self, values):
def Update(self, values=None, disable=None):
if disable == True:
self.TKListbox.configure(state='disabled')
elif disable == False:
self.TKListbox.configure(state='normal')
if values is not None:
self.TKListbox.delete(0, 'end')
for item in values:
self.TKListbox.insert(tk.END, item)
self.TKListbox.selection_set(0, 0)
self.Values = values
def SetValue(self, values):
for index, item in enumerate(self.Values):
try:
@ -466,14 +486,17 @@ class Radio(Element):
super().__init__(ELEM_TYPE_INPUT_RADIO, scale=scale , size=size, auto_size_text=auto_size_text, font=font, background_color=background_color, text_color=self.TextColor, key=key, pad=pad)
def Update(self, value):
if not value:
return
def Update(self, value=None, disable=None):
location = EncodeRadioRowCol(self.Position[0], self.Position[1])
if value is not None:
try:
self.TKIntVar.set(location)
except: pass
self.InitialState = value
if disable == True:
self.TKRadio['state'] = 'disabled'
elif disable == False:
self.TKRadio['state'] = 'normal'
def __del__(self):
try:
@ -508,15 +531,16 @@ class Checkbox(Element):
def Get(self):
return self.TKIntVar.get()
def Update(self, value):
def Update(self, value=None, disable=None):
if value is not None:
try:
if value is None:
self.TKCheckbutton.configure(state='disabled')
else:
self.TKCheckbutton.configure(state='normal')
self.TKIntVar.set(value)
except: pass
self.InitialState = value
except: pass
if disable == True:
self.TKCheckbutton.configure(state='disabled')
elif disable == False:
self.TKCheckbutton.configure(state='normal')
def __del__(self):
@ -550,17 +574,21 @@ class Spin(Element):
super().__init__(ELEM_TYPE_INPUT_SPIN, scale, size, auto_size_text, font=font,background_color=bg, text_color=fg, key=key, pad=pad)
return
def Update(self, new_value=None, new_values=None ):
if new_values != None:
def Update(self, value=None, values=None, disable=None):
if values != None:
old_value = self.TKStringVar.get()
self.Values = new_values
self.TKSpinBox.configure(values=new_values)
self.Values = values
self.TKSpinBox.configure(values=values)
self.TKStringVar.set(old_value)
if new_value is not None:
if value is not None:
try:
self.TKStringVar.set(new_value)
self.TKStringVar.set(value)
except: pass
self.DefaultValue = new_value
self.DefaultValue = value
if disable == True:
self.TKSpinBox.configure(state='disabled')
elif disable == False:
self.TKSpinBox.configure(state='normal')
def SpinChangedHandler(self, event):
@ -601,12 +629,17 @@ class Multiline(Element):
super().__init__(ELEM_TYPE_INPUT_MULTILINE, scale=scale, size=size, auto_size_text=auto_size_text, background_color=bg, text_color=fg, key=key, pad=pad)
return
def Update(self, new_value):
def Update(self, value=None, disable=None):
if value is not None:
try:
self.TKText.delete('1.0', tk.END)
self.TKText.insert(1.0, new_value)
self.TKText.insert(1.0, value)
except: pass
self.DefaultText = new_value
self.DefaultText = value
if disable == True:
self.TKText.configure(state='disabled')
elif disable == False:
self.TKText.configure(state='normal')
def Get(self):
return self.TKText.get(1.0, tk.END)
@ -641,11 +674,11 @@ class Text(Element):
super().__init__(ELEM_TYPE_TEXT, scale, size, auto_size_text, background_color=bg, font=font if font else DEFAULT_FONT, text_color=self.TextColor, pad=pad, key=key)
return
def Update(self, new_value = None, background_color=None, text_color=None, font=None):
if new_value is not None:
self.DisplayText=new_value
def Update(self, value = None, background_color=None, text_color=None, font=None):
if value is not None:
self.DisplayText=value
stringvar = self.TKStringVar
stringvar.set(new_value)
stringvar.set(value)
if background_color is not None:
self.TKText.configure(background=background_color)
if text_color is not None:
@ -690,14 +723,15 @@ class TKProgressBar():
s.configure(str(length)+str(width)+"my.Vertical.TProgressbar", troughrelief=relief, borderwidth=border_width, thickness=width)
self.TKProgressBarForReal = ttk.Progressbar(root, maximum=self.Max, style=str(length)+str(width)+'my.Vertical.TProgressbar', length=length, orient=tk.VERTICAL, mode='determinate')
def Update(self, count, max=None):
def Update(self, count=None, max=None):
if max is not None:
self.Max = max
try:
self.TKProgressBarForReal.config(maximum=max)
except:
return False
if count > self.Max: return False
if count is not None and count > self.Max: return False
if count is not None:
try:
self.TKProgressBarForReal['value'] = count
except: return False
@ -922,16 +956,23 @@ class Button(Element):
return
def Update(self, value=None, new_text=None, button_color=(None, None)):
def Update(self, value=None, text=None, button_color=(None, None), disable=None):
try:
if new_text is not None:
self.TKButton.configure(text=new_text)
self.ButtonText = new_text
if text is not None:
self.TKButton.configure(text=text)
self.ButtonText = text
if button_color != (None, None):
self.TKButton.config(foreground=button_color[0], background=button_color[1])
except:
return
if value is not None:
self.DefaultValue = value
if disable == True:
self.TKButton['state'] = 'disabled'
elif disable == False:
self.TKButton['state'] = 'normal'
def __del__(self):
try:
@ -1089,13 +1130,18 @@ class Slider(Element):
super().__init__(ELEM_TYPE_INPUT_SLIDER, scale=scale, size=size, font=font, background_color=background_color, text_color=text_color, key=key, pad=pad)
return
def Update(self, value, range=(None, None)):
def Update(self, value=None, range=(None, None), disable=None):
if value is not None:
try:
self.TKIntVar.set(value)
if range != (None, None):
self.TKScale.config(from_ = range[0], to_ = range[1])
except: pass
self.DefaultValue = value
if disable == True:
self.TKScale['state'] = 'disabled'
elif disable == False:
self.TKScale['state'] = 'normal'
def SliderChangedHandler(self, event):
# first, get the results table built
@ -2737,8 +2783,7 @@ def StartupTK(my_flex_form):
my_flex_form.TKroot = root
# Make moveable window
if ((my_flex_form.NoTitleBar or my_flex_form.GrabAnywhere in (None, True)) and not my_flex_form.NonBlocking) or \
(my_flex_form.GrabAnywhere == True and my_flex_form.NonBlocking):
if (my_flex_form.GrabAnywhere is not False and not (my_flex_form.NonBlocking and my_flex_form.GrabAnywhere is not True)):
root.bind("<ButtonPress-1>", my_flex_form.StartMove)
root.bind("<ButtonRelease-1>", my_flex_form.StopMove)
root.bind("<B1-Motion>", my_flex_form.OnMotion)
@ -3556,7 +3601,7 @@ def ObjToString(obj, extra=' '):
# Exits via an OK button2 press #
# Returns nothing #
# ===================================================#
def Popup(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None, font=None, no_titlebar=False):
def Popup(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None, font=None, no_titlebar=False, keep_on_top=False):
'''
Show message box. Displays one line per user supplied argument. Takes any Type of variable to display.
:param args:
@ -3578,7 +3623,7 @@ def Popup(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, au
else:
local_line_width = MESSAGE_BOX_LINE_WIDTH
title = args_to_print[0] if args_to_print[0] is not None else 'None'
with FlexForm(title, auto_size_text=True, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font, no_titlebar=no_titlebar) as form:
with FlexForm(title, auto_size_text=True, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font, no_titlebar=no_titlebar, keep_on_top=keep_on_top) as form:
max_line_total, total_lines = 0,0
for message in args_to_print:
# fancy code to check if string and convert if not is not need. Just always convert to string :-)