Merge pull request #53 from MikeTheWatchGuy/Dev-latest

Dev latest
This commit is contained in:
MikeTheWatchGuy 2018-08-26 15:31:22 -04:00 committed by GitHub
commit a8b363e8d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 47 deletions

22
Demo_Canvas.py Normal file
View File

@ -0,0 +1,22 @@
import PySimpleGUI as gui
canvas = gui.Canvas(size=(100,100), background_color='red')
layout = [
[canvas],
[gui.T('Change circle color to:'), gui.ReadFormButton('Red'), gui.ReadFormButton('Blue')]
]
form = gui.FlexForm('Canvas test')
form.Layout(layout)
form.ReadNonBlocking()
cir = canvas.TKCanvas.create_oval(50, 50, 100, 100)
while True:
button, values = form.Read()
if button is None: break
if button is 'Blue':
canvas.TKCanvas.itemconfig(cir, fill = "Blue")
elif button is 'Red':
canvas.TKCanvas.itemconfig(cir, fill = "Red")

View File

@ -2,22 +2,32 @@ 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
# ReadFormButton
# Dictionary return values
# 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('Choose Test'), g.DropDown(values=['Input', 'Output', 'Some option']), g.ReadFormButton('Input Option', size=(10,1))],
layout = [[g.Text('Choose Test'), g.DropDown(values=['Input', 'Output', 'Some option']), g.ReadFormButton('Input Option', auto_size_button=True)],
[in_elem],
[g.ReadFormButton('1', size=(5,2)), g.ReadFormButton('2', size=(5,2)), g.ReadFormButton('3', size=(5,2))],
[g.ReadFormButton('4', size=(5,2)), g.ReadFormButton('5', size=(5,2)), g.ReadFormButton('6', size=(5,2))],
[g.ReadFormButton('7', size=(5,2)), g.ReadFormButton('8', size=(5,2)), g.ReadFormButton('9', size=(5,2))],
[g.ReadFormButton('Submit', size=(5,2)),g.ReadFormButton('0', size=(5,2)), g.ReadFormButton('Clear', size=(5,2))],
[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],
]
form = g.FlexForm('Keypad', auto_size_buttons=False)
form = g.FlexForm('Keypad', default_element_size=(5,2), auto_size_buttons=False)
form.Layout(layout)
# Loop forever reading the form's values, updating the Input field
keys_entered = ''
while True:
button, values = form.Read() # read the form
@ -26,10 +36,10 @@ while True:
if button == '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 = values['input'] # get what's been entered so far
keys_entered += button # add the new digit
elif button == 'Submit':
keys_entered = in_elem.Get()
keys_entered = values['input']
out_elem.Update(keys_entered) # output the final string
in_elem.Update(keys_entered) # change the form to reflect current key string

View File

