commit
fc2672d32c
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import sys
|
||||||
|
if sys.version_info[0] >= 3:
|
||||||
|
import PySimpleGUI as sg
|
||||||
|
else:
|
||||||
|
import PySimpleGUI27 as sg
|
||||||
|
|
||||||
|
"""
|
||||||
|
Demo program that reroutes stdout and stderr.
|
||||||
|
Type something in the input box and click Print
|
||||||
|
Whatever you typed is "printed" using a standard print statement
|
||||||
|
Use the Output Element in your window layout to reroute stdout
|
||||||
|
You will see the output of the print in the Output Element in the center of the window
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
layout = [
|
||||||
|
[sg.Text('Type something in input field and click print')],
|
||||||
|
[sg.In()],
|
||||||
|
[sg.Output()],
|
||||||
|
[sg.Button('Print')]
|
||||||
|
]
|
||||||
|
|
||||||
|
window = sg.Window('Reroute stdout').Layout(layout)
|
||||||
|
|
||||||
|
while True: # Event Loop
|
||||||
|
event, values = window.Read()
|
||||||
|
if event is None:
|
||||||
|
break
|
||||||
|
print('You typed: ', values[0])
|
346
PySimpleGUI27.py
346
PySimpleGUI27.py
|
@ -190,15 +190,18 @@ ThisRow = 555666777 # magic number
|
||||||
# DEFAULT_WINDOW_ICON = ''
|
# DEFAULT_WINDOW_ICON = ''
|
||||||
MESSAGE_BOX_LINE_WIDTH = 60
|
MESSAGE_BOX_LINE_WIDTH = 60
|
||||||
|
|
||||||
|
# "Special" Key Values.. reserved
|
||||||
# Key representing a Read timeout
|
# Key representing a Read timeout
|
||||||
TIMEOUT_KEY = '__timeout__'
|
TIMEOUT_KEY = '__TIMEOUT__'
|
||||||
|
# Key indicating should not create any return values for element
|
||||||
|
WRITE_ONLY_KEY = '__WRITE ONLY__'
|
||||||
|
|
||||||
# a shameful global variable. This represents the top-level window information. Needed because opening a second window is different than opening the first.
|
# a shameful global variable. This represents the top-level window information. Needed because opening a second window is different than opening the first.
|
||||||
class MyWindows(object):
|
class MyWindows(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.NumOpenWindows = 0
|
self.NumOpenWindows = 0
|
||||||
self.user_defined_icon = None
|
self.user_defined_icon = None
|
||||||
|
self.hidden_master_root = None
|
||||||
|
|
||||||
def Decrement(self):
|
def Decrement(self):
|
||||||
self.NumOpenWindows -= 1 * (self.NumOpenWindows != 0) # decrement if not 0
|
self.NumOpenWindows -= 1 * (self.NumOpenWindows != 0) # decrement if not 0
|
||||||
|
@ -405,7 +408,6 @@ class Element(object):
|
||||||
button_element.ButtonCallBack()
|
button_element.ButtonCallBack()
|
||||||
|
|
||||||
def ListboxSelectHandler(self, event):
|
def ListboxSelectHandler(self, event):
|
||||||
MyForm = self.ParentForm
|
|
||||||
# first, get the results table built
|
# first, get the results table built
|
||||||
# modify the Results table in the parent FlexForm object
|
# modify the Results table in the parent FlexForm object
|
||||||
if self.Key is not None:
|
if self.Key is not None:
|
||||||
|
@ -417,7 +419,6 @@ class Element(object):
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
def ComboboxSelectHandler(self, event):
|
def ComboboxSelectHandler(self, event):
|
||||||
MyForm = self.ParentForm
|
|
||||||
# first, get the results table built
|
# first, get the results table built
|
||||||
# modify the Results table in the parent FlexForm object
|
# modify the Results table in the parent FlexForm object
|
||||||
if self.Key is not None:
|
if self.Key is not None:
|
||||||
|
@ -428,8 +429,16 @@ class Element(object):
|
||||||
if self.ParentForm.CurrentlyRunningMainloop:
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
self.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
|
def RadioHandler(self):
|
||||||
|
if self.Key is not None:
|
||||||
|
self.ParentForm.LastButtonClicked = self.Key
|
||||||
|
else:
|
||||||
|
self.ParentForm.LastButtonClicked = ''
|
||||||
|
self.ParentForm.FormRemainedOpen = True
|
||||||
|
if self.ParentForm.CurrentlyRunningMainloop:
|
||||||
|
self.ParentForm.TKroot.quit()
|
||||||
|
|
||||||
def CheckboxHandler(self):
|
def CheckboxHandler(self):
|
||||||
MyForm = self.ParentForm
|
|
||||||
if self.Key is not None:
|
if self.Key is not None:
|
||||||
self.ParentForm.LastButtonClicked = self.Key
|
self.ParentForm.LastButtonClicked = self.Key
|
||||||
else:
|
else:
|
||||||
|
@ -439,7 +448,6 @@ class Element(object):
|
||||||
self.ParentForm.TKroot.quit()
|
self.ParentForm.TKroot.quit()
|
||||||
|
|
||||||
def TabGroupSelectHandler(self, event):
|
def TabGroupSelectHandler(self, event):
|
||||||
MyForm = self.ParentForm
|
|
||||||
if self.Key is not None:
|
if self.Key is not None:
|
||||||
self.ParentForm.LastButtonClicked = self.Key
|
self.ParentForm.LastButtonClicked = self.Key
|
||||||
else:
|
else:
|
||||||
|
@ -449,7 +457,6 @@ class Element(object):
|
||||||
self.ParentForm.TKroot.quit()
|
self.ParentForm.TKroot.quit()
|
||||||
|
|
||||||
def KeyboardHandler(self, event):
|
def KeyboardHandler(self, event):
|
||||||
MyForm = self.ParentForm
|
|
||||||
if self.Key is not None:
|
if self.Key is not None:
|
||||||
self.ParentForm.LastButtonClicked = self.Key
|
self.ParentForm.LastButtonClicked = self.Key
|
||||||
else:
|
else:
|
||||||
|
@ -520,6 +527,13 @@ class InputText(Element):
|
||||||
def Get(self):
|
def Get(self):
|
||||||
return self.TKStringVar.get()
|
return self.TKStringVar.get()
|
||||||
|
|
||||||
|
|
||||||
|
def SetFocus(self):
|
||||||
|
try:
|
||||||
|
self.TKEntry.focus_set()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
super().__del__()
|
super().__del__()
|
||||||
|
|
||||||
|
@ -535,7 +549,7 @@ Input = InputText
|
||||||
class InputCombo(Element):
|
class InputCombo(Element):
|
||||||
def __init__(self, values, default_value=None, size=(None, None), auto_size_text=None, background_color=None,
|
def __init__(self, values, default_value=None, size=(None, None), auto_size_text=None, background_color=None,
|
||||||
text_color=None, change_submits=False, disabled=False, key=None, pad=None, tooltip=None,
|
text_color=None, change_submits=False, disabled=False, key=None, pad=None, tooltip=None,
|
||||||
readonly=False):
|
readonly=False, font=None):
|
||||||
'''
|
'''
|
||||||
Input Combo Box Element (also called Dropdown box)
|
Input Combo Box Element (also called Dropdown box)
|
||||||
:param values:
|
:param values:
|
||||||
|
@ -554,9 +568,9 @@ class InputCombo(Element):
|
||||||
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
|
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
|
||||||
|
|
||||||
super().__init__(ELEM_TYPE_INPUT_COMBO, size=size, auto_size_text=auto_size_text, background_color=bg,
|
super().__init__(ELEM_TYPE_INPUT_COMBO, size=size, auto_size_text=auto_size_text, background_color=bg,
|
||||||
text_color=fg, key=key, pad=pad, tooltip=tooltip)
|
text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT)
|
||||||
|
|
||||||
def Update(self, value=None, values=None, set_to_index=None, disabled=None, readonly=None):
|
def Update(self, value=None, values=None, set_to_index=None, disabled=None, readonly=None, font=None):
|
||||||
if values is not None:
|
if values is not None:
|
||||||
try:
|
try:
|
||||||
self.TKCombo['values'] = values
|
self.TKCombo['values'] = values
|
||||||
|
@ -587,6 +601,8 @@ class InputCombo(Element):
|
||||||
self.Readonly = readonly
|
self.Readonly = readonly
|
||||||
if self.Readonly:
|
if self.Readonly:
|
||||||
self.TKCombo['state'] = 'readonly'
|
self.TKCombo['state'] = 'readonly'
|
||||||
|
if font is not None:
|
||||||
|
self.TKText.configure(font=font)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
try:
|
try:
|
||||||
|
@ -745,7 +761,7 @@ class Listbox(Element):
|
||||||
# ---------------------------------------------------------------------- #
|
# ---------------------------------------------------------------------- #
|
||||||
class Radio(Element):
|
class Radio(Element):
|
||||||
def __init__(self, text, group_id, default=False, disabled=False, size=(None, None), auto_size_text=None,
|
def __init__(self, text, group_id, default=False, disabled=False, size=(None, None), auto_size_text=None,
|
||||||
background_color=None, text_color=None, font=None, key=None, pad=None, tooltip=None):
|
background_color=None, text_color=None, font=None, key=None, pad=None, tooltip=None, change_submits=False):
|
||||||
'''
|
'''
|
||||||
Radio Button Element
|
Radio Button Element
|
||||||
:param text:
|
:param text:
|
||||||
|
@ -760,6 +776,7 @@ class Radio(Element):
|
||||||
:param key:
|
:param key:
|
||||||
:param pad:
|
:param pad:
|
||||||
:param tooltip:
|
:param tooltip:
|
||||||
|
:param change_submits:
|
||||||
'''
|
'''
|
||||||
self.InitialState = default
|
self.InitialState = default
|
||||||
self.Text = text
|
self.Text = text
|
||||||
|
@ -767,7 +784,8 @@ class Radio(Element):
|
||||||
self.GroupID = group_id
|
self.GroupID = group_id
|
||||||
self.Value = None
|
self.Value = None
|
||||||
self.Disabled = disabled
|
self.Disabled = disabled
|
||||||
self.TextColor = text_color if text_color else DEFAULT_TEXT_COLOR
|
self.TextColor = text_color or DEFAULT_TEXT_COLOR
|
||||||
|
self.ChangeSubmits = change_submits
|
||||||
|
|
||||||
super().__init__(ELEM_TYPE_INPUT_RADIO, size=size, auto_size_text=auto_size_text, font=font,
|
super().__init__(ELEM_TYPE_INPUT_RADIO, size=size, auto_size_text=auto_size_text, font=font,
|
||||||
background_color=background_color, text_color=self.TextColor, key=key, pad=pad,
|
background_color=background_color, text_color=self.TextColor, key=key, pad=pad,
|
||||||
|
@ -931,7 +949,7 @@ class Spin(Element):
|
||||||
class Multiline(Element):
|
class Multiline(Element):
|
||||||
def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, size=(None, None),
|
def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, size=(None, None),
|
||||||
auto_size_text=None, background_color=None, text_color=None, change_submits=False, do_not_clear=False, key=None, focus=False,
|
auto_size_text=None, background_color=None, text_color=None, change_submits=False, do_not_clear=False, key=None, focus=False,
|
||||||
pad=None, tooltip=None):
|
font=None, pad=None, tooltip=None):
|
||||||
'''
|
'''
|
||||||
Multiline Element
|
Multiline Element
|
||||||
:param default_text:
|
:param default_text:
|
||||||
|
@ -947,6 +965,7 @@ class Multiline(Element):
|
||||||
:param focus:
|
:param focus:
|
||||||
:param pad:
|
:param pad:
|
||||||
:param tooltip:
|
:param tooltip:
|
||||||
|
:param font:
|
||||||
'''
|
'''
|
||||||
self.DefaultText = default_text
|
self.DefaultText = default_text
|
||||||
self.EnterSubmits = enter_submits
|
self.EnterSubmits = enter_submits
|
||||||
|
@ -959,10 +978,10 @@ class Multiline(Element):
|
||||||
self.ChangeSubmits = change_submits
|
self.ChangeSubmits = change_submits
|
||||||
|
|
||||||
super().__init__(ELEM_TYPE_INPUT_MULTILINE, size=size, auto_size_text=auto_size_text, background_color=bg,
|
super().__init__(ELEM_TYPE_INPUT_MULTILINE, size=size, auto_size_text=auto_size_text, background_color=bg,
|
||||||
text_color=fg, key=key, pad=pad, tooltip=tooltip)
|
text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT)
|
||||||
return
|
return
|
||||||
|
|
||||||
def Update(self, value=None, disabled=None, append=False):
|
def Update(self, value=None, disabled=None, append=False, font=None):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
try:
|
try:
|
||||||
if not append:
|
if not append:
|
||||||
|
@ -977,10 +996,19 @@ class Multiline(Element):
|
||||||
self.TKText.configure(state='disabled')
|
self.TKText.configure(state='disabled')
|
||||||
elif disabled == False:
|
elif disabled == False:
|
||||||
self.TKText.configure(state='normal')
|
self.TKText.configure(state='normal')
|
||||||
|
if font is not None:
|
||||||
|
self.TKText.configure(font=font)
|
||||||
|
|
||||||
def Get(self):
|
def Get(self):
|
||||||
return self.TKText.get(1.0, tk.END)
|
return self.TKText.get(1.0, tk.END)
|
||||||
|
|
||||||
|
|
||||||
|
def SetFocus(self):
|
||||||
|
try:
|
||||||
|
self.TKText.focus_set()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
super().__del__()
|
super().__del__()
|
||||||
|
|
||||||
|
@ -1240,6 +1268,7 @@ class Button(Element):
|
||||||
self.Focus = focus
|
self.Focus = focus
|
||||||
self.TKCal = None
|
self.TKCal = None
|
||||||
self.CalendarCloseWhenChosen = None
|
self.CalendarCloseWhenChosen = None
|
||||||
|
self.DefaultDate_M_D_Y = (None, None, None)
|
||||||
self.InitialFolder = initial_folder
|
self.InitialFolder = initial_folder
|
||||||
self.Disabled = disabled
|
self.Disabled = disabled
|
||||||
|
|
||||||
|
@ -1369,7 +1398,7 @@ class Button(Element):
|
||||||
should_submit_window = False
|
should_submit_window = False
|
||||||
root = tk.Toplevel()
|
root = tk.Toplevel()
|
||||||
root.title('Calendar Chooser')
|
root.title('Calendar Chooser')
|
||||||
self.TKCal = TKCalendar(master=root, firstweekday=calendar.SUNDAY, target_element=target_element, close_when_chosen=self.CalendarCloseWhenChosen )
|
self.TKCal = TKCalendar(master=root, firstweekday=calendar.SUNDAY, target_element=target_element, close_when_chosen=self.CalendarCloseWhenChosen, default_date=self.DefaultDate_M_D_Y )
|
||||||
self.TKCal.pack(expand=1, fill='both')
|
self.TKCal.pack(expand=1, fill='both')
|
||||||
root.update()
|
root.update()
|
||||||
|
|
||||||
|
@ -2067,6 +2096,12 @@ class TkScrollableFrame(tk.Frame):
|
||||||
self.TKFrame.config(borderwidth=0, highlightthickness=0)
|
self.TKFrame.config(borderwidth=0, highlightthickness=0)
|
||||||
self.config(borderwidth=0, highlightthickness=0)
|
self.config(borderwidth=0, highlightthickness=0)
|
||||||
|
|
||||||
|
# scrollbar = tk.Scrollbar(frame)
|
||||||
|
# scrollbar.pack(side=tk.RIGHT, fill='y')
|
||||||
|
# scrollbar.config(command=treeview.yview)
|
||||||
|
# self.vscrollbar.config(command=self.TKFrame.yview)
|
||||||
|
# self.TKFrame.configure(yscrollcommand=self.vscrollbar.set)
|
||||||
|
|
||||||
self.bind('<Configure>', self.set_scrollregion)
|
self.bind('<Configure>', self.set_scrollregion)
|
||||||
|
|
||||||
self.bind_mouse_scroll(self.canvas, self.yscroll)
|
self.bind_mouse_scroll(self.canvas, self.yscroll)
|
||||||
|
@ -2182,7 +2217,7 @@ class TKCalendar(tkinter.ttk.Frame):
|
||||||
datetime = calendar.datetime.datetime
|
datetime = calendar.datetime.datetime
|
||||||
timedelta = calendar.datetime.timedelta
|
timedelta = calendar.datetime.timedelta
|
||||||
|
|
||||||
def __init__(self, master=None, target_element=None, close_when_chosen=True, **kw):
|
def __init__(self, master=None, target_element=None, close_when_chosen=True, default_date=(None, None, None), **kw):
|
||||||
"""
|
"""
|
||||||
WIDGET-SPECIFIC OPTIONS
|
WIDGET-SPECIFIC OPTIONS
|
||||||
|
|
||||||
|
@ -2190,15 +2225,16 @@ class TKCalendar(tkinter.ttk.Frame):
|
||||||
selectforeground
|
selectforeground
|
||||||
"""
|
"""
|
||||||
self._TargetElement = target_element
|
self._TargetElement = target_element
|
||||||
|
default_mon, default_day, default_year = default_date
|
||||||
# remove custom options from kw before initializating ttk.Frame
|
# remove custom options from kw before initializating ttk.Frame
|
||||||
fwday = kw.pop('firstweekday', calendar.MONDAY)
|
fwday = kw.pop('firstweekday', calendar.MONDAY)
|
||||||
year = kw.pop('year', self.datetime.now().year)
|
year = kw.pop('year', default_year or self.datetime.now().year)
|
||||||
month = kw.pop('month', self.datetime.now().month)
|
month = kw.pop('month', default_mon or self.datetime.now().month)
|
||||||
locale = kw.pop('locale', None)
|
locale = kw.pop('locale', None)
|
||||||
sel_bg = kw.pop('selectbackground', '#ecffc4')
|
sel_bg = kw.pop('selectbackground', '#ecffc4')
|
||||||
sel_fg = kw.pop('selectforeground', '#05640e')
|
sel_fg = kw.pop('selectforeground', '#05640e')
|
||||||
|
|
||||||
self._date = self.datetime(year, month, 1)
|
self._date = self.datetime(year, month, default_day or 1)
|
||||||
self._selection = None # no date selected
|
self._selection = None # no date selected
|
||||||
self._master = master
|
self._master = master
|
||||||
self.close_when_chosen = close_when_chosen
|
self.close_when_chosen = close_when_chosen
|
||||||
|
@ -2582,17 +2618,25 @@ class Tree(Element):
|
||||||
self.add_treeview_data(node)
|
self.add_treeview_data(node)
|
||||||
|
|
||||||
|
|
||||||
def Update(self, values=None):
|
def Update(self, values=None, key=None, value=None, text=None):
|
||||||
if values is None:
|
if values is not None:
|
||||||
return
|
children = self.TKTreeview.get_children()
|
||||||
children = self.TKTreeview.get_children()
|
for i in children:
|
||||||
for i in children:
|
self.TKTreeview.detach(i)
|
||||||
self.TKTreeview.detach(i)
|
self.TKTreeview.delete(i)
|
||||||
self.TKTreeview.delete(i)
|
children = self.TKTreeview.get_children()
|
||||||
children = self.TKTreeview.get_children()
|
self.TreeData = values
|
||||||
self.TreeData = values
|
self.add_treeview_data(self.TreeData.root_node)
|
||||||
self.add_treeview_data(self.TreeData.root_node)
|
self.SelectedRows = []
|
||||||
self.SelectedRows = []
|
if key is not None:
|
||||||
|
item = self.TKTreeview.item(key)
|
||||||
|
if value is not None:
|
||||||
|
self.TKTreeview.item(key, values=value)
|
||||||
|
if text is not None:
|
||||||
|
self.TKTreeview.item(key, text=text)
|
||||||
|
item = self.TKTreeview.item(key)
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
super().__del__()
|
super().__del__()
|
||||||
|
@ -2624,11 +2668,6 @@ class TreeData(object):
|
||||||
parent_node = self.tree_dict[parent]
|
parent_node = self.tree_dict[parent]
|
||||||
parent_node._Add(node)
|
parent_node._Add(node)
|
||||||
|
|
||||||
# def _print_node(self, node):
|
|
||||||
# # print(f'Node: {node.text}')
|
|
||||||
# # print(f'Children = {[c.text for c in node.children]}')
|
|
||||||
# for node in node.children:
|
|
||||||
# self._print_node(node)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self._NodeStr(self.root_node, 1)
|
return self._NodeStr(self.root_node, 1)
|
||||||
|
@ -2940,13 +2979,11 @@ class Window(object):
|
||||||
else:
|
else:
|
||||||
return self.ReturnValues
|
return self.ReturnValues
|
||||||
|
|
||||||
def ReadNonBlocking(self, Message=''):
|
def ReadNonBlocking(self):
|
||||||
if self.TKrootDestroyed:
|
if self.TKrootDestroyed:
|
||||||
return None, None
|
return None, None
|
||||||
if not self.Shown:
|
if not self.Shown:
|
||||||
self.Show(non_blocking=True)
|
self.Show(non_blocking=True)
|
||||||
if Message:
|
|
||||||
print(Message)
|
|
||||||
try:
|
try:
|
||||||
rc = self.TKroot.update()
|
rc = self.TKroot.update()
|
||||||
except:
|
except:
|
||||||
|
@ -3086,7 +3123,8 @@ class Window(object):
|
||||||
self.RootNeedsDestroying = True
|
self.RootNeedsDestroying = True
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def CloseNonBlocking(self):
|
|
||||||
|
def Close(self):
|
||||||
if self.TKrootDestroyed:
|
if self.TKrootDestroyed:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
|
@ -3095,16 +3133,16 @@ class Window(object):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
CloseNonBlockingForm = CloseNonBlocking
|
CloseNonBlockingForm = Close
|
||||||
Close = CloseNonBlockingForm
|
CloseNonBlocking = Close
|
||||||
|
|
||||||
|
|
||||||
# IT FINALLY WORKED! 29-Oct-2018 was the first time this damned thing got called
|
# IT FINALLY WORKED! 29-Oct-2018 was the first time this damned thing got called
|
||||||
def OnClosingCallback(self):
|
def OnClosingCallback(self):
|
||||||
print('Got closing callback')
|
# print('Got closing callback')
|
||||||
self.TKroot.quit() # kick the users out of the mainloop
|
self.TKroot.quit() # kick the users out of the mainloop
|
||||||
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
||||||
self.TKroot.destroy() # kick the users out of the mainloop
|
self.TKroot.destroy() # kick the users out of the mainloop
|
||||||
|
self.TKrootDestroyed = True
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -3150,6 +3188,10 @@ class Window(object):
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def CurrentLocation(self):
|
||||||
|
return int(self.TKroot.winfo_x()), int(self.TKroot.winfo_y())
|
||||||
|
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -3161,10 +3203,7 @@ class Window(object):
|
||||||
for row in self.Rows:
|
for row in self.Rows:
|
||||||
for element in row:
|
for element in row:
|
||||||
element.__del__()
|
element.__del__()
|
||||||
# try:
|
|
||||||
# del(self.TKroot)
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
|
|
||||||
FlexForm = Window
|
FlexForm = Window
|
||||||
|
@ -3370,7 +3409,7 @@ def DummyButton(button_text, image_filename=None, image_data=None, image_size=(N
|
||||||
|
|
||||||
|
|
||||||
# ------------------------- Calendar Chooser Button lazy function ------------------------- #
|
# ------------------------- Calendar Chooser Button lazy function ------------------------- #
|
||||||
def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True, image_filename=None, image_data=None, image_size=(None, None),
|
def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True, default_date_m_d_y=(None,None,None), image_filename=None, image_data=None, image_size=(None, None),
|
||||||
image_subsample=None, tooltip=None, border_width=None, size=(None, None), auto_size_button=None,
|
image_subsample=None, tooltip=None, border_width=None, size=(None, None), auto_size_button=None,
|
||||||
button_color=None, disabled=False, font=None, bind_return_key=False, focus=False, pad=None,
|
button_color=None, disabled=False, font=None, bind_return_key=False, focus=False, pad=None,
|
||||||
key=None):
|
key=None):
|
||||||
|
@ -3380,6 +3419,7 @@ def CalendarButton(button_text, target=(None, None), close_when_date_chosen=True
|
||||||
auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled,
|
auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled,
|
||||||
bind_return_key=bind_return_key, focus=focus, pad=pad, key=key)
|
bind_return_key=bind_return_key, focus=focus, pad=pad, key=key)
|
||||||
button.CalendarCloseWhenChosen = close_when_date_chosen
|
button.CalendarCloseWhenChosen = close_when_date_chosen
|
||||||
|
button.DefaultDate_M_D_Y = default_date_m_d_y
|
||||||
return button
|
return button
|
||||||
|
|
||||||
|
|
||||||
|
@ -3453,6 +3493,8 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
button_pressed_text = top_level_form.LastButtonClicked
|
button_pressed_text = top_level_form.LastButtonClicked
|
||||||
for row_num, row in enumerate(form.Rows):
|
for row_num, row in enumerate(form.Rows):
|
||||||
for col_num, element in enumerate(row):
|
for col_num, element in enumerate(row):
|
||||||
|
if element.Key is not None and WRITE_ONLY_KEY in str(element.Key):
|
||||||
|
continue
|
||||||
value = None
|
value = None
|
||||||
if element.Type == ELEM_TYPE_COLUMN:
|
if element.Type == ELEM_TYPE_COLUMN:
|
||||||
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
|
@ -4199,8 +4241,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
||||||
element.TKIntVar = RadVar # store the RadVar in Radio object
|
element.TKIntVar = RadVar # store the RadVar in Radio object
|
||||||
if default_value: # if this radio is the one selected, set RadVar to match
|
if default_value: # if this radio is the one selected, set RadVar to match
|
||||||
element.TKIntVar.set(value)
|
element.TKIntVar.set(value)
|
||||||
element.TKRadio = tk.Radiobutton(tk_row_frame, anchor=tk.NW, text=element.Text, width=width,
|
if element.ChangeSubmits:
|
||||||
variable=element.TKIntVar, value=value, bd=border_depth, font=font)
|
element.TKRadio = tk.Radiobutton(tk_row_frame, anchor=tk.NW, text=element.Text, width=width,
|
||||||
|
variable=element.TKIntVar, value=value, bd=border_depth, font=font,
|
||||||
|
command=element.RadioHandler)
|
||||||
|
else:
|
||||||
|
element.TKRadio = tk.Radiobutton(tk_row_frame, anchor=tk.NW, text=element.Text, width=width,
|
||||||
|
variable=element.TKIntVar, value=value, bd=border_depth, font=font)
|
||||||
if not element.BackgroundColor in (None, COLOR_SYSTEM_DEFAULT):
|
if not element.BackgroundColor in (None, COLOR_SYSTEM_DEFAULT):
|
||||||
element.TKRadio.configure(background=element.BackgroundColor)
|
element.TKRadio.configure(background=element.BackgroundColor)
|
||||||
element.TKRadio.configure(selectcolor=element.BackgroundColor)
|
element.TKRadio.configure(selectcolor=element.BackgroundColor)
|
||||||
|
@ -4643,7 +4690,16 @@ def StartupTK(my_flex_form):
|
||||||
|
|
||||||
# print('Starting TK open Windows = {}'.format(ow))
|
# print('Starting TK open Windows = {}'.format(ow))
|
||||||
if not ow and not my_flex_form.ForceTopLevel:
|
if not ow and not my_flex_form.ForceTopLevel:
|
||||||
root = tk.Tk()
|
# if first window being created, make a throwaway, hidden master root. This stops one user
|
||||||
|
# window from becoming the child of another user window. All windows are children of this
|
||||||
|
# hidden window
|
||||||
|
_my_windows.Increment()
|
||||||
|
_my_windows.hidden_master_root = tk.Tk()
|
||||||
|
_my_windows.hidden_master_root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint'
|
||||||
|
_my_windows.hidden_master_root.wm_overrideredirect(True)
|
||||||
|
|
||||||
|
# root = tk.Tk() # users windows are no longer using tk.Tk. They are all Toplevel windows
|
||||||
|
root = tk.Toplevel()
|
||||||
else:
|
else:
|
||||||
root = tk.Toplevel()
|
root = tk.Toplevel()
|
||||||
|
|
||||||
|
@ -5061,16 +5117,20 @@ _easy_print_data = None # global variable... I'm cheating
|
||||||
|
|
||||||
|
|
||||||
class DebugWin(object):
|
class DebugWin(object):
|
||||||
def __init__(self, size=(None, None)):
|
def __init__(self, size=(None, None), location=(None, None), font=None, no_titlebar=False, no_button=False, grab_anywhere=False, keep_on_top=False):
|
||||||
# Show a form that's a running counter
|
# Show a form that's a running counter
|
||||||
win_size = size if size != (None, None) else DEFAULT_DEBUG_WINDOW_SIZE
|
win_size = size if size != (None, None) else DEFAULT_DEBUG_WINDOW_SIZE
|
||||||
self.form = Window('Debug Window', auto_size_text=True, font=('Courier New', 12))
|
self.window = Window('Debug Window', no_titlebar=no_titlebar, auto_size_text=True, location=location, font=font or ('Courier New', 10), grab_anywhere=grab_anywhere, keep_on_top=keep_on_top)
|
||||||
self.output_element = Output(size=win_size)
|
self.output_element = Output(size=win_size)
|
||||||
self.form_rows = [[Text('EasyPrint Output')],
|
if no_button:
|
||||||
[self.output_element],
|
self.layout = [[self.output_element]]
|
||||||
[DummyButton('Quit')]]
|
else:
|
||||||
self.form.AddRows(self.form_rows)
|
self.layout = [
|
||||||
self.form.Show(non_blocking=True) # Show a ;non-blocking form, returns immediately
|
[self.output_element],
|
||||||
|
[DummyButton('Quit')]
|
||||||
|
]
|
||||||
|
self.window.AddRows(self.layout)
|
||||||
|
self.window.Read(timeout=0) # Show a non-blocking form, returns immediately
|
||||||
return
|
return
|
||||||
|
|
||||||
def Print(self, *args, **_3to2kwargs):
|
def Print(self, *args, **_3to2kwargs):
|
||||||
|
@ -5080,45 +5140,43 @@ class DebugWin(object):
|
||||||
else: end = None
|
else: end = None
|
||||||
sepchar = sep if sep is not None else ' '
|
sepchar = sep if sep is not None else ' '
|
||||||
endchar = end if end is not None else '\n'
|
endchar = end if end is not None else '\n'
|
||||||
|
|
||||||
|
if self.window is None: # if window was destroyed already, just print
|
||||||
|
print(*args, sep=sepchar, end=endchar)
|
||||||
|
return
|
||||||
|
|
||||||
|
event, values = self.window.Read(timeout=0)
|
||||||
|
if event == 'Quit' or event is None:
|
||||||
|
self.Close()
|
||||||
print(*args, sep=sepchar, end=endchar)
|
print(*args, sep=sepchar, end=endchar)
|
||||||
# for a in args:
|
# Add extra check to see if the window was closed... if closed by X sometimes am not told
|
||||||
# msg = str(a)
|
try:
|
||||||
# print(msg, end="", sep=sepchar)
|
state = self.window.TKroot.state()
|
||||||
# print(1, 2, 3, sep='-')
|
except:
|
||||||
# if end is None:
|
self.Close()
|
||||||
# print("")
|
|
||||||
self.form.ReadNonBlocking()
|
|
||||||
|
|
||||||
def Close(self):
|
def Close(self):
|
||||||
self.form.CloseNonBlockingForm()
|
self.window.Close()
|
||||||
self.form.__del__()
|
self.window.__del__()
|
||||||
|
self.window = None
|
||||||
|
|
||||||
def Print(*args, **_3to2kwargs):
|
|
||||||
if 'sep' in _3to2kwargs: sep = _3to2kwargs['sep']; del _3to2kwargs['sep']
|
|
||||||
else: sep = None
|
|
||||||
if 'end' in _3to2kwargs: end = _3to2kwargs['end']; del _3to2kwargs['end']
|
|
||||||
else: end = None
|
|
||||||
if 'size' in _3to2kwargs: size = _3to2kwargs['size']; del _3to2kwargs['size']
|
|
||||||
else: size = (None, None)
|
|
||||||
EasyPrint(*args, size=size, end=end, sep=sep)
|
|
||||||
|
|
||||||
|
|
||||||
def PrintClose():
|
def PrintClose():
|
||||||
EasyPrintClose()
|
EasyPrintClose()
|
||||||
|
|
||||||
|
|
||||||
def eprint(*args, **_3to2kwargs):
|
|
||||||
if 'sep' in _3to2kwargs: sep = _3to2kwargs['sep']; del _3to2kwargs['sep']
|
|
||||||
else: sep = None
|
|
||||||
if 'end' in _3to2kwargs: end = _3to2kwargs['end']; del _3to2kwargs['end']
|
|
||||||
else: end = None
|
|
||||||
if 'size' in _3to2kwargs: size = _3to2kwargs['size']; del _3to2kwargs['size']
|
|
||||||
else: size = (None, None)
|
|
||||||
EasyPrint(*args, size=size, end=end, sep=sep)
|
|
||||||
|
|
||||||
|
|
||||||
def EasyPrint(*args, **_3to2kwargs):
|
def EasyPrint(*args, **_3to2kwargs):
|
||||||
|
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_button' in _3to2kwargs: no_button = _3to2kwargs['no_button']; del _3to2kwargs['no_button']
|
||||||
|
else: no_button = 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 'location' in _3to2kwargs: location = _3to2kwargs['location']; del _3to2kwargs['location']
|
||||||
|
else: location = (None, None)
|
||||||
if 'sep' in _3to2kwargs: sep = _3to2kwargs['sep']; del _3to2kwargs['sep']
|
if 'sep' in _3to2kwargs: sep = _3to2kwargs['sep']; del _3to2kwargs['sep']
|
||||||
else: sep = None
|
else: sep = None
|
||||||
if 'end' in _3to2kwargs: end = _3to2kwargs['end']; del _3to2kwargs['end']
|
if 'end' in _3to2kwargs: end = _3to2kwargs['end']; del _3to2kwargs['end']
|
||||||
|
@ -5128,30 +5186,18 @@ def EasyPrint(*args, **_3to2kwargs):
|
||||||
global _easy_print_data
|
global _easy_print_data
|
||||||
|
|
||||||
if _easy_print_data is None:
|
if _easy_print_data is None:
|
||||||
_easy_print_data = DebugWin(size=size)
|
_easy_print_data = DebugWin(size=size, location=location, font=font, no_titlebar=no_titlebar, no_button=no_button, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top)
|
||||||
_easy_print_data.Print(*args, end=end, sep=sep)
|
_easy_print_data.Print(*args, end=end, sep=sep)
|
||||||
|
|
||||||
|
Print = EasyPrint
|
||||||
def EasyPrintold(*args, **_3to2kwargs):
|
eprint = EasyPrint
|
||||||
if 'sep' in _3to2kwargs: sep = _3to2kwargs['sep']; del _3to2kwargs['sep']
|
|
||||||
else: sep = None
|
|
||||||
if 'end' in _3to2kwargs: end = _3to2kwargs['end']; del _3to2kwargs['end']
|
|
||||||
else: end = None
|
|
||||||
if 'size' in _3to2kwargs: size = _3to2kwargs['size']; del _3to2kwargs['size']
|
|
||||||
else: size = (None, None)
|
|
||||||
if 'easy_print_data' not in EasyPrint.__dict__: # use a function property to save DebugWin object (static variable)
|
|
||||||
EasyPrint.easy_print_data = DebugWin(size=size)
|
|
||||||
if EasyPrint.easy_print_data is None:
|
|
||||||
EasyPrint.easy_print_data = DebugWin(size=size)
|
|
||||||
EasyPrint.easy_print_data.Print(*args, end=end, sep=sep)
|
|
||||||
|
|
||||||
|
|
||||||
def EasyPrintClose():
|
def EasyPrintClose():
|
||||||
if 'easy_print_data' in EasyPrint.__dict__:
|
global _easy_print_data
|
||||||
if EasyPrint.easy_print_data is not None:
|
if _easy_print_data is not None:
|
||||||
EasyPrint.easy_print_data._Close()
|
_easy_print_data.Close()
|
||||||
EasyPrint.easy_print_data = None
|
_easy_print_data = None
|
||||||
# del EasyPrint.easy_print_data
|
|
||||||
|
|
||||||
|
|
||||||
# ======================== Scrolled Text Box =====#
|
# ======================== Scrolled Text Box =====#
|
||||||
|
@ -5825,7 +5871,7 @@ def Popup(*args, **_3to2kwargs):
|
||||||
pad=((20, 0), 3)))
|
pad=((20, 0), 3)))
|
||||||
|
|
||||||
if non_blocking:
|
if non_blocking:
|
||||||
button, values = window.ReadNonBlocking()
|
button, values = window.Read(timeout=0)
|
||||||
else:
|
else:
|
||||||
button, values = window.Read()
|
button, values = window.Read()
|
||||||
|
|
||||||
|
@ -5972,7 +6018,7 @@ def PopupQuick(*args, **_3to2kwargs):
|
||||||
if 'non_blocking' in _3to2kwargs: non_blocking = _3to2kwargs['non_blocking']; del _3to2kwargs['non_blocking']
|
if 'non_blocking' in _3to2kwargs: non_blocking = _3to2kwargs['non_blocking']; del _3to2kwargs['non_blocking']
|
||||||
else: non_blocking = True
|
else: non_blocking = True
|
||||||
if 'auto_close_duration' in _3to2kwargs: auto_close_duration = _3to2kwargs['auto_close_duration']; del _3to2kwargs['auto_close_duration']
|
if 'auto_close_duration' in _3to2kwargs: auto_close_duration = _3to2kwargs['auto_close_duration']; del _3to2kwargs['auto_close_duration']
|
||||||
else: auto_close_duration = 1
|
else: auto_close_duration = 2
|
||||||
if 'auto_close' in _3to2kwargs: auto_close = _3to2kwargs['auto_close']; del _3to2kwargs['auto_close']
|
if 'auto_close' in _3to2kwargs: auto_close = _3to2kwargs['auto_close']; del _3to2kwargs['auto_close']
|
||||||
else: auto_close = True
|
else: auto_close = True
|
||||||
if 'text_color' in _3to2kwargs: text_color = _3to2kwargs['text_color']; del _3to2kwargs['text_color']
|
if 'text_color' in _3to2kwargs: text_color = _3to2kwargs['text_color']; del _3to2kwargs['text_color']
|
||||||
|
@ -6009,6 +6055,62 @@ def PopupQuick(*args, **_3to2kwargs):
|
||||||
font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
|
font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location)
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------- PopupQuick - a NonBlocking, Self-closing Popup with no titlebar and no buttons ---------------------------
|
||||||
|
def PopupQuickMessage(*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 = True
|
||||||
|
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 = 2
|
||||||
|
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_NO_BUTTONS
|
||||||
|
"""
|
||||||
|
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 ---------------------------
|
# --------------------------- PopupNoTitlebar ---------------------------
|
||||||
def PopupNoTitlebar(*args, **_3to2kwargs):
|
def PopupNoTitlebar(*args, **_3to2kwargs):
|
||||||
if 'location' in _3to2kwargs: location = _3to2kwargs['location']; del _3to2kwargs['location']
|
if 'location' in _3to2kwargs: location = _3to2kwargs['location']; del _3to2kwargs['location']
|
||||||
|
@ -6395,7 +6497,7 @@ def PopupYesNo(*args, **_3to2kwargs):
|
||||||
|
|
||||||
def PopupGetFolder(message, default_path='', no_window=False, size=(None, None), button_color=None,
|
def PopupGetFolder(message, default_path='', no_window=False, size=(None, None), button_color=None,
|
||||||
background_color=None, text_color=None, icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False,
|
background_color=None, text_color=None, icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False,
|
||||||
grab_anywhere=False, keep_on_top=False, location=(None, None)):
|
grab_anywhere=False, keep_on_top=False, location=(None, None), initial_folder=None):
|
||||||
"""
|
"""
|
||||||
Display popup with text entry field and browse button. Browse for folder
|
Display popup with text entry field and browse button. Browse for folder
|
||||||
:param message:
|
:param message:
|
||||||
|
@ -6413,8 +6515,14 @@ def PopupGetFolder(message, default_path='', no_window=False, size=(None, None),
|
||||||
:param location:
|
:param location:
|
||||||
:return: Contents of text field. None if closed using X or cancelled
|
:return: Contents of text field. None if closed using X or cancelled
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
global _my_windows
|
||||||
|
|
||||||
if no_window:
|
if no_window:
|
||||||
root = tk.Tk()
|
if _my_windows.NumOpenWindows:
|
||||||
|
root = tk.Toplevel()
|
||||||
|
else:
|
||||||
|
root = tk.Tk()
|
||||||
try:
|
try:
|
||||||
root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint'
|
root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint'
|
||||||
except:
|
except:
|
||||||
|
@ -6424,7 +6532,7 @@ def PopupGetFolder(message, default_path='', no_window=False, size=(None, None),
|
||||||
return folder_name
|
return folder_name
|
||||||
|
|
||||||
layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)],
|
layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)],
|
||||||
[InputText(default_text=default_path, size=size), FolderBrowse()],
|
[InputText(default_text=default_path, size=size), FolderBrowse(initial_folder=initial_folder)],
|
||||||
[CloseButton('Ok', size=(5, 1), bind_return_key=True), CloseButton('Cancel', size=(5, 1))]]
|
[CloseButton('Ok', size=(5, 1), bind_return_key=True), CloseButton('Cancel', size=(5, 1))]]
|
||||||
|
|
||||||
window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color,
|
window = Window(title=message, icon=icon, auto_size_text=True, button_color=button_color,
|
||||||
|
@ -6446,7 +6554,7 @@ def PopupGetFolder(message, default_path='', no_window=False, size=(None, None),
|
||||||
def PopupGetFile(message, default_path='', default_extension='', save_as=False, file_types=(("ALL Files", "*.*"),),
|
def PopupGetFile(message, default_path='', default_extension='', save_as=False, file_types=(("ALL Files", "*.*"),),
|
||||||
no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None,
|
no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None,
|
||||||
icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False,
|
icon=DEFAULT_WINDOW_ICON, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False,
|
||||||
location=(None, None)):
|
location=(None, None), initial_folder=None):
|
||||||
"""
|
"""
|
||||||
Display popup with text entry field and browse button. Browse for file
|
Display popup with text entry field and browse button. Browse for file
|
||||||
:param message:
|
:param message:
|
||||||
|
@ -6467,8 +6575,14 @@ def PopupGetFile(message, default_path='', default_extension='', save_as=False,
|
||||||
:param location:
|
:param location:
|
||||||
:return: string representing the path chosen, None if cancelled or window closed with X
|
:return: string representing the path chosen, None if cancelled or window closed with X
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
global _my_windows
|
||||||
|
|
||||||
if no_window:
|
if no_window:
|
||||||
root = tk.Tk()
|
if _my_windows.NumOpenWindows:
|
||||||
|
root = tk.Toplevel()
|
||||||
|
else:
|
||||||
|
root = tk.Tk()
|
||||||
try:
|
try:
|
||||||
root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint'
|
root.attributes('-alpha', 0) # hide window while building it. makes for smoother 'paint'
|
||||||
except:
|
except:
|
||||||
|
@ -6482,7 +6596,7 @@ def PopupGetFile(message, default_path='', default_extension='', save_as=False,
|
||||||
root.destroy()
|
root.destroy()
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
browse_button = SaveAs(file_types=file_types) if save_as else FileBrowse(file_types=file_types)
|
browse_button = SaveAs(file_types=file_types, initial_folder=initial_folder) if save_as else FileBrowse(file_types=file_types, initial_folder=initial_folder)
|
||||||
|
|
||||||
layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)],
|
layout = [[Text(message, auto_size_text=True, text_color=text_color, background_color=background_color)],
|
||||||
[InputText(default_text=default_path, size=size), browse_button],
|
[InputText(default_text=default_path, size=size), browse_button],
|
||||||
|
|
|
@ -24,9 +24,9 @@
|
||||||
|
|
||||||
## Now supports both Python 2.7 & 3
|
## Now supports both Python 2.7 & 3
|
||||||
|
|
||||||
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.13.0-red.svg?longCache=true&style=for-the-badge)
|
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.14.0-red.svg?longCache=true&style=for-the-badge)
|
||||||
|
|
||||||
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.13.0-blue.svg?longCache=true&style=for-the-badge)
|
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.14.0-blue.svg?longCache=true&style=for-the-badge)
|
||||||
|
|
||||||
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
|
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
|
||||||
|
|
||||||
|
@ -3569,6 +3569,8 @@ A MikeTheWatchGuy production... entirely responsible for this code.... unless it
|
||||||
| 3.11.0 & 1.11.0 | Oct 28, 2018
|
| 3.11.0 & 1.11.0 | Oct 28, 2018
|
||||||
| 3.12.0 & 1.12.0 | Oct 28, 2018
|
| 3.12.0 & 1.12.0 | Oct 28, 2018
|
||||||
| 3.13.0 & 1.13.0 | Oct 29, 2018
|
| 3.13.0 & 1.13.0 | Oct 29, 2018
|
||||||
|
| 3.14.0 & 1.14.0 | Nov 2, 2018
|
||||||
|
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
2.3 - Sliders, Listbox's and Image elements (oh my!)
|
2.3 - Sliders, Listbox's and Image elements (oh my!)
|
||||||
|
@ -3797,7 +3799,7 @@ Emergency patch release... going out same day as previous release
|
||||||
* Progress meter uses new CloseButton
|
* Progress meter uses new CloseButton
|
||||||
* Popups use new CloseButton
|
* Popups use new CloseButton
|
||||||
|
|
||||||
## 3.13.0 & 1.13.0
|
### 3.13.0 & 1.13.0
|
||||||
* Improved multiple window handling of Popups when the X is used to close
|
* Improved multiple window handling of Popups when the X is used to close
|
||||||
* Change submits added for:
|
* Change submits added for:
|
||||||
* Multiline
|
* Multiline
|
||||||
|
@ -3809,6 +3811,39 @@ Emergency patch release... going out same day as previous release
|
||||||
* Scroll bars for Trees
|
* Scroll bars for Trees
|
||||||
|
|
||||||
|
|
||||||
|
### 3.14.0 & 1.14.0
|
||||||
|
|
||||||
|
- More windowing changes...
|
||||||
|
using a hidden root windowing (Tk())
|
||||||
|
all children are Toplevel() windows
|
||||||
|
Read only setting for:
|
||||||
|
Input Text
|
||||||
|
Multiline
|
||||||
|
Font setting for InputCombo, Multiline
|
||||||
|
change_submits settinf for Radio Element
|
||||||
|
SetFocus for multiline, input elements
|
||||||
|
Default mon, day, year for calendar chooser button
|
||||||
|
Tree element update, added ability to change a single key
|
||||||
|
Message parm removed from ReadNonBlocking
|
||||||
|
Fix for closing windows using X
|
||||||
|
CurrentLocation method for Windows
|
||||||
|
Debug Window options
|
||||||
|
location
|
||||||
|
font
|
||||||
|
no_button
|
||||||
|
no_titlebar
|
||||||
|
grab_anywhere
|
||||||
|
keep_on_top
|
||||||
|
New Print / EasyPrint options
|
||||||
|
location
|
||||||
|
font
|
||||||
|
no_button
|
||||||
|
no_titlebar
|
||||||
|
grab_anywhere
|
||||||
|
keep_on_top
|
||||||
|
New popup, PopupQuickMessage
|
||||||
|
PopupGetFolder, PopupGetFile new initial_folder parm
|
||||||
|
|
||||||
### Upcoming
|
### Upcoming
|
||||||
Make suggestions people! Future release features
|
Make suggestions people! Future release features
|
||||||
|
|
||||||
|
@ -3885,6 +3920,8 @@ GNU Lesser General Public License (LGPL 3) +
|
||||||
* 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.
|
* 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.
|
||||||
* [spectre6000](https://github.com/spectre6000) - Readme updates
|
* [spectre6000](https://github.com/spectre6000) - Readme updates
|
||||||
* [jackyOO7](https://github.com/jackyOO7) - Demo programs. OpenCV with realtime image processing, popup keyboard, input Combo read only option.
|
* [jackyOO7](https://github.com/jackyOO7) - Demo programs. OpenCV with realtime image processing, popup keyboard, input Combo read only option.
|
||||||
|
* [AltoRetrato](https://github.com/AltoRetrato) - Fonts for multiline and combo
|
||||||
|
|
||||||
|
|
||||||
## How Do I
|
## How Do I
|
||||||
Finally, I must thank the fine folks at How Do I.
|
Finally, I must thank the fine folks at How Do I.
|
||||||
|
|
43
readme.md
43
readme.md
|
@ -24,9 +24,9 @@
|
||||||
|
|
||||||
## Now supports both Python 2.7 & 3
|
## Now supports both Python 2.7 & 3
|
||||||
|
|
||||||
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.13.0-red.svg?longCache=true&style=for-the-badge)
|
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_3.x_Version-3.14.0-red.svg?longCache=true&style=for-the-badge)
|
||||||
|
|
||||||
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.13.0-blue.svg?longCache=true&style=for-the-badge)
|
![Python Version](https://img.shields.io/badge/PySimpleGUI_For_Python_2.7_Version-1.14.0-blue.svg?longCache=true&style=for-the-badge)
|
||||||
|
|
||||||
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
|
[Announcements of Latest Developments](https://github.com/MikeTheWatchGuy/PySimpleGUI/issues/142)
|
||||||
|
|
||||||
|
@ -3569,6 +3569,8 @@ A MikeTheWatchGuy production... entirely responsible for this code.... unless it
|
||||||
| 3.11.0 & 1.11.0 | Oct 28, 2018
|
| 3.11.0 & 1.11.0 | Oct 28, 2018
|
||||||
| 3.12.0 & 1.12.0 | Oct 28, 2018
|
| 3.12.0 & 1.12.0 | Oct 28, 2018
|
||||||
| 3.13.0 & 1.13.0 | Oct 29, 2018
|
| 3.13.0 & 1.13.0 | Oct 29, 2018
|
||||||
|
| 3.14.0 & 1.14.0 | Nov 2, 2018
|
||||||
|
|
||||||
|
|
||||||
## Release Notes
|
## Release Notes
|
||||||
2.3 - Sliders, Listbox's and Image elements (oh my!)
|
2.3 - Sliders, Listbox's and Image elements (oh my!)
|
||||||
|
@ -3797,7 +3799,7 @@ Emergency patch release... going out same day as previous release
|
||||||
* Progress meter uses new CloseButton
|
* Progress meter uses new CloseButton
|
||||||
* Popups use new CloseButton
|
* Popups use new CloseButton
|
||||||
|
|
||||||
## 3.13.0 & 1.13.0
|
### 3.13.0 & 1.13.0
|
||||||
* Improved multiple window handling of Popups when the X is used to close
|
* Improved multiple window handling of Popups when the X is used to close
|
||||||
* Change submits added for:
|
* Change submits added for:
|
||||||
* Multiline
|
* Multiline
|
||||||
|
@ -3809,6 +3811,39 @@ Emergency patch release... going out same day as previous release
|
||||||
* Scroll bars for Trees
|
* Scroll bars for Trees
|
||||||
|
|
||||||
|
|
||||||
|
### 3.14.0 & 1.14.0
|
||||||
|
|
||||||
|
- More windowing changes...
|
||||||
|
using a hidden root windowing (Tk())
|
||||||
|
all children are Toplevel() windows
|
||||||
|
Read only setting for:
|
||||||
|
Input Text
|
||||||
|
Multiline
|
||||||
|
Font setting for InputCombo, Multiline
|
||||||
|
change_submits settinf for Radio Element
|
||||||
|
SetFocus for multiline, input elements
|
||||||
|
Default mon, day, year for calendar chooser button
|
||||||
|
Tree element update, added ability to change a single key
|
||||||
|
Message parm removed from ReadNonBlocking
|
||||||
|
Fix for closing windows using X
|
||||||
|
CurrentLocation method for Windows
|
||||||
|
Debug Window options
|
||||||
|
location
|
||||||
|
font
|
||||||
|
no_button
|
||||||
|
no_titlebar
|
||||||
|
grab_anywhere
|
||||||
|
keep_on_top
|
||||||
|
New Print / EasyPrint options
|
||||||
|
location
|
||||||
|
font
|
||||||
|
no_button
|
||||||
|
no_titlebar
|
||||||
|
grab_anywhere
|
||||||
|
keep_on_top
|
||||||
|
New popup, PopupQuickMessage
|
||||||
|
PopupGetFolder, PopupGetFile new initial_folder parm
|
||||||
|
|
||||||
### Upcoming
|
### Upcoming
|
||||||
Make suggestions people! Future release features
|
Make suggestions people! Future release features
|
||||||
|
|
||||||
|
@ -3885,6 +3920,8 @@ GNU Lesser General Public License (LGPL 3) +
|
||||||
* 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.
|
* 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.
|
||||||
* [spectre6000](https://github.com/spectre6000) - Readme updates
|
* [spectre6000](https://github.com/spectre6000) - Readme updates
|
||||||
* [jackyOO7](https://github.com/jackyOO7) - Demo programs. OpenCV with realtime image processing, popup keyboard, input Combo read only option.
|
* [jackyOO7](https://github.com/jackyOO7) - Demo programs. OpenCV with realtime image processing, popup keyboard, input Combo read only option.
|
||||||
|
* [AltoRetrato](https://github.com/AltoRetrato) - Fonts for multiline and combo
|
||||||
|
|
||||||
|
|
||||||
## How Do I
|
## How Do I
|
||||||
Finally, I must thank the fine folks at How Do I.
|
Finally, I must thank the fine folks at How Do I.
|
||||||
|
|
Loading…
Reference in New Issue