Release 3.9.1 & 1.1.2

This commit is contained in:
MikeTheWatchGuy 2018-10-08 13:30:33 -04:00
parent 8f7356f425
commit 91da5ed7b2
23 changed files with 487 additions and 150 deletions

View File

@ -20,7 +20,7 @@ column1 = [[sg.Text('Column 1', background_color='#F7F3EC', justification='cente
layout = [
[sg.Menu(menu_def, tearoff=True)],
[sg.Text('All graphic widgets in one form!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE)],
[sg.Text('All graphic widgets in one Window!', size=(30, 1), justification='center', font=("Helvetica", 25), relief=sg.RELIEF_RIDGE, text_color='midnightblue')],
[sg.Text('Here is some text.... and a place to enter text')],
[sg.InputText('This is my text')],
[sg.Frame(layout=[

View File

@ -16,16 +16,16 @@ sg.SetOptions(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.ReadButton('Start', button_color=('white', 'black'), key='Start'),
sg.ReadButton('Stop', button_color=('white', 'black'), key='Stop'),
sg.ReadButton('Reset', button_color=('white', 'firebrick3'), key='Reset'),
sg.ReadButton('Submit', button_color=('white', 'springgreen4'), key='Submit')]]
[sg.ReadButton('Start', button_color=('white', 'black'), key='_Start_'),
sg.ReadButton('Stop', button_color=('white', 'black'), key='_Stop_'),
sg.ReadButton('Reset', button_color=('white', 'firebrick3'), key='_Reset_'),
sg.ReadButton('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()
for key, state in {'Start': False, 'Stop': True, 'Reset': True, 'Submit': True}.items():
for key, state in {'_Start_': False, '_Stop_': True, '_Reset_': True, '_Submit_': True}.items():
window.FindElement(key).Update(disabled=state)
recording = have_data = False
@ -34,18 +34,18 @@ while True:
print(button)
if button is None:
sys.exit(69)
if button is 'Start':
for key, state in {'Start':True, 'Stop':False, 'Reset':False, 'Submit':True}.items():
if button == '_Start_':
for key, state in {'_Start_':True, '_Stop_':False, '_Reset_':False, '_Submit_':True}.items():
window.FindElement(key).Update(disabled=state)
recording = True
elif button is 'Stop' and recording:
[window.FindElement(key).Update(disabled=value) for key,value in {'Start':False, 'Stop':True, 'Reset':False, 'Submit':False}.items()]
elif button == '_Stop_' and recording:
[window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':False, '_Submit_':False}.items()]
recording = False
have_data = True
elif button is 'Reset':
[window.FindElement(key).Update(disabled=value) for key,value in {'Start':False, 'Stop':True, 'Reset':True, 'Submit':True}.items()]
elif button == '_Reset_':
[window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':True, '_Submit_':True}.items()]
recording = False
have_data = False
elif button is 'Submit' and have_data:
[window.FindElement(key).Update(disabled=value) for key,value in {'Start':False, 'Stop':True, 'Reset':True, 'Submit':False}.items()]
elif button is '_Submit_' and have_data:
[window.FindElement(key).Update(disabled=value) for key,value in {'_Start_':False, '_Stop_':True, '_Reset_':True, '_Submit_':False}.items()]
recording = False

View File

@ -11,6 +11,7 @@ else:
Shows a big chart of colors... give it a few seconds to create it
Once large window is shown, you can click on any color and another window will popup
showing both white and black text on that color
Uses TOOLTIPS to show the hex values for the colors. Hover over a color and a tooltip will show you the RGB
You will find the list of tkinter colors here:
http://www.tcl.tk/man/tcl8.5/TkCmd/colors.htm
@ -670,7 +671,7 @@ color_map = {
}
sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=1)
sg.SetOptions(button_element_size=(12,1), element_padding=(0,0), auto_size_buttons=False, border_width=1, tooltip_time=100)
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))),]]
row = []
@ -689,5 +690,5 @@ while True:
if b is None:
break
# -- Create a secondary window that shows white and black text on chosen color
layout2 =[[sg.Button(b, button_color=('white', b), tooltip=color_map[b]), sg.Button(b, button_color=('black', b), tooltip=color_map[b])] ]
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read()
layout2 =[[sg.DummyButton(b, button_color=('white', b), tooltip=color_map[b]), sg.DummyButton(b, button_color=('black', b), tooltip=color_map[b])] ]
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).ReadNonBlocking()

View File

@ -109,5 +109,5 @@ while True:
if b is None:
break
# -- Create a secondary window that shows white and black text on chosen color
layout2 =[[sg.Button(b, button_color=('white', b)), sg.Button(b, button_color=('black', b))] ]
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).Read()
layout2 =[[sg.DummyButton(b, button_color=('white', b)), sg.DummyButton(b, button_color=('black', b))] ]
sg.Window('Buttons with white and black text', keep_on_top=True).Layout(layout2).ReadNonBlocking()

View File

@ -277,7 +277,7 @@ def CallbackSimulation():
break
# All done!
sg.PopupOk('Done')
sg.PopupOK('Done')
def RealtimeButtons():
"""

View File

@ -45,12 +45,16 @@ def main():
# ---------------- Create Form ----------------
sg.ChangeLookAndFeel('Black')
layout = [[sg.Text('', size=(8,1), font=('Helvetica', 20),text_color=sg.YELLOWS[0], justification='center', key='text')],
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)), sg.Spin([x+1 for x in range(10)], 1, key='spin')],]
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15,0), 0), size=(9,1)),
sg.Spin([x+1 for x in range(10)], 1, key='spin')],]
window = sg.Window('CPU Utilization', no_titlebar=True, auto_size_buttons=False,
keep_on_top=True, grab_anywhere=True).Layout(layout)
window = sg.Window('CPU Utilization',
no_titlebar=True,
keep_on_top=True,
grab_anywhere=True).Layout(layout)
# start cpu measurement thread
thread = Thread(target=CPU_thread,args=(None,))

View File

@ -10,12 +10,17 @@ import psutil
# ---------------- Create Form ----------------
sg.ChangeLookAndFeel('Black')
layout = [[sg.Text('')],
[sg.Text('', size=(8, 2), font=('Helvetica', 20), justification='center', key='text')],
[sg.Exit(button_color=('white', 'firebrick4'), pad=((15, 0), 0)),
sg.Spin([x + 1 for x in range(10)], 1, key='spin')]]
# Layout the rows of the form and perform a read. Indicate the form is non-blocking!
window = sg.Window('CPU Meter', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout)
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)], 1, key='_spin_')]]
# Layout the rows of the Window
window = sg.Window('CPU Meter',
no_titlebar=True,
keep_on_top=True,
grab_anywhere=True).Layout(layout)
# ---------------- main loop ----------------
while (True):
@ -26,7 +31,7 @@ while (True):
if values is None or button == 'Exit':
break
try:
interval = int(values['spin'])
interval = int(values['_spin_'])
except:
interval = 1
@ -34,7 +39,7 @@ while (True):
# --------- Display timer in window --------
window.FindElement('text').Update(f'CPU {cpu_percent:02.0f}%')
window.FindElement('_text_').Update(f'CPU {cpu_percent:02.0f}%')
# Broke out of main loop. Close the window.
window.CloseNonBlocking()

View File

@ -23,7 +23,7 @@ layout = [[sg.Text('')],
sg.ReadButton('Reset', button_color=('white', '#007339'), key='Reset'),
sg.Exit(button_color=('white', 'firebrick4'), key='Exit')]]
window = sg.Window('Running Timer', no_titlebar=False, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout)
window = sg.Window('Running Timer', no_titlebar=True, auto_size_buttons=False, keep_on_top=True, grab_anywhere=True).Layout(layout)
# ---------------- main loop ----------------
current_time = 0

View File

@ -22,9 +22,9 @@ Dependecies
Python v3
PIL
"""
# Get the folder containing the images from the user
rc, folder = sg.GetPathBox('Image Browser', 'Image folder to open', default_path='')
if not rc or not folder:
# Get the folder containin:g the images from the user
folder = sg.PopupGetFolder('Image folder to open', default_path='')
if not folder:
sg.PopupCancel('Cancelling')
raise SystemExit()
@ -89,7 +89,7 @@ i=0
while True:
# read the form
button, values = window.Read()
print(button, values)
# perform button and keyboard operations
if button is None:
break
@ -103,7 +103,7 @@ while True:
if i < 0:
i = num_files + i
filename = os.path.join(folder, fnames[i])
elif button in ('Read', ''): # something from the listbox
elif button == 'listbox': # something from the listbox
f = values["listbox"][0] # selected filename
filename = os.path.join(folder, f) # read this file
i = fnames.index(f) # update running index

View File

@ -35,7 +35,7 @@ while True:
if button == 'Clear': # clear keys if clear button
keys_entered = ''
elif button in '1234567890':
keys_entere=d = 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 = values['input']

View File

@ -16,29 +16,33 @@ import random
"""
def LEDIndicator(key):
return sg.Graph(canvas_size=(30, 30), graph_bottom_left=(-20, -20), graph_top_right=(20, 20),
def LEDIndicator(key=None, radius=30):
return sg.Graph(canvas_size=(radius, radius),
graph_bottom_left=(-radius, -radius),
graph_top_right=(radius, radius),
pad=(0, 0), key=key)
def SetLED(window, key, color):
graph = window.FindElement(key)
graph.Erase()
graph.DrawCircle((0, 0), 10, fill_color=color, line_color=color)
graph.DrawCircle((0, 0), 12, fill_color=color, line_color=color)
layout = [[sg.Text('My Status Report')],
layout = [[sg.Text('My LED Status Indicators', size=(20,1))],
[sg.Text('CPU Use'), LEDIndicator('_cpu_')],
[sg.Text('RAM'), LEDIndicator('_ram_')],
[sg.Text('Temperature'), LEDIndicator('_temp_')],
[sg.Text('Server 1'), LEDIndicator('_server1_')],
[sg.Exit()]]
[sg.RButton('Exit')]]
window = sg.Window('My new window', default_element_size=(12, 1), auto_size_text=False).Layout(layout).Finalize()
i = 0
while True: # Event Loop
button, value = window.ReadNonBlocking()
if button == 'Exit':
window.CloseNonBlocking()
break
if value is None:
break
i += 1

View File

@ -76,7 +76,7 @@ class PlayerGUI():
image_filename=image_exit, image_size=(50,50), image_subsample=2, border_width=0, )]
]
window = sg.FlexForm('MIDI File Player', default_element_size=(30, 1), font=("Helvetica", 25)).Layout(layout).Finalize()
window = sg.Window('MIDI File Player', default_element_size=(30, 1), font=("Helvetica", 25)).Layout(layout).Finalize()
self.Window = window
@ -87,7 +87,7 @@ class PlayerGUI():
# ------------------------------------------------------------------------- #
def PlayerPlaybackGUIUpdate(self, DisplayString):
window = self.Window
if 'window' not in locals() or window is None: # if the form has been destoyed don't mess with it
if 'window' not in locals() or window is None: # if the widnow has been destoyed don't mess with it
return PLAYER_COMMAND_EXIT
self.TextElem.Update(DisplayString)
button, (values) = window.ReadNonBlocking()

View File

@ -23,22 +23,6 @@ Basic steps are:
"""
def draw_figure(canvas, figure, loc=(0, 0)):
""" Draw a matplotlib figure onto a Tk canvas
loc: location of top-left corner of figure on canvas in pixels.
Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
"""
figure_canvas_agg = FigureCanvasAgg(figure)
figure_canvas_agg.draw()
figure_x, figure_y, figure_w, figure_h = figure.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(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
return photo
#------------------------------- PASTE YOUR MATPLOTLIB CODE HERE -------------------------------
import numpy as np
@ -95,7 +79,28 @@ figure_x, figure_y, figure_w, figure_h = fig.bbox.bounds
#------------------------------- END OF YOUR MATPLOTLIB CODE -------------------------------
# define the form layout
#------------------------------- Beginning of Matplotlib helper code -----------------------
def draw_figure(canvas, figure, loc=(0, 0)):
""" Draw a matplotlib figure onto a Tk canvas
loc: location of top-left corner of figure on canvas in pixels.
Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
"""
figure_canvas_agg = FigureCanvasAgg(figure)
figure_canvas_agg.draw()
figure_x, figure_y, figure_w, figure_h = figure.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(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
return photo
#------------------------------- Beginning of GUI CODE -------------------------------
# define the window layout
layout = [[sg.Text('Plot test', font='Any 18')],
[sg.Canvas(size=(figure_w, figure_h), key='canvas')],
[sg.OK(pad=((figure_w / 2, 0), 3), size=(4, 2))]]

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
import sys
if sys.version_info[0] >= 3:
import PySimpleGUI_mod as sg
import PySimpleGUI as sg
else:
import PySimpleGUI27 as sg
"""
@ -20,26 +20,26 @@ def SecondForm():
def TestMenus():
import PySimpleGUI as sg
sg.ChangeLookAndFeel('LightGreen')
sg.SetOptions(element_padding=(0, 0))
# ------ Menu Definition ------ #
menu_def = [['&File', ['&Open', '&Save', '---', 'Properties', 'E&xit' ]],
['&Edit', ['Paste', ['Special', 'Normal',], 'Undo'],],
[''
'&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)],
[sg.Menu(menu_def, tearoff=True)],
[sg.Output(size=(60,20))],
[sg.In('Test', key='input', do_not_clear=True)]
]
window = sg.Window("Windows-like program", default_element_size=(12, 1), auto_size_text=False, auto_size_buttons=False,
default_button_element_size=(12, 1)).Layout(layout)
window = sg.Window("Windows-like program", default_element_size=(12, 1), auto_size_text=False,
auto_size_buttons=False, default_button_element_size=(12, 1)).Layout(layout)
# ------ Loop & Process button menu choices ------ #
while True:
@ -58,6 +58,4 @@ def TestMenus():
elif button == 'Properties':
SecondForm()
TestMenus()

View File

@ -6,7 +6,7 @@ else:
import PySimpleGUI27 as sg
# Here, have some windows on me....
[sg.PopupNoWait(location=(500+100*x,500)) for x in range(10)]
[sg.PopupNoWait('No-wait Popup', location=(500+100*x,500)) for x in range(10)]
answer = sg.PopupYesNo('Do not worry about all those open windows... they will disappear at the end', 'Are you OK with that?')
@ -26,7 +26,6 @@ sg.Popup('Simple popup')
sg.PopupNoTitlebar('No titlebar')
sg.PopupNoBorder('No border')
sg.PopupNoFrame('No frame')
# sg.PopupNoButtons('No Buttons') # don't mix with non-blocking... disaster ahead...
sg.PopupCancel('Cancel')
sg.PopupOKCancel('OK Cancel')
sg.PopupAutoClose('Autoclose')

View File

@ -31,10 +31,9 @@ If you want to change the GUI, make changes to the GUI portion marked below.
import numpy as np
import matplotlib.pyplot as plt
N = 5
values_to_plot = (20, 35, 30, 35, 27)
ind = np.arange(N) # the x locations for the groups
width = 0.4 # the width of the bars: can also be len(x) sequence
ind = np.arange(len(values_to_plot))
width = 0.4
p1 = plt.bar(ind, values_to_plot, width)

View File

@ -53,7 +53,7 @@ def Launcher2():
window.Layout(layout)
# ---===--- Loop taking in user input and using it to query HowDoI --- #
# ---===--- Loop taking in user input --- #
while True:
(button, value) = window.Read()
if button in ('EXIT', None):

11
Demo_YouTube_Intro.py Normal file
View File

@ -0,0 +1,11 @@
import PySimpleGUI as sg
layout = [[sg.Text('What is your name?')],
[sg.InputText()],
[sg.Button('Ok')]]
window = sg.Window('Title of Window').Layout(layout)
button, values = window.Read()
sg.Popup('Hello {}'.format(values[0]))

View File

@ -15,6 +15,7 @@ else:
import tkFont
import ScrolledText
import types
import datetime
import textwrap
@ -218,6 +219,7 @@ ELEM_TYPE_MENUBAR = 600
ELEM_TYPE_PROGRESS_BAR = 200
ELEM_TYPE_BLANK = 100
ELEM_TYPE_TABLE = 700
ELEM_TYPE_TREE = 800
ELEM_TYPE_ERROR = 666
# ------------------------- Popup Buttons Types ------------------------- #
@ -2045,7 +2047,7 @@ class Menu(Element):
# Table #
# ---------------------------------------------------------------------- #
class Table(Element):
def __init__(self, values, headings=None, visible_column_map=None, col_widths=None, def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, display_row_numbers=False, scrollable=None, font=None, justification='right', text_color=None, background_color=None, size=(None, None), pad=None, key=None, tooltip=None):
def __init__(self, values, headings=None, visible_column_map=None, col_widths=None, def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, display_row_numbers=False, font=None, justification='right', text_color=None, background_color=None, size=(None, None), pad=None, key=None, tooltip=None):
self.Values = values
self.ColumnHeadings = headings
self.ColumnsToDisplay = visible_column_map
@ -2056,7 +2058,6 @@ class Table(Element):
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.TextColor = text_color
self.Justification = justification
self.Scrollable = scrollable
self.InitialState = None
self.SelectMode = select_mode
self.DisplayRowNumbers = display_row_numbers
@ -2070,6 +2071,37 @@ class Table(Element):
super().__del__()
# ---------------------------------------------------------------------- #
# Tree #
# ---------------------------------------------------------------------- #
class Tree(Element):
def __init__(self, headings=None, visible_column_map=None, col_widths=None, def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, font=None, justification='right', text_color=None, background_color=None, num_rows=None, pad=None, key=None, tooltip=None):
self.ColumnHeadings = headings
self.ColumnsToDisplay = visible_column_map
self.ColumnWidths = col_widths
self.MaxColumnWidth = max_col_width
self.DefaultColumnWidth = def_col_width
self.AutoSizeColumns = auto_size_columns
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.TextColor = text_color
self.Justification = justification
self.InitialState = None
self.SelectMode = select_mode
self.NumRows = num_rows
self.TKTreeview = None
super().__init__(ELEM_TYPE_TREE, text_color=text_color, background_color=background_color, font=font, pad=pad, key=key, tooltip=tooltip)
return
def __del__(self):
super().__del__()
# ---------------------------------------------------------------------- #
# Error Element #
# ---------------------------------------------------------------------- #
@ -2914,9 +2946,11 @@ else:
AddMenuItem(top_menu, item, element)
i += 1
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
# ===================================== TK CODE STARTS HERE ====================================================== #
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
def PackFormIntoFrame(form, containing_frame, toplevel_form):
def CharWidthInPixels():
@ -3560,6 +3594,48 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
element.TKTreeview.pack(side=tk.LEFT,expand=True, padx=0, pady=0, fill='both')
if element.Tooltip is not None:
element.TooltipObject = ToolTip(element.TKTreeview, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
# ------------------------- Tree element ------------------------- #
elif element_type == ELEM_TYPE_TREE:
width, height = element_size
if element.Justification == 'left': # justification
anchor = tk.W
elif element.Justification == 'right':
anchor = tk.E
else:
anchor = tk.CENTER
if element.ColumnsToDisplay is None: # Which cols to display
displaycolumns = element.ColumnHeadings
else:
displaycolumns = []
for i, should_display in enumerate(element.ColumnsToDisplay):
if should_display:
displaycolumns.append(element.ColumnHeadings[i])
column_headings= element.ColumnHeadings
# ------------- GET THE TREEVIEW WIDGET -------------
element.TKTreeview = ttk.Treeview(tk_row_frame, columns=column_headings,
displaycolumns=displaycolumns, show='headings', height=height, selectmode=element.SelectMode)
treeview = element.TKTreeview
for i, heading in enumerate(element.ColumnHeadings): # Configure cols + headings
treeview.heading(heading, text=heading)
if element.AutoSizeColumns:
width = min(element.MaxColumnWidth, len(heading))
else:
try:
width = element.ColumnWidths[i]
except:
width = element.DefaultColumnWidth
treeview.column(heading, width=width*CharWidthInPixels(), anchor=anchor)
# ----- configure colors -----
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
ttk.Style().configure("Treeview", background=element.BackgroundColor, fieldbackground=element.BackgroundColor)
if element.TextColor is not None and element.TextColor != COLOR_SYSTEM_DEFAULT:
ttk.Style().configure("Treeview", foreground=element.TextColor)
element.TKTreeview.pack(side=tk.LEFT,expand=True, padx=0, pady=0, fill='both')
if element.Tooltip is not None: # tooltip
element.TooltipObject = ToolTip(element.TKTreeview, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
#............................DONE WITH ROW pack the row of widgets ..........................#
# done with row, pack the row of widgets
# tk_row_frame.grid(row=row_num+2, sticky=tk.NW, padx=DEFAULT_MARGINS[0])
@ -4385,7 +4461,6 @@ def SetOptions(icon=None, button_color=None, element_size=(None,None), button_el
# of the elements. #
##############################################################
LOOK_AND_FEEL_TABLE = {'SystemDefault': {'BACKGROUND' : COLOR_SYSTEM_DEFAULT, 'TEXT': COLOR_SYSTEM_DEFAULT, 'INPUT': COLOR_SYSTEM_DEFAULT,'TEXT_INPUT' : COLOR_SYSTEM_DEFAULT, 'SCROLL': COLOR_SYSTEM_DEFAULT, 'BUTTON': OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, 'PROGRESS': COLOR_SYSTEM_DEFAULT, 'BORDER': 1,'SLIDER_DEPTH':1, 'PROGRESS_DEPTH':0},
# ∩(^-^)∩
'Topanga': {'BACKGROUND': '#282923', 'TEXT': '#E7DB74', 'INPUT': '#393a32',
'TEXT_INPUT': '#E7C855','SCROLL': '#E7C855', 'BUTTON': ('#E7C855', '#284B5A'),
'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1,'SLIDER_DEPTH':0, 'PROGRESS_DEPTH':0},

View File

@ -27,6 +27,7 @@ else:
import tkinter.font
import tkinter.scrolledtext
import types
import datetime
import textwrap
@ -149,6 +150,14 @@ TITLE_LOCATION_TOP_RIGHT = tk.NE
TITLE_LOCATION_BOTTOM_LEFT = tk.SW
TITLE_LOCATION_BOTTOM_RIGHT = tk.SE
THEME_DEFAULT = 'default'
THEME_WINNATIVE = 'winnative'
THEME_CLAM = 'clam'
THEME_ALT = 'alt'
THEME_CLASSIC = 'classic'
THEME_VISTA = 'vista'
THEME_XPNATIVE = 'xpnative'
# DEFAULT_METER_ORIENTATION = 'Vertical'
# ----====----====----==== Constants the user should NOT f-with ====----====----====----#
@ -222,6 +231,7 @@ ELEM_TYPE_MENUBAR = 600
ELEM_TYPE_PROGRESS_BAR = 200
ELEM_TYPE_BLANK = 100
ELEM_TYPE_TABLE = 700
ELEM_TYPE_TREE = 800
ELEM_TYPE_ERROR = 666
# ------------------------- Popup Buttons Types ------------------------- #
@ -623,7 +633,6 @@ class Listbox(Element):
self.Values = values
def SetValue(self, values):
for index, item in enumerate(self.Values):
try:
@ -634,6 +643,9 @@ class Listbox(Element):
except: pass
self.DefaultValues = values
def GetListValues(self):
return self.Values
def __del__(self):
try:
self.TKListBox.__del__()
@ -897,7 +909,7 @@ T = Text
# ---------------------------------------------------------------------- #
class TKProgressBar(object):
def __init__(self, root, max, length=400, width=DEFAULT_PROGRESS_BAR_SIZE[1], style=DEFAULT_PROGRESS_BAR_STYLE, relief=DEFAULT_PROGRESS_BAR_RELIEF, border_width=DEFAULT_PROGRESS_BAR_BORDER_WIDTH, orientation='horizontal', BarColor=(None,None)):
def __init__(self, root, max, length=400, width=DEFAULT_PROGRESS_BAR_SIZE[1], style=DEFAULT_PROGRESS_BAR_STYLE, relief=DEFAULT_PROGRESS_BAR_RELIEF, border_width=DEFAULT_PROGRESS_BAR_BORDER_WIDTH, orientation='horizontal', BarColor=(None,None), key=None):
self.Length = length
self.Width = width
self.Max = max
@ -909,11 +921,11 @@ class TKProgressBar(object):
s = tkinter.ttk.Style()
s.theme_use(style)
if BarColor != COLOR_SYSTEM_DEFAULT:
s.configure(str(length)+str(width)+"my.Horizontal.TProgressbar", background=BarColor[0], troughcolor=BarColor[1], troughrelief=relief, borderwidth=border_width, thickness=width)
s.configure(str(key)+"my.Horizontal.TProgressbar", background=BarColor[0], troughcolor=BarColor[1], troughrelief=relief, borderwidth=border_width, thickness=width)
else:
s.configure(str(length)+str(width)+"my.Horizontal.TProgressbar", troughrelief=relief, borderwidth=border_width, thickness=width)
s.configure(str(key)+"my.Horizontal.TProgressbar", troughrelief=relief, borderwidth=border_width, thickness=width)
self.TKProgressBarForReal = tkinter.ttk.Progressbar(root, maximum=self.Max, style=str(length)+str(width)+'my.Horizontal.TProgressbar', length=length, orient=tk.HORIZONTAL, mode='determinate')
self.TKProgressBarForReal = tkinter.ttk.Progressbar(root, maximum=self.Max, style=str(key)+'my.Horizontal.TProgressbar', length=length, orient=tk.HORIZONTAL, mode='determinate')
else:
s = tkinter.ttk.Style()
s.theme_use(style)
@ -1154,8 +1166,7 @@ class Button(Element):
self.ParentForm.LastButtonClicked = self.ButtonText
self.ParentForm.FormRemainedOpen = True
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # this is a return type button so GET RESULTS and destroy window
# if the form is tabbed, must collect all form's results and destroy all forms
elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # special kind of button that does not exit main loop
self.ParentForm._Close()
if self.ParentForm.NonBlocking:
self.ParentForm.TKroot.destroy()
@ -1494,7 +1505,7 @@ class Frame(Element):
# Tab #
# ---------------------------------------------------------------------- #
class Tab(Element):
def __init__(self, title, layout, title_color=None, background_color=None, font=None, pad=None, border_width=None, key=None, tooltip=None):
def __init__(self, title, layout, title_color=None, background_color=None, font=None, pad=None, disabled=False, border_width=None, key=None, tooltip=None):
self.UseDictionary = False
self.ReturnValues = None
@ -1506,6 +1517,9 @@ class Tab(Element):
self.TKFrame = None
self.Title = title
self.BorderWidth = border_width
self.Disabled = disabled
self.ParentNotebook = None
self.TabID = None
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.Layout(layout)
@ -1531,6 +1545,15 @@ class Tab(Element):
def Layout(self, rows):
for row in rows:
self.AddRow(*row)
return self
def Update(self, disabled = None): # TODO Disable / enable of tabs is not complete
if disabled is None:
return
self.Disabled = disabled
state = 'disabled' if disabled is True else 'normal'
self.ParentNotebook.tab(self.TabID, state=state)
return self
def _GetElementAtLocation(self, location):
(row_num,col_num) = location
@ -1551,7 +1574,7 @@ class Tab(Element):
# TabGroup #
# ---------------------------------------------------------------------- #
class TabGroup(Element):
def __init__(self, layout, tab_location=None, title_color=None, background_color=None, font=None, change_submits=False, pad=None, border_width=None, key=None, tooltip=None):
def __init__(self, layout, tab_location=None, title_color=None, selected_title_color=None, background_color=None, font=None, change_submits=False, pad=None, border_width=None, theme=None, key=None, tooltip=None):
self.UseDictionary = False
self.ReturnValues = None
@ -1559,9 +1582,12 @@ class TabGroup(Element):
self.ReturnValuesDictionary = {}
self.DictionaryKeyCounter = 0
self.ParentWindow = None
self.SelectedTitleColor = selected_title_color
self.Rows = []
self.TKNotebook = None
self.TabCount = 0
self.BorderWidth = border_width
self.Theme = theme
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.ChangeSubmits = change_submits
self.TabLocation = tab_location
@ -2033,7 +2059,7 @@ class Menu(Element):
# Table #
# ---------------------------------------------------------------------- #
class Table(Element):
def __init__(self, values, headings=None, visible_column_map=None, col_widths=None, def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, display_row_numbers=False, scrollable=None, font=None, justification='right', text_color=None, background_color=None, size=(None, None), pad=None, key=None, tooltip=None):
def __init__(self, values, headings=None, visible_column_map=None, col_widths=None, def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, display_row_numbers=False, font=None, justification='right', text_color=None, background_color=None, size=(None, None), pad=None, key=None, tooltip=None):
self.Values = values
self.ColumnHeadings = headings
self.ColumnsToDisplay = visible_column_map
@ -2044,7 +2070,6 @@ class Table(Element):
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.TextColor = text_color
self.Justification = justification
self.Scrollable = scrollable
self.InitialState = None
self.SelectMode = select_mode
self.DisplayRowNumbers = display_row_numbers
@ -2058,6 +2083,37 @@ class Table(Element):
super().__del__()
# ---------------------------------------------------------------------- #
# Tree #
# ---------------------------------------------------------------------- #
class Tree(Element):
def __init__(self, headings=None, visible_column_map=None, col_widths=None, def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, font=None, justification='right', text_color=None, background_color=None, num_rows=None, pad=None, key=None, tooltip=None):
self.ColumnHeadings = headings
self.ColumnsToDisplay = visible_column_map
self.ColumnWidths = col_widths
self.MaxColumnWidth = max_col_width
self.DefaultColumnWidth = def_col_width
self.AutoSizeColumns = auto_size_columns
self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR
self.TextColor = text_color
self.Justification = justification
self.InitialState = None
self.SelectMode = select_mode
self.NumRows = num_rows
self.TKTreeview = None
super().__init__(ELEM_TYPE_TREE, text_color=text_color, background_color=background_color, font=font, pad=pad, key=key, tooltip=tooltip)
return
def __del__(self):
super().__del__()
# ---------------------------------------------------------------------- #
# Error Element #
# ---------------------------------------------------------------------- #
@ -2078,11 +2134,9 @@ class ErrorElement(Element):
return self
def MenuItemChosenCallback(self, item_chosen):
# print('IN MENU ITEM CALLBACK', item_chosen)
self.ParentForm.LastButtonClicked = item_chosen
self.ParentForm.FormRemainedOpen = True
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
def Get(self):
return 'This is NOT a valid Element!\nSTOP trying to do things with it or I will have to crash at some point!'
def __del__(self):
super().__del__()
@ -2227,6 +2281,9 @@ class Window(object):
else:
window = self
if window:
if window.NonBlocking:
self.CloseNonBlockingForm()
else:
window._Close()
self.TKroot.quit()
self.RootNeedsDestroying = True
@ -2472,6 +2529,14 @@ class UberForm(object):
def __del__(self):
return
# ################################################################################
# ################################################################################
# END OF ELEMENT DEFINITIONS
# ################################################################################
# ################################################################################
# =========================================================================== #
# Button Lazy Functions so the caller doesn't have to define a bunch of stuff #
# =========================================================================== #
@ -2893,9 +2958,11 @@ else:
AddMenuItem(top_menu, item, element)
i += 1
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
# ===================================== TK CODE STARTS HERE ====================================================== #
# ------------------------------------------------------------------------------------------------------------------ #
# ------------------------------------------------------------------------------------------------------------------ #
def PackFormIntoFrame(form, containing_frame, toplevel_form):
def CharWidthInPixels():
@ -3160,7 +3227,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
element.TooltipObject = ToolTip(element.TKOptionMenu, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
# ------------------------- LISTBOX element ------------------------- #
elif element_type == ELEM_TYPE_INPUT_LISTBOX:
max_line_len = max([len(str(l)) for l in element.Values])
max_line_len = max([len(str(l)) for l in element.Values]) if len(element.Values) != 0 else 0
if auto_size_text is False: width=element_size[0]
else: width = max_line_len
listbox_frame = tk.Frame(tk_row_frame)
@ -3242,7 +3309,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
bar_color = element.BarColor
else:
bar_color = DEFAULT_PROGRESS_BAR_COLOR
element.TKProgressBar = TKProgressBar(tk_row_frame, element.MaxValue, progress_length, progress_width, orientation=direction, BarColor=bar_color, border_width=element.BorderWidth, relief=element.Relief, style=element.BarStyle )
element.TKProgressBar = TKProgressBar(tk_row_frame, element.MaxValue, progress_length, progress_width, orientation=direction, BarColor=bar_color, border_width=element.BorderWidth, relief=element.Relief, style=element.BarStyle, key=element.Key )
element.TKProgressBar.TKProgressBarForReal.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
# ------------------------- INPUT RADIO BUTTON element ------------------------- #
elif element_type == ELEM_TYPE_INPUT_RADIO:
@ -3383,15 +3450,27 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
elif element_type == ELEM_TYPE_TAB:
element.TKFrame = tk.Frame(form.TKNotebook)
PackFormIntoFrame(element, element.TKFrame, toplevel_form)
if element.Disabled:
form.TKNotebook.add(element.TKFrame, text=element.Title, state='disabled')
else:
form.TKNotebook.add(element.TKFrame, text=element.Title)
form.TKNotebook.pack(side=tk.LEFT, padx=element.Pad[0], pady=element.Pad[1])
element.ParentNotebook = form.TKNotebook
element.TabID = form.TabCount
form.TabCount += 1
if element.BackgroundColor != COLOR_SYSTEM_DEFAULT and element.BackgroundColor is not None:
element.TKFrame.configure(background=element.BackgroundColor,
highlightbackground=element.BackgroundColor,
highlightcolor=element.BackgroundColor)
# if element.TextColor != COLOR_SYSTEM_DEFAULT and element.TextColor is not None:
# element.TKFrame.configure(foreground=element.TextColor)
# ttk.Style().configure("TNotebook", background='red')
# ttk.Style().map("TNotebook.Tab", background=[("selected", 'orange')],
# foreground=[("selected", 'green')])
# ttk.Style().configure("TNotebook.Tab", background='blue', foreground='yellow')
if element.BorderWidth is not None:
element.TKFrame.configure(borderwidth=element.BorderWidth)
if element.Tooltip is not None:
@ -3400,20 +3479,37 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
# ------------------------- TabGroup element ------------------------- #
elif element_type == ELEM_TYPE_TAB_GROUP:
if element.TabLocation is not None:
custom_style = str(element.Key)+'customtab.TNotebook'
style = tkinter.ttk.Style(tk_row_frame)
if element.TabLocation == 'left':
style.configure('customtab.TNotebook', tabposition='ws')
elif element.TabLocation == 'right':
style.configure('customtab.TNotebook', tabposition='es')
elif element.TabLocation == 'top':
style.configure('customtab.TNotebook', tabposition='nw')
elif element.TabLocation == 'bottom':
style.configure('customtab.TNotebook', tabposition='sw')
if element.Theme is not None:
style.theme_use(element.Theme)
if element.TabLocation is not None:
position_dict = {'left':'w','right':'e', 'top':'n', 'bottom':'s', 'lefttop':'wn', 'leftbottom':'ws', 'righttop':'en', 'rightbottom':'es', 'bottomleft':'sw', 'bottomright':'se', 'topleft':'nw', 'topright':'ne'}
try:
tab_position = position_dict[element.TabLocation]
except:
tab_position = position_dict['top']
style.configure(custom_style, tabposition=tab_position)
element.TKNotebook = tkinter.ttk.Notebook(tk_row_frame, style='customtab.TNotebook')
else:
element.TKNotebook = tkinter.ttk.Notebook(tk_row_frame)
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
style.configure(custom_style, background=element.BackgroundColor, foreground='purple')
# style.theme_create("yummy", parent="alt", settings={
# "TNotebook": {"configure": {"tabmargins": [2, 5, 2, 0]}},
# "TNotebook.Tab": {
# "configure": {"padding": [5, 1], "background": mygreen},
# "map": {"background": [("selected", myred)],
# "expand": [("selected", [1, 1, 1, 0])]}}})
# style.configure(custom_style+'.Tab', background='red')
if element.SelectedTitleColor != None:
style.map(custom_style+'.Tab', foreground=[("selected",element.SelectedTitleColor)])
if element.TextColor is not None and element.TextColor != COLOR_SYSTEM_DEFAULT:
style.configure(custom_style+'.Tab', foreground=element.TextColor)
# style.configure(custom_style, background='blue', foreground='yellow')
element.TKNotebook = tkinter.ttk.Notebook(tk_row_frame, style=custom_style)
PackFormIntoFrame(element, toplevel_form.TKroot, toplevel_form)
@ -3510,6 +3606,48 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
element.TKTreeview.pack(side=tk.LEFT,expand=True, padx=0, pady=0, fill='both')
if element.Tooltip is not None:
element.TooltipObject = ToolTip(element.TKTreeview, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
# ------------------------- Tree element ------------------------- #
elif element_type == ELEM_TYPE_TREE:
width, height = element_size
if element.Justification == 'left': # justification
anchor = tk.W
elif element.Justification == 'right':
anchor = tk.E
else:
anchor = tk.CENTER
if element.ColumnsToDisplay is None: # Which cols to display
displaycolumns = element.ColumnHeadings
else:
displaycolumns = []
for i, should_display in enumerate(element.ColumnsToDisplay):
if should_display:
displaycolumns.append(element.ColumnHeadings[i])
column_headings= element.ColumnHeadings
# ------------- GET THE TREEVIEW WIDGET -------------
element.TKTreeview = tkinter.ttk.Treeview(tk_row_frame, columns=column_headings,
displaycolumns=displaycolumns, show='headings', height=height, selectmode=element.SelectMode)
treeview = element.TKTreeview
for i, heading in enumerate(element.ColumnHeadings): # Configure cols + headings
treeview.heading(heading, text=heading)
if element.AutoSizeColumns:
width = min(element.MaxColumnWidth, len(heading))
else:
try:
width = element.ColumnWidths[i]
except:
width = element.DefaultColumnWidth
treeview.column(heading, width=width*CharWidthInPixels(), anchor=anchor)
# ----- configure colors -----
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
tkinter.ttk.Style().configure("Treeview", background=element.BackgroundColor, fieldbackground=element.BackgroundColor)
if element.TextColor is not None and element.TextColor != COLOR_SYSTEM_DEFAULT:
tkinter.ttk.Style().configure("Treeview", foreground=element.TextColor)
element.TKTreeview.pack(side=tk.LEFT,expand=True, padx=0, pady=0, fill='both')
if element.Tooltip is not None: # tooltip
element.TooltipObject = ToolTip(element.TKTreeview, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
#............................DONE WITH ROW pack the row of widgets ..........................#
# done with row, pack the row of widgets
# tk_row_frame.grid(row=row_num+2, sticky=tk.NW, padx=DEFAULT_MARGINS[0])
@ -3961,7 +4099,7 @@ class DebugWin(object):
self.output_element = Output(size=win_size)
self.form_rows = [[Text('EasyPrint Output')],
[self.output_element],
[Quit()]]
[DummyButton('Quit')]]
self.form.AddRows(self.form_rows)
self.form.Show(non_blocking=True) # Show a ;non-blocking form, returns immediately
return
@ -4406,13 +4544,10 @@ def SetOptions(icon=None, button_color=None, element_size=(None,None), button_el
# Predefined settings that will change the colors and styles #
# of the elements. #
##############################################################
def ChangeLookAndFeel(index):
if sys.platform == 'darwin':
print('*** Changing look and feel is not supported on Mac platform ***')
return
# look and feel table
look_and_feel = {'SystemDefault': {'BACKGROUND' : COLOR_SYSTEM_DEFAULT, 'TEXT': COLOR_SYSTEM_DEFAULT, 'INPUT': COLOR_SYSTEM_DEFAULT,'TEXT_INPUT' : COLOR_SYSTEM_DEFAULT, 'SCROLL': COLOR_SYSTEM_DEFAULT, 'BUTTON': OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, 'PROGRESS': COLOR_SYSTEM_DEFAULT, 'BORDER': 1,'SLIDER_DEPTH':1, 'PROGRESS_DEPTH':0},
LOOK_AND_FEEL_TABLE = {'SystemDefault': {'BACKGROUND' : COLOR_SYSTEM_DEFAULT, 'TEXT': COLOR_SYSTEM_DEFAULT, 'INPUT': COLOR_SYSTEM_DEFAULT,'TEXT_INPUT' : COLOR_SYSTEM_DEFAULT, 'SCROLL': COLOR_SYSTEM_DEFAULT, 'BUTTON': OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, 'PROGRESS': COLOR_SYSTEM_DEFAULT, 'BORDER': 1,'SLIDER_DEPTH':1, 'PROGRESS_DEPTH':0},
'Topanga': {'BACKGROUND': '#282923', 'TEXT': '#E7DB74', 'INPUT': '#393a32',
'TEXT_INPUT': '#E7C855','SCROLL': '#E7C855', 'BUTTON': ('#E7C855', '#284B5A'),
'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1,'SLIDER_DEPTH':0, 'PROGRESS_DEPTH':0},
'GreenTan': {'BACKGROUND' : '#9FB8AD', 'TEXT': COLOR_SYSTEM_DEFAULT, 'INPUT':'#F7F3EC','TEXT_INPUT' : 'black','SCROLL': '#F7F3EC', 'BUTTON': ('white', '#475841'), 'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1,'SLIDER_DEPTH':0, 'PROGRESS_DEPTH':0},
@ -4497,8 +4632,18 @@ def ChangeLookAndFeel(index):
'TealMono': {'BACKGROUND': '#a8cfdd', 'TEXT': 'black', 'INPUT': '#dfedf2','SCROLL': '#dfedf2', 'TEXT_INPUT' : 'black', 'BUTTON': ('white', '#183440'), 'PROGRESS': DEFAULT_PROGRESS_BAR_COLOR, 'BORDER': 1,'SLIDER_DEPTH':0, 'PROGRESS_DEPTH':0}
}
def ChangeLookAndFeel(index):
global LOOK_AND_FEEL_TABLE
if sys.platform == 'darwin':
print('*** Changing look and feel is not supported on Mac platform ***')
return
# look and feel table
try:
colors = look_and_feel[index]
colors = LOOK_AND_FEEL_TABLE[index]
SetOptions(background_color=colors['BACKGROUND'],
text_element_background_color=colors['BACKGROUND'],
@ -4607,7 +4752,7 @@ def Popup(*args, **_3to2kwargs):
else:
local_line_width = MESSAGE_BOX_LINE_WIDTH
title = args_to_print[0] if args_to_print[0] is not None else 'None'
form = Window(title, auto_size_text=True, background_color=background_color, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
window = Window(title, auto_size_text=True, background_color=background_color, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
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 :-)
@ -4623,34 +4768,32 @@ def Popup(*args, **_3to2kwargs):
max_line_total = max(max_line_total, width_used)
# height = _GetNumLinesNeeded(message, width_used)
height = message_wrapped_lines
form.AddRow(Text(message_wrapped, auto_size_text=True, text_color=text_color, background_color=background_color))
window.AddRow(Text(message_wrapped, auto_size_text=True, text_color=text_color, background_color=background_color))
total_lines += height
pad = max_line_total-15 if max_line_total > 15 else 1
pad =1
if non_blocking:
PopupButton = DummyButton
PopupButton = DummyButton # important to use or else button will close other windows too!
else:
PopupButton = SimpleButton
PopupButton = Button
# show either an OK or Yes/No depending on paramater
if button_type is POPUP_BUTTONS_YES_NO:
form.AddRow(Text('', size=(pad, 1), auto_size_text=False, text_color=text_color, background_color=background_color), PopupButton('Yes', button_color=button_color, focus=True, bind_return_key=True), PopupButton('No', button_color=button_color))
window.AddRow(PopupButton('Yes', button_color=button_color, focus=True, bind_return_key=True, pad=((20,5),3)), PopupButton('No', button_color=button_color))
elif button_type is POPUP_BUTTONS_CANCELLED:
form.AddRow(Text('', size=(pad, 1), auto_size_text=False, text_color=text_color, background_color=background_color), PopupButton('Cancelled', button_color=button_color, focus=True, bind_return_key=True))
window.AddRow(PopupButton('Cancelled', button_color=button_color, focus=True, bind_return_key=True, pad=((20,0),3)))
elif button_type is POPUP_BUTTONS_ERROR:
form.AddRow(Text('', size=(pad, 1), auto_size_text=False, text_color=text_color, background_color=background_color), PopupButton('Error', size=(6, 1), button_color=button_color, focus=True, bind_return_key=True))
window.AddRow(PopupButton('Error', size=(6,1), button_color=button_color, focus=True, bind_return_key=True, pad=((20,0),3)))
elif button_type is POPUP_BUTTONS_OK_CANCEL:
form.AddRow(Text('', size=(pad, 1), auto_size_text=False, text_color=text_color, background_color=background_color), PopupButton('OK', size=(5, 1), button_color=button_color, focus=True, bind_return_key=True),
window.AddRow(PopupButton('OK', size=(5,1), button_color=button_color, focus=True, bind_return_key=True),
PopupButton('Cancel', size=(5,1), button_color=button_color))
elif button_type is POPUP_BUTTONS_NO_BUTTONS:
pass
else:
form.AddRow(Text('', size=(pad, 1), auto_size_text=False, background_color=background_color), PopupButton('OK', size=(5, 1), button_color=button_color, focus=True, bind_return_key=True))
window.AddRow(PopupButton('OK', size=(5,1), button_color=button_color, focus=True, bind_return_key=True, pad=((20,0),3)))
if non_blocking:
button, values = form.ReadNonBlocking()
button, values = window.ReadNonBlocking()
else:
button, values = form.Show()
button, values = window.Show()
return button
@ -4773,6 +4916,61 @@ def PopupNonBlocking(*args, **_3to2kwargs):
PopupNoWait = PopupNonBlocking
# --------------------------- PopupQuick - a NonBlocking, Self-closing Popup ---------------------------
def PopupQuick(*args, **_3to2kwargs):
if 'location' in _3to2kwargs: location = _3to2kwargs['location']; del _3to2kwargs['location']
else: location = (None,None)
if 'keep_on_top' in _3to2kwargs: keep_on_top = _3to2kwargs['keep_on_top']; del _3to2kwargs['keep_on_top']
else: keep_on_top = False
if 'grab_anywhere' in _3to2kwargs: grab_anywhere = _3to2kwargs['grab_anywhere']; del _3to2kwargs['grab_anywhere']
else: grab_anywhere = False
if 'no_titlebar' in _3to2kwargs: no_titlebar = _3to2kwargs['no_titlebar']; del _3to2kwargs['no_titlebar']
else: no_titlebar = False
if 'font' in _3to2kwargs: font = _3to2kwargs['font']; del _3to2kwargs['font']
else: font = None
if 'line_width' in _3to2kwargs: line_width = _3to2kwargs['line_width']; del _3to2kwargs['line_width']
else: line_width = None
if 'icon' in _3to2kwargs: icon = _3to2kwargs['icon']; del _3to2kwargs['icon']
else: icon = DEFAULT_WINDOW_ICON
if 'non_blocking' in _3to2kwargs: non_blocking = _3to2kwargs['non_blocking']; del _3to2kwargs['non_blocking']
else: non_blocking = True
if 'auto_close_duration' in _3to2kwargs: auto_close_duration = _3to2kwargs['auto_close_duration']; del _3to2kwargs['auto_close_duration']
else: auto_close_duration = 1
if 'auto_close' in _3to2kwargs: auto_close = _3to2kwargs['auto_close']; del _3to2kwargs['auto_close']
else: auto_close = True
if 'text_color' in _3to2kwargs: text_color = _3to2kwargs['text_color']; del _3to2kwargs['text_color']
else: text_color = None
if 'background_color' in _3to2kwargs: background_color = _3to2kwargs['background_color']; del _3to2kwargs['background_color']
else: background_color = None
if 'button_color' in _3to2kwargs: button_color = _3to2kwargs['button_color']; del _3to2kwargs['button_color']
else: button_color = None
if 'button_type' in _3to2kwargs: button_type = _3to2kwargs['button_type']; del _3to2kwargs['button_type']
else: button_type = POPUP_BUTTONS_OK
"""
Show Popup box that doesn't block and closes itself
:param args:
:param button_type:
:param button_color:
:param background_color:
:param text_color:
:param auto_close:
:param auto_close_duration:
:param non_blocking:
:param icon:
:param line_width:
:param font:
:param no_titlebar:
:param grab_anywhere:
:param keep_on_top:
:param location:
:return:
"""
Popup(*args, button_color=button_color, background_color=background_color, text_color=text_color, button_type=button_type,
auto_close=auto_close, auto_close_duration=auto_close_duration, non_blocking=non_blocking, icon=icon, line_width=line_width,
font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
# --------------------------- PopupNoTitlebar ---------------------------
def PopupNoTitlebar(*args, **_3to2kwargs):
if 'location' in _3to2kwargs: location = _3to2kwargs['location']; del _3to2kwargs['location']

View File

@ -21,9 +21,9 @@
## Now supports both Python 2.7 & 3
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.9.0-red.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.9.1-red.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.1.0-blue.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.1.2-blue.svg?longCache=true&style=for-the-badge)
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
@ -2774,6 +2774,8 @@ A MikeTheWatchGuy production... entirely responsible for this code.... unless it
| 03.08.04 | Sept 30, 2018 - See release notes
| 03.09.00 | Oct 1, 2018 |
| 2.7 01.01.00 | Oct 1, 2018
| 2.7 01.01.02 | Oct 8, 2018
| 03.09.01 | Oct 8, 2018
@ -2905,6 +2907,20 @@ It's official. There is a 2.7 version of PySimpleGUI!
* Python 2.7 got a TON of features . Look back to 1.0 release for the list
* Tab locations - Can place Tabs on top, bottom, left, right now instead of only the top
### 3.9.1 & 1.1.2
* Tab features
* Themes
* Enable / Disable
* Tab text colors
* Selected tab color
* New GetListValues method for Listbox
* Can now have multiple progress bars in 1 window
* Fix for closing debug-output window with other windows open
* Topanga Look and Feel setting
* User can create new look and feel settings / can access the look and feel table
* New PopupQuick call. Shows a non-blocking popup window with auto-close
* Tree Element partially done (don't use despite it showing up)
### Upcoming
Make suggestions people! Future release features
@ -2943,6 +2959,9 @@ Want to view your form's results as a dictionary instead of a list... no problem
You can also look up elements using their keys. This is an excellent way to update elements in reaction to another element. Call `form.FindElement(key)` to get the Element.
**Named / Optional Parameters**
This is a language feature that is featured **heavily** in all of the API calls, both functions and classes. Elements are configured, in-place, by setting one or more optional parameters. For example, a Text element's color is chosen by setting the optional `text_color` parameter.
## Author
MikeTheWatchGuy
@ -2970,7 +2989,7 @@ GNU Lesser General Public License (LGPL 3) +
* one of the most critical constructs in PySimpleGUI
* [venim](https://github.com/venim) code to doing Alt-Selections in menus, updating Combobox using index, request to disable windows (a really good idea), checkbox and tab submits on change, returning keys for elements that have change_submits set, ...
* [rtrrtr](https://github.com/rtrrtr) Helped get the 2.7 and 3.x code unified (big damned deal)
* Tony Crewe (anthony.crewe@gmail.com) Generously provided his classroom materials that he has written to teach a GUI course. If you're an educator and want to trade materials with Tony, he would like to hear from you.
## How Do I
Finally, I must thank the fine folks at How Do I.

View File

@ -21,9 +21,9 @@
## Now supports both Python 2.7 & 3
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.9.0-red.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.9.1-red.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.1.0-blue.svg?longCache=true&style=for-the-badge)
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.1.2-blue.svg?longCache=true&style=for-the-badge)
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
@ -2774,6 +2774,8 @@ A MikeTheWatchGuy production... entirely responsible for this code.... unless it
| 03.08.04 | Sept 30, 2018 - See release notes
| 03.09.00 | Oct 1, 2018 |
| 2.7 01.01.00 | Oct 1, 2018
| 2.7 01.01.02 | Oct 8, 2018
| 03.09.01 | Oct 8, 2018
@ -2905,6 +2907,20 @@ It's official. There is a 2.7 version of PySimpleGUI!
* Python 2.7 got a TON of features . Look back to 1.0 release for the list
* Tab locations - Can place Tabs on top, bottom, left, right now instead of only the top
### 3.9.1 & 1.1.2
* Tab features
* Themes
* Enable / Disable
* Tab text colors
* Selected tab color
* New GetListValues method for Listbox
* Can now have multiple progress bars in 1 window
* Fix for closing debug-output window with other windows open
* Topanga Look and Feel setting
* User can create new look and feel settings / can access the look and feel table
* New PopupQuick call. Shows a non-blocking popup window with auto-close
* Tree Element partially done (don't use despite it showing up)
### Upcoming
Make suggestions people! Future release features
@ -2943,6 +2959,9 @@ Want to view your form's results as a dictionary instead of a list... no problem
You can also look up elements using their keys. This is an excellent way to update elements in reaction to another element. Call `form.FindElement(key)` to get the Element.
**Named / Optional Parameters**
This is a language feature that is featured **heavily** in all of the API calls, both functions and classes. Elements are configured, in-place, by setting one or more optional parameters. For example, a Text element's color is chosen by setting the optional `text_color` parameter.
## Author
MikeTheWatchGuy
@ -2970,7 +2989,7 @@ GNU Lesser General Public License (LGPL 3) +
* one of the most critical constructs in PySimpleGUI
* [venim](https://github.com/venim) code to doing Alt-Selections in menus, updating Combobox using index, request to disable windows (a really good idea), checkbox and tab submits on change, returning keys for elements that have change_submits set, ...
* [rtrrtr](https://github.com/rtrrtr) Helped get the 2.7 and 3.x code unified (big damned deal)
* Tony Crewe (anthony.crewe@gmail.com) Generously provided his classroom materials that he has written to teach a GUI course. If you're an educator and want to trade materials with Tony, he would like to hear from you.
## How Do I
Finally, I must thank the fine folks at How Do I.