@ -4,54 +4,62 @@ 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='A:/TEMP/PDFs')
rc, folder = sg.GetPathBox('Image Browser', 'Image folder to open', default_path='')
if rc is False or folder is '':
sg.MsgBoxCancel('Cancelling')
exit(0)
# get list of PNG files in folder
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')
exit(0)
# create the form that also returns keyboard events
form = sg.FlexForm('Image Browser', return_keyboard_events=True)
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=(10,1))
file_num_display_elem = sg.Text('File 1 of {}'.format(len(png_files)), size=(15,1))
# define layout, show and read the form
layout = [[filename_display_elem],
col = [[filename_display_elem],
[image_elem],
[sg.ReadFormButton('Next', size=(8,2)), sg.ReadFormButton('Prev', size=(8,2)), file_num_display_elem]]
form.LayoutAndRead(layout) # Shows form on screen
col_files = [[sg.Listbox(values=filenames_only, size=(60,30), key='listbox')],
[sg.ReadFormButton('Read')]]
layout = [[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:
f = png_files[i]
# update window with new image
image_elem.Update(filename=f)
# update window with filename
filename_display_elem.Update(f)
# update page display
file_num_display_elem.Update('File {} of {}'.format(i+1, len(png_files)))
# read the form
button, values = form.Read()
# perform button and keyboard operations
if button is None:
break
elif button in ('Next', 'MouseWheel:Down', 'Down:40', 'Next:34') and i < len(png_files):
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
if button == 'Read':
filename = folder + '\\' + values['listbox'][0]
# print(filename)
else:
filename = png_files[i]
# update window with new image
image_elem.Update(filename=filename)
# update window with filename
filename_display_elem.Update(filename)
# update page display
file_num_display_elem.Update('File {} of {}'.format(i+1, len(png_files)))
# read the form
button, values = form.Read()

View File

@ -139,6 +139,7 @@ ELEM_TYPE_INPUT_CHECKBOX = 8
ELEM_TYPE_INPUT_SPIN = 9
ELEM_TYPE_BUTTON = 3
ELEM_TYPE_IMAGE = 30
ELEM_TYPE_CANVAS = 40
ELEM_TYPE_INPUT_SLIDER = 10
ELEM_TYPE_INPUT_LISTBOX = 11
ELEM_TYPE_OUTPUT = 300
@ -542,12 +543,13 @@ class TKProgressBar():
# Scroll bar will span the length of the frame #
# ---------------------------------------------------------------------- #
class TKOutput(tk.Frame):
def __init__(self, parent, width, height, bd, background_color=None, text_color=None):
frame = tk.Frame(parent, width=width, height=height)
def __init__(self, parent, width, height, bd, background_color=None, text_color=None, font=None):
frame = tk.Frame(parent)
tk.Frame.__init__(self, frame)
self.output = tk.Text(frame, width=width, height=height, bd=bd)
self.output = tk.Text(frame, width=width, height=height, bd=bd, font=font)
if background_color and background_color != COLOR_SYSTEM_DEFAULT:
self.output.configure(background=background_color)
frame.configure(background=background_color)
if text_color and text_color != COLOR_SYSTEM_DEFAULT:
self.output.configure(fg=text_color)
self.vsb = tk.Scrollbar(frame, orient="vertical", command=self.output.yview)
@ -586,7 +588,7 @@ class TKOutput(tk.Frame):
# Routes stdout, stderr to a scrolled window #
# ---------------------------------------------------------------------- #
class Output(Element):
def __init__(self, scale=(None, None), size=(None, None), background_color=None, text_color=None, pad=None):
def __init__(self, scale=(None, None), size=(None, None), background_color=None, text_color=None, pad=None, font=None):
'''
Output Element - reroutes stdout, stderr to this window
:param scale: Adds multiplier to size (w,h)
@ -597,7 +599,7 @@ class Output(Element):
bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
super().__init__(ELEM_TYPE_OUTPUT, scale=scale, size=size, background_color=bg, text_color=fg, pad=pad)
super().__init__(ELEM_TYPE_OUTPUT, scale=scale, size=size, background_color=bg, text_color=fg, pad=pad, font=font)
def __del__(self):
try:
@ -807,6 +809,28 @@ class Image(Element):
def __del__(self):
super().__del__()
# ---------------------------------------------------------------------- #
# Canvas #
# ---------------------------------------------------------------------- #
class Canvas(Element):
def __init__(self, background_color=None, scale=(None, None), size=(None, None), pad=None):
'''
Image Element
:param filename:
:param scale: Adds multiplier to size (w,h)
:param size: Size of field in characters
'''
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.TKCanvas = None
super().__init__(ELEM_TYPE_CANVAS, background_color=background_color, scale=scale, size=size, pad=pad)
return
def __del__(self):
super().__del__()
# ---------------------------------------------------------------------- #
# Slider #
# ---------------------------------------------------------------------- #
@ -1168,11 +1192,14 @@ class UberForm():
# ====================================================================== #
# ------------------------- INPUT TEXT Element lazy functions ------------------------- #
def In(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, do_not_clear=False, key=None, focus=False):
return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, password_char=password_char, background_color=background_color, text_color=text_color, do_not_clear=do_not_clear, focus=focus, key=key)
In = InputText
Input = InputText
#### TODO REMOVE THESE COMMENTS - was the old way, but want to keep around for a bit just in case
# def In(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, do_not_clear=False, key=None, focus=False):
# return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, password_char=password_char, background_color=background_color, text_color=text_color, do_not_clear=do_not_clear, focus=focus, key=key)
def Input(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, do_not_clear=False, key=None, focus=False):
return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, password_char=password_char, background_color=background_color, text_color=text_color, do_not_clear=do_not_clear, focus=focus, key=key)
# def Input(default_text ='', scale=(None, None), size=(None, None), auto_size_text=None, password_char='', background_color=None, text_color=None, do_not_clear=False, key=None, focus=False):
# return InputText(default_text=default_text, scale=scale, size=size, auto_size_text=auto_size_text, password_char=password_char, background_color=background_color, text_color=text_color, do_not_clear=do_not_clear, focus=focus, key=key)
# ------------------------- CHECKBOX Element lazy functions ------------------------- #
CB = Checkbox
@ -1180,20 +1207,29 @@ CBox = Checkbox
Check = Checkbox
# ------------------------- INPUT COMBO Element lazy functions ------------------------- #
def Combo(values, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None):
return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text, background_color=background_color)
def DropDown(values, scale=(None, None), size=(None, None), auto_size_text=None):
return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text)
Combo = InputCombo
DropDown = InputCombo
Drop = InputCombo
def Drop(values, scale=(None, None), size=(None, None), auto_size_text=None):
return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text)
# def Combo(values, scale=(None, None), size=(None, None), auto_size_text=None, background_color=None):
# return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text, background_color=background_color)
#
# def DropDown(values, scale=(None, None), size=(None, None), auto_size_text=None):
# return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text)
#
# def Drop(values, scale=(None, None), size=(None, None), auto_size_text=None):
# return InputCombo(values=values, scale=scale, size=size, auto_size_text=auto_size_text)
# ------------------------- TEXT Element lazy functions ------------------------- #
def Txt(display_text, scale=(None, None), size=(None, None), auto_size_text=None, font=None, text_color=None, justification=None):
return Text(display_text, scale=scale, size=size, auto_size_text=auto_size_text, font=font, text_color=text_color, justification=justification)
def T(display_text, scale=(None, None), size=(None, None), auto_size_text=None, font=None, text_color=None, justification=None):
return Text(display_text, scale=scale, size=size, auto_size_text=auto_size_text, font=font, text_color=text_color, justification=justification)
Txt = Text
T = Text
# def Txt(display_text, scale=(None, None), size=(None, None), auto_size_text=None, font=None, text_color=None, justification=None):
# return Text(display_text, scale=scale, size=size, auto_size_text=auto_size_text, font=font, text_color=text_color, justification=justification)
#
# def T(display_text, scale=(None, None), size=(None, None), auto_size_text=None, font=None, text_color=None, justification=None):
# return Text(display_text, scale=scale, size=size, auto_size_text=auto_size_text, font=font, text_color=text_color, justification=justification)
# ------------------------- FOLDER BROWSE Element lazy function ------------------------- #
def FolderBrowse(target=(ThisRow, -1), button_text='Browse', scale=(None, None), size=(None, None), auto_size_button=None, button_color=None, font=None, pad=None):
@ -1469,7 +1505,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
stringvar = tk.StringVar()
element.TKStringVar = stringvar
stringvar.set(display_text)
if element.AutoSizeText:
if auto_size_text:
width = 0
if element.Justification is not None:
justification = element.Justification
@ -1500,7 +1536,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
if element.AutoSizeButton is not None:
auto_size = element.AutoSizeButton
else: auto_size = toplevel_form.AutoSizeButtons
if auto_size is False: width=element_size[0]
if auto_size is False or element.Size[0] is not None: width=element_size[0]
else: width = 0
height=element_size[1]
lines = btext.split('\n')
@ -1702,8 +1738,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
# ------------------------- OUTPUT element ------------------------- #
elif element_type == ELEM_TYPE_OUTPUT:
width, height = element_size
element.TKOut = TKOutput(tk_row_frame, width=width, height=height, bd=border_depth, background_color=element.BackgroundColor, text_color=text_color)
element.TKOut.pack(side=tk.LEFT,padx=element.Pad[0], pady=element.Pad[1])
element.TKOut = TKOutput(tk_row_frame, width=width, height=height, bd=border_depth, background_color=element.BackgroundColor, text_color=text_color, font=font)
element.TKOut.pack(side=tk.LEFT)
# ------------------------- IMAGE Box element ------------------------- #
elif element_type == ELEM_TYPE_IMAGE:
if element.Filename is not None:
@ -1723,6 +1759,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
element.tktext_label.image = photo
# tktext_label.configure(anchor=tk.NW, image=photo)
element.tktext_label.pack(side=tk.LEFT, padx=element.Pad[0],pady=element.Pad[1])
# ------------------------- Canvas element ------------------------- #
elif element_type == ELEM_TYPE_CANVAS:
width, height = element_size
element.TKCanvas = tk.Canvas(tk_row_frame, width=width, height=height, bd=border_depth)
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
element.TKCanvas.configure(background=element.BackgroundColor)
element.TKCanvas.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
# ------------------------- SLIDER Box element ------------------------- #
elif element_type == ELEM_TYPE_INPUT_SLIDER:
slider_length = element_size[0] * CharWidthInPixels()
@ -1954,7 +1997,7 @@ def MsgBox(*args, button_color=None, button_type=MSG_BOX_OK, auto_close=False, a
# height = _GetNumLinesNeeded(message, width_used)
height = message_wrapped_lines
# print('Msgbox width, height', width_used, height)
form.AddRow(Text(message_wrapped, auto_size_text=True, size=(width_used, height)))
form.AddRow(Text(message_wrapped, auto_size_text=True))
total_lines += height
pad = max_line_total-15 if max_line_total > 15 else 1