Release 3.22.0
This commit is contained in:
parent
f49bf1b570
commit
c4ba6f35b1
|
@ -17,6 +17,7 @@ else:
|
|||
|
||||
import types
|
||||
import datetime
|
||||
import time
|
||||
import textwrap
|
||||
import pickle
|
||||
import calendar
|
||||
|
@ -26,7 +27,6 @@ g_time_start = 0
|
|||
g_time_end = 0
|
||||
g_time_delta = 0
|
||||
|
||||
import time
|
||||
|
||||
|
||||
def TimerStart():
|
||||
|
@ -3309,7 +3309,7 @@ class TreeData(object):
|
|||
|
||||
def __init__(self):
|
||||
self.tree_dict = {}
|
||||
self.root_node = self.Node("", "", 'root', [])
|
||||
self.root_node = self.Node("", "", 'root', [], None)
|
||||
self.tree_dict[""] = self.root_node
|
||||
|
||||
def _AddNode(self, key, node):
|
||||
|
@ -3749,7 +3749,7 @@ class Window:
|
|||
FillFormWithValues(self, values_dict)
|
||||
return self
|
||||
|
||||
def FindElement(self, key, silent_on_error=None):
|
||||
def FindElement(self, key, silent_on_error=False):
|
||||
element = _FindElementFromKeyInSubForm(self, key)
|
||||
if element is None:
|
||||
if not silent_on_error:
|
||||
|
@ -5039,8 +5039,9 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form:Window):
|
|||
# print(style_name)
|
||||
combostyle = ttk.Style()
|
||||
|
||||
unique_field = str(time.time()).replace('.','') + '.TCombobox.field'
|
||||
# Creates a unique name for each field element(Sure there is a better way to do this)
|
||||
unique_field = str(datetime.datetime.today().timestamp()).replace('.','') + '.TCombobox.field'
|
||||
# unique_field = str(datetime.datetime.today().timestamp()).replace('.','') + '.TCombobox.field'
|
||||
# unique_field = str(randint(1,50000000)) + '.TCombobox.field'
|
||||
|
||||
# print(unique_field)
|
||||
|
@ -5718,7 +5719,6 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form:Window):
|
|||
except:
|
||||
width = element.DefaultColumnWidth
|
||||
treeview.column(heading, width=width * CharWidthInPixels(), anchor=anchor)
|
||||
|
||||
def add_treeview_data(node):
|
||||
# print(f'Inserting {node.key} under parent {node.parent}')
|
||||
if node.key != '':
|
||||
|
@ -5728,8 +5728,6 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form:Window):
|
|||
else:
|
||||
photo = tk.PhotoImage(file=node.icon)
|
||||
node.photo = photo
|
||||
# except:
|
||||
# self.photo = None
|
||||
treeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values, open=element.ShowExpanded, image=node.photo)
|
||||
else:
|
||||
treeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values, open=element.ShowExpanded)
|
||||
|
|
327
PySimpleGUI27.py
327
PySimpleGUI27.py
|
@ -29,15 +29,16 @@ else:
|
|||
|
||||
import types
|
||||
import datetime
|
||||
import time
|
||||
import textwrap
|
||||
import pickle
|
||||
import calendar
|
||||
from random import randint
|
||||
|
||||
g_time_start = 0
|
||||
g_time_end = 0
|
||||
g_time_delta = 0
|
||||
|
||||
import time
|
||||
|
||||
|
||||
def TimerStart():
|
||||
|
@ -73,8 +74,9 @@ def TimerStop():
|
|||
|
||||
# ----====----====----==== Constants the user CAN safely change ====----====----====----#
|
||||
|
||||
# Base64 encoded GIF file
|
||||
DEFAULT_BASE64_ICON = b'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'
|
||||
|
||||
DEFAULT_BASE64_ICON = b'iVBORw0KGgoAAAANSUhEUgAAACEAAAAgCAMAAACrZuH4AAAABGdBTUEAALGPC/xhBQAAAwBQTFRFAAAAMGmYMGqZMWqaMmubMmycM22dNGuZNm2bNm6bNG2dN26cNG6dNG6eNW+fN3CfOHCeOXGfNXCgNnGhN3KiOHOjOXSjOHSkOnWmOnamOnanPHSiPXakPnalO3eoPnimO3ioPHioPHmpPHmqPXqqPnurPnusPnytP3yuQHimQnurQn2sQH2uQX6uQH6vR32qRn+sSXujSHynTH2mTn+nSX6pQH6wTIGsTYKuTYSvQoCxQoCyRIK0R4S1RYS2Roa4SIe4SIe6SIi7Soq7SYm8SYq8Sou+TY2/UYStUYWvVIWtUYeyVoewUIi0VIizUI6+Vo+8WImxXJG5YI2xZI+xZ5CzZJC0ZpG1b5a3apW4aZm/cZi4dJ2/eJ69fJ+9XZfEZZnCZJzHaZ/Jdp/AeKTI/tM8/9Q7/9Q8/9Q9/9Q+/tQ//9VA/9ZA/9ZB/9ZC/9dD/9ZE/tdJ/9dK/9hF/9hG/9hH/9hI/9hJ/9hK/9lL/9pK/9pL/thO/9pM/9pN/9tO/9tP/9xP/tpR/9xQ/9xR/9xS/9xT/91U/91V/t1W/95W/95X/95Y/95Z/99a/99b/txf/txh/txk/t5l/t1q/t5v/+Bb/+Bc/+Bd/+Be/+Bf/+Bg/+Fh/+Fi/+Jh/+Ji/uJk/uJl/+Jm/+Rm/uJo/+Ro/+Rr/+Zr/+Vs/+Vu/+Zs/+Zu/uF0/uVw/+dw/+dz/+d2/uB5/uB6/uJ9/uR7/uR+/uV//+hx/+hy/+h0/+h2/+l4/+l7/+h8gKXDg6vLgazOhKzMiqrEj6/KhK/Qka/Hk7HJlLHJlLPMmLTLmbbOkLXSmLvXn77XoLrPpr/Tn8DaocLdpcHYrcjdssfZus/g/uOC/uOH/uaB/uWE/uaF/uWK/+qA/uqH/uqI/uuN/uyM/ueS/ueW/ueY/umQ/uqQ/uuS/uuW/uyU/uyX/uqa/uue/uye/uyf/u6f/uyq/u+r/u+t/vCm/vCp/vCu/vCy/vC2/vK2/vO8/vO/wtTjwtXlzdrl/vTA/vPQAAAAiNpY5gAAAQB0Uk5T////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AFP3ByUAAAAJcEhZcwAAFw8AABcPASe7rwsAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAKUSURBVDhPhdB3WE1xHMdxt5JV0dANoUiyd8kqkey996xclUuTlEKidO3qVnTbhIyMW/bee5NskjJLmR/f3++cK/94vP76Ps/n/Zx7z6mE/6koJowcK154vvHOL/GsKCZXkUgkWlf4vWGWq5tsDz+JWIzSokAiqXGe7nWu3HxhEYof7fhOqp1GtptQuMruVhQdxZ05U5G47tYUHbQ4oah6Fg9Z4ubm7i57JhQjdHS0RSzUPoG17u6zZTKZh8c8XlytqW9YWUOH1LqFOZ6enl5ec+XybFb0rweM1tPTM6yuq6vLs0lYJJfLvb19fHwDWGF0jh5lYNAe4/QFemOwxtfXz8/fPyBgwVMqzAcCF4ybAZ2MRCexJGBhYGBQUHDw4u1UHDG1G2ZqB/Q1MTHmzAE+kpCwL1RghlTaBt/6SaXS2kx9YH1IaOjSZST8vfA9JtoDnSngGgL7wkg4WVkofA9mcF1Sx8zMzBK4v3wFiYiMVLxlEy9u21syFhYNmgN7IyJXEYViNZvEYoCVVWOmUVvgQVSUQqGIjolRFvOAFd8HWVs34VoA+6OjY2JjY5Vxm4BC1UuhGG5jY9OUaQXci1MqlfHx8YmqjyhOViW9ZsUN29akJRmPFwkJCZsTSXIpilJffXiTzorLXYgtcxRJKpUqKTklJQ0oSt9FP/EonxVdNY4jla1kK4q2ZB6mIr+AipvduzFUzMSOtLT09IyMzMxtJKug/F0u/6dTexAWDcXXLGEjapKjfsILOLKEuYiSnTQeYCt3UHhbwEHjGMrETfBJU5zq5dSTcXC8hLJccSWP2cgLXHPu7cQNAcpyxF1dyjehAKb0cSYUAOXCUw6V8OFPgevTXFymC+fPPLU677Nw/1X8A/AbfAKGulaqFlIAAAAASUVORK5CYII='
|
||||
if sys.version_info[0] >= 3:
|
||||
DEFAULT_WINDOW_ICON = DEFAULT_BASE64_ICON
|
||||
else:
|
||||
|
@ -369,7 +371,7 @@ class Element(object):
|
|||
self.TKEntry = None
|
||||
self.TKImage = None
|
||||
|
||||
self.ParentForm = None
|
||||
self.ParentForm = None # type: Window
|
||||
self.ParentContainer = None # will be a Form, Column, or Frame element
|
||||
self.TextInputDefault = None
|
||||
self.Position = (0, 0) # Default position Row 0, Col 0
|
||||
|
@ -379,7 +381,7 @@ class Element(object):
|
|||
self.Tooltip = tooltip
|
||||
self.TooltipObject = None
|
||||
self.Visible = visible
|
||||
|
||||
self.TKRightClickMenu = None
|
||||
|
||||
def RightClickMenuCallback(self, event):
|
||||
self.TKRightClickMenu.tk_popup(event.x_root, event.y_root, 0)
|
||||
|
@ -1414,9 +1416,9 @@ class Output(Element):
|
|||
self._TKOut.output.delete('1.0', tk.END)
|
||||
self._TKOut.output.insert(tk.END, value)
|
||||
if visible is False:
|
||||
self._TKOut.pack_forget()
|
||||
self._TKOut.frame.pack_forget()
|
||||
elif visible is True:
|
||||
self._TKOut.pack()
|
||||
self._TKOut.frame.pack()
|
||||
|
||||
def __del__(self):
|
||||
try:
|
||||
|
@ -1649,10 +1651,15 @@ class Button(Element):
|
|||
self.TKButton.image = image
|
||||
if image_filename is not None:
|
||||
self.TKButton.config(highlightthickness=0)
|
||||
photo = tk.PhotoImage(file=image_filename)
|
||||
width, height = photo.width(), photo.height()
|
||||
self.TKButton.config(image=photo, width=width, height=height)
|
||||
self.TKButton.image = photo
|
||||
image = tk.PhotoImage(file=image_filename)
|
||||
if image_size is not None:
|
||||
width, height = image_size
|
||||
else:
|
||||
width, height = image.width(), image.height()
|
||||
if image_subsample:
|
||||
image = image.subsample(image_subsample)
|
||||
self.TKButton.config(image=image, width=width, height=height)
|
||||
self.TKButton.image = image
|
||||
if visible is False:
|
||||
self.TKButton.pack_forget()
|
||||
elif visible is True:
|
||||
|
@ -1721,6 +1728,7 @@ class ButtonMenu(Element):
|
|||
self.MenuItemChosen = None
|
||||
self.Tearoff = tearoff
|
||||
self.TKButtonMenu = None
|
||||
self.TKMenu = None
|
||||
# self.temp_size = size if size != (NONE, NONE) else
|
||||
|
||||
super().__init__(ELEM_TYPE_BUTTONMENU, size=size, font=font, pad=pad, key=key, tooltip=tooltip, text_color=self.TextColor, background_color=self.BackgroundColor, visible=visible)
|
||||
|
@ -1741,32 +1749,11 @@ class ButtonMenu(Element):
|
|||
if menu_definition is not None:
|
||||
self.TKMenu = tk.Menu(self.TKButtonMenu, tearoff=self.Tearoff) # create the menubar
|
||||
AddMenuItem(self.TKMenu, menu_definition[1], self)
|
||||
# for menu_entry in menu_definition:
|
||||
# # print(f'Adding a Menubar ENTRY {menu_entry}')
|
||||
# baritem = tk.Menu(menubar, tearoff=self.Tearoff)
|
||||
# pos = menu_entry[0].find('&')
|
||||
# # print(pos)
|
||||
# if pos != -1:
|
||||
# if pos == 0 or menu_entry[0][pos - 1] != "\\":
|
||||
# menu_entry[0] = menu_entry[0][:pos] + menu_entry[0][pos + 1:]
|
||||
# if menu_entry[0][0] == MENU_DISABLED_CHARACTER:
|
||||
# menubar.add_cascade(label=menu_entry[0][len(MENU_DISABLED_CHARACTER):], menu=baritem, underline=pos)
|
||||
# menubar.entryconfig(menu_entry[0][len(MENU_DISABLED_CHARACTER):], state='disabled')
|
||||
# else:
|
||||
# menubar.add_cascade(label=menu_entry[0], menu=baritem, underline=pos)
|
||||
#
|
||||
# if len(menu_entry) > 1:
|
||||
# AddMenuItem(baritem, menu_entry[1], self)
|
||||
self.TKButtonMenu.configure(menu=self.TKMenu)
|
||||
|
||||
def UpdateQt(self, menu_definition=None, text=None, button_color=(None, None), font=None, visible=None):
|
||||
if menu_definition is not None:
|
||||
menu_def = menu_definition
|
||||
qmenu = QMenu(self.QT_QPushButton)
|
||||
qmenu.setTitle(menu_def[0])
|
||||
AddMenuItem(qmenu, menu_def[1], self)
|
||||
self.QT_QPushButton.setMenu(qmenu)
|
||||
super().Update(self.QT_QPushButton, background_color=button_color[1], text_color=button_color[0], font=font, visible=visible)
|
||||
if visible is False:
|
||||
self.TKButtonMenu.pack_forget()
|
||||
elif visible is True:
|
||||
self.TKButtonMenu.pack()
|
||||
|
||||
|
||||
|
||||
|
@ -2548,6 +2535,30 @@ class Slider(Element):
|
|||
super().__del__()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# TkScrollableFrame (Used by Column) #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class TkFixedFrame(tk.Frame):
|
||||
def __init__(self, master, **kwargs):
|
||||
tk.Frame.__init__(self, master, **kwargs)
|
||||
|
||||
self.canvas = tk.Canvas(self)
|
||||
|
||||
self.canvas.pack(side="left", fill="both", expand=True)
|
||||
|
||||
# reset the view
|
||||
self.canvas.xview_moveto(0)
|
||||
self.canvas.yview_moveto(0)
|
||||
|
||||
# create a frame inside the canvas which will be scrolled with it
|
||||
self.TKFrame = tk.Frame(self.canvas, **kwargs)
|
||||
self.frame_id = self.canvas.create_window(0, 0, window=self.TKFrame, anchor="nw")
|
||||
self.canvas.config(borderwidth=0, highlightthickness=0)
|
||||
self.TKFrame.config(borderwidth=0, highlightthickness=0)
|
||||
self.config(borderwidth=0, highlightthickness=0)
|
||||
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------- #
|
||||
# TkScrollableFrame (Used by Column) #
|
||||
# ---------------------------------------------------------------------- #
|
||||
|
@ -3048,7 +3059,7 @@ MenuBar = Menu # another name for Menu to make it clear it's the Menu B
|
|||
# ---------------------------------------------------------------------- #
|
||||
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, num_rows=None, row_height=None, font=None, justification='right', text_color=None, background_color=None, alternating_row_color=None,
|
||||
auto_size_columns=True, max_col_width=20, select_mode=None, display_row_numbers=False, num_rows=None, row_height=None, font=None, justification='right', text_color=None, background_color=None, alternating_row_color=None, row_colors=None, vertical_scroll_only=True,
|
||||
size=(None, None), change_submits=False, enable_events=False, bind_return_key=False, pad=None, key=None, tooltip=None, right_click_menu=None, visible=True):
|
||||
'''
|
||||
Table
|
||||
|
@ -3095,12 +3106,14 @@ class Table(Element):
|
|||
self.RowHeight = row_height
|
||||
self.TKTreeview = None
|
||||
self.AlternatingRowColor = alternating_row_color
|
||||
self.VerticalScrollOnly = vertical_scroll_only
|
||||
self.SelectedRows = []
|
||||
self.ChangeSubmits = change_submits or enable_events
|
||||
self.BindReturnKey = bind_return_key
|
||||
self.StartingRowNumber = 0 # When displaying row numbers, where to start
|
||||
self.RowHeaderText = 'Row'
|
||||
self.RightClickMenu = right_click_menu
|
||||
self.RowColors = row_colors
|
||||
|
||||
super().__init__(ELEM_TYPE_TABLE, text_color=text_color, background_color=background_color, font=font,
|
||||
size=size, pad=pad, key=key, tooltip=tooltip, visible=visible)
|
||||
|
@ -3167,7 +3180,7 @@ class Table(Element):
|
|||
# ---------------------------------------------------------------------- #
|
||||
class Tree(Element):
|
||||
def __init__(self, data=None, headings=None, visible_column_map=None, col_widths=None, col0_width=10,
|
||||
def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, show_expanded=False, change_submits=False, enable_events=False, font=None, justification='right', text_color=None, background_color=None, num_rows=None, pad=None, key=None, tooltip=None,right_click_menu=None, visible=True):
|
||||
def_col_width=10, auto_size_columns=True, max_col_width=20, select_mode=None, show_expanded=False, change_submits=False, enable_events=False, font=None, justification='right', text_color=None, background_color=None, num_rows=None, row_height=None, pad=None, key=None, tooltip=None,right_click_menu=None, visible=True):
|
||||
'''
|
||||
Tree
|
||||
:param data:
|
||||
|
@ -3212,6 +3225,9 @@ class Tree(Element):
|
|||
self.SelectedRows = []
|
||||
self.ChangeSubmits = change_submits or enable_events
|
||||
self.RightClickMenu = right_click_menu
|
||||
self.RowHeight = row_height
|
||||
self.IconList = {}
|
||||
|
||||
|
||||
super().__init__(ELEM_TYPE_TREE, text_color=text_color, background_color=background_color, font=font, pad=pad,
|
||||
key=key, tooltip=tooltip, visible=visible)
|
||||
|
@ -3234,13 +3250,26 @@ class Tree(Element):
|
|||
def add_treeview_data(self, node):
|
||||
# print(f'Inserting {node.key} under parent {node.parent}')
|
||||
if node.key != '':
|
||||
self.TKTreeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values,
|
||||
open=self.ShowExpanded)
|
||||
if node.icon:
|
||||
try:
|
||||
if type(node.icon) is bytes:
|
||||
photo = tk.PhotoImage(data=node.icon)
|
||||
else:
|
||||
photo = tk.PhotoImage(file=node.icon)
|
||||
node.photo = photo
|
||||
self.TKTreeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values,
|
||||
open=self.ShowExpanded, image=node.photo)
|
||||
except:
|
||||
self.photo = None
|
||||
else:
|
||||
self.TKTreeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values,
|
||||
open=self.ShowExpanded)
|
||||
|
||||
for node in node.children:
|
||||
self.add_treeview_data(node)
|
||||
|
||||
|
||||
def Update(self, values=None, key=None, value=None, text=None, visible=None):
|
||||
def Update(self, values=None, key=None, value=None, text=None, icon=None, visible=None):
|
||||
if values is not None:
|
||||
children = self.TKTreeview.get_children()
|
||||
for i in children:
|
||||
|
@ -3256,6 +3285,16 @@ class Tree(Element):
|
|||
self.TKTreeview.item(key, values=value)
|
||||
if text is not None:
|
||||
self.TKTreeview.item(key, text=text)
|
||||
if icon is not None:
|
||||
try:
|
||||
if type(icon) is bytes:
|
||||
photo = tk.PhotoImage(data=icon)
|
||||
else:
|
||||
photo = tk.PhotoImage(file=icon)
|
||||
self.TKTreeview.item(key, image=photo)
|
||||
self.IconList[key] = photo # save so that it's not deleted (save reference)
|
||||
except:
|
||||
pass
|
||||
item = self.TKTreeview.item(key)
|
||||
if visible is False:
|
||||
self.TKTreeview.pack_forget()
|
||||
|
@ -3269,26 +3308,27 @@ class Tree(Element):
|
|||
|
||||
class TreeData(object):
|
||||
class Node(object):
|
||||
def __init__(self, parent, key, text, values):
|
||||
def __init__(self, parent, key, text, values, icon=None):
|
||||
self.parent = parent
|
||||
self.children = []
|
||||
self.key = key
|
||||
self.text = text
|
||||
self.values = values
|
||||
self.icon = icon
|
||||
|
||||
def _Add(self, node):
|
||||
self.children.append(node)
|
||||
|
||||
def __init__(self):
|
||||
self.tree_dict = {}
|
||||
self.root_node = self.Node("", "", 'root', [])
|
||||
self.root_node = self.Node("", "", 'root', [], None)
|
||||
self.tree_dict[""] = self.root_node
|
||||
|
||||
def _AddNode(self, key, node):
|
||||
self.tree_dict[key] = node
|
||||
|
||||
def Insert(self, parent, key, text, values):
|
||||
node = self.Node(parent, key, text, values)
|
||||
def Insert(self, parent, key, text, values, icon=None):
|
||||
node = self.Node(parent, key, text, values, icon)
|
||||
self.tree_dict[key] = node
|
||||
parent_node = self.tree_dict[parent]
|
||||
parent_node._Add(node)
|
||||
|
@ -3396,7 +3436,7 @@ class Window(object):
|
|||
self.Font = font if font else DEFAULT_FONT
|
||||
self.RadioDict = {}
|
||||
self.BorderDepth = border_depth
|
||||
self.WindowIcon = icon if icon is not None else Window.user_defined_icon
|
||||
self.WindowIcon = Window.user_defined_icon if Window.user_defined_icon is not None else icon if icon is not None else DEFAULT_WINDOW_ICON
|
||||
self.AutoClose = auto_close
|
||||
self.NonBlocking = False
|
||||
self.TKroot = None
|
||||
|
@ -3594,6 +3634,8 @@ class Window(object):
|
|||
# if the last button clicked was realtime, emulate a read non-blocking
|
||||
# the idea is to quickly return realtime buttons without any blocks until released
|
||||
if self.LastButtonClickedWasRealtime:
|
||||
self.LastButtonClickedWasRealtime = False # stops from generating events until something changes
|
||||
|
||||
# print(f'RTime down {self.LastButtonClicked}' )
|
||||
try:
|
||||
rc = self.TKroot.update()
|
||||
|
@ -3719,15 +3761,18 @@ class Window(object):
|
|||
FillFormWithValues(self, values_dict)
|
||||
return self
|
||||
|
||||
def FindElement(self, key):
|
||||
def FindElement(self, key, silent_on_error=False):
|
||||
element = _FindElementFromKeyInSubForm(self, key)
|
||||
if element is None:
|
||||
print('*** WARNING = FindElement did not find the key. Please check your key\'s spelling ***')
|
||||
PopupError('Keyword error in FindElement Call',
|
||||
'Bad key = {}'.format(key),
|
||||
'Your bad line of code may resemble this:',
|
||||
'window.FindElement("{}")'.format(key))
|
||||
return ErrorElement(key=key)
|
||||
if not silent_on_error:
|
||||
print('*** WARNING = FindElement did not find the key. Please check your key\'s spelling ***')
|
||||
PopupError('Keyword error in FindElement Call',
|
||||
'Bad key = {}'.format(key),
|
||||
'Your bad line of code may resemble this:',
|
||||
'window.FindElement("{}")'.format(key))
|
||||
return ErrorElement(key=key)
|
||||
else:
|
||||
return False
|
||||
return element
|
||||
|
||||
Element = FindElement # Shortcut function
|
||||
|
@ -4340,7 +4385,7 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
|||
value = 0
|
||||
elif element.Type == ELEM_TYPE_INPUT_SLIDER:
|
||||
try:
|
||||
value = element.TKIntVar.get()
|
||||
value = float(element.TKScale.get())
|
||||
except:
|
||||
value = 0
|
||||
elif element.Type == ELEM_TYPE_INPUT_MULTILINE:
|
||||
|
@ -4687,10 +4732,18 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
highlightthickness=0)
|
||||
element.TKColFrame.config(background=element.BackgroundColor, borderwidth=0, highlightthickness=0)
|
||||
else:
|
||||
element.TKColFrame = tk.Frame(tk_row_frame)
|
||||
if element.Size != (None, None):
|
||||
element.TKColFrame.configure(width=element.Size[0], height=element.Size[1])
|
||||
PackFormIntoFrame(element, element.TKColFrame, toplevel_form)
|
||||
element.TKColFrame = TkFixedFrame(tk_row_frame)
|
||||
PackFormIntoFrame(element, element.TKColFrame.TKFrame, toplevel_form)
|
||||
element.TKColFrame.TKFrame.update()
|
||||
if element.Size[1] is not None:
|
||||
element.TKColFrame.canvas.config(height=element.Size[1])
|
||||
elif element.Size[0] is not None:
|
||||
element.TKColFrame.canvas.config(width=element.Size[0])
|
||||
else:
|
||||
element.TKColFrame = tk.Frame(tk_row_frame)
|
||||
PackFormIntoFrame(element, element.TKColFrame, toplevel_form)
|
||||
|
||||
element.TKColFrame.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1], expand=True, fill='both')
|
||||
if element.Visible is False:
|
||||
element.TKColFrame.pack_forget()
|
||||
|
@ -4946,7 +4999,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
timeout=DEFAULT_TOOLTIP_TIME)
|
||||
|
||||
|
||||
# ------------------------- INPUT (Single Line) element ------------------------- #
|
||||
# ------------------------- INPUT element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_TEXT:
|
||||
default_text = element.DefaultText
|
||||
element.TKStringVar = tk.StringVar()
|
||||
|
@ -4983,7 +5036,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
AddMenuItem(top_menu, menu[1], element)
|
||||
element.TKRightClickMenu = top_menu
|
||||
element.TKEntry.bind('<Button-3>', element.RightClickMenuCallback)
|
||||
# ------------------------- COMBO BOX (Drop Down) element ------------------------- #
|
||||
# ------------------------- COMBOBOX element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_COMBO:
|
||||
max_line_len = max([len(str(l)) for l in element.Values])
|
||||
if auto_size_text is False:
|
||||
|
@ -4993,66 +5046,49 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKStringVar = tk.StringVar()
|
||||
style_name = 'TCombobox'
|
||||
if element.TextColor is not None and element.TextColor != COLOR_SYSTEM_DEFAULT:
|
||||
# print('Combo special style', element.TextColor, element.BackgroundColor)
|
||||
style_name = 'PSG.TCombobox'
|
||||
# Creates 1 style per Text Color/ Background Color combination
|
||||
style_name = element.TextColor + element.BackgroundColor + '.TCombobox'
|
||||
# print(style_name)
|
||||
combostyle = tkinter.ttk.Style()
|
||||
#
|
||||
# combostyle.map("C.TButton",
|
||||
# foreground=[('pressed', 'red'), ('active', 'blue')],
|
||||
# background=[('pressed', '!disabled', 'black'), ('active', 'white')]
|
||||
# )
|
||||
# combostyle.map('PSG.TCombobox', background=[('selected', 'green')])
|
||||
# combostyle.configure('PSG.TCombobox.Listbox',foreground='green')
|
||||
# combostyle.map('PSG.TCombobox', foreground=[('active','purple')])
|
||||
# combostyle.map('PSG.TCombobox.textarea', foreground=[('active','purple')])
|
||||
# combostyle.map('PSG.TCombobox.rightdownarrow', arrowcolor=[('active','purple')])
|
||||
# combostyle.configure('PSG.TCombobox.TEntry', background='red')
|
||||
# combostyle.configure('PSG.TCombobox', background=element.BackgroundColor)
|
||||
combostyle.configure('PSG.TCombobox', foreground=element.TextColor) # WORKS
|
||||
combostyle.configure('PSG.TCombobox', selectbackground='gray70') # WORKS
|
||||
combostyle.configure('PSG.TCombobox', selectforeground=element.TextColor) # WORKS
|
||||
# combostyle.configure('PSG.TCombobox.Listbox', background='purple')
|
||||
# toplevel_form.TKroot.option_add("*TCombobox*Background", element.BackgroundColor) # WORK for drop-down list (Changes all)
|
||||
# combostyle.map('PSG.TCombobox', background=[('active', 'purple'), ('disabled', 'purple')])
|
||||
# combostyle.configure('PSG.TCombobox.PopdownFrame', background=element.BackgroundColor)
|
||||
# combostyle.configure('PSG.TCombobox.field', fieldbackground=element.BackgroundColor)
|
||||
# combostyle.configure('PSG.TCombobox.Listbox', background=element.BackgroundColor)
|
||||
# print(combostyle.element_names())
|
||||
# print(combostyle.element_options('PSG.TCombobox'))
|
||||
# try:
|
||||
# combostyle.theme_create('combostyle',
|
||||
# settings={'TCombobox':
|
||||
# {'configure':
|
||||
# {'selectbackground': 'gray50',
|
||||
# 'fieldbackground': element.BackgroundColor,
|
||||
# 'foreground': text_color,
|
||||
# 'background': element.BackgroundColor}
|
||||
# }})
|
||||
# except:
|
||||
# try:
|
||||
# combostyle.theme_settings('combostyle',
|
||||
# settings={'TCombobox':
|
||||
# {'configure':
|
||||
# {'selectbackground': 'gray50',
|
||||
# 'fieldbackground': element.BackgroundColor,
|
||||
# 'foreground': text_color,
|
||||
# 'background': element.BackgroundColor}
|
||||
# }})
|
||||
# except:
|
||||
# pass
|
||||
# # ATTENTION: this applies the new style 'combostyle' to all ttk.Combobox
|
||||
# combostyle.theme_use('combostyle')
|
||||
|
||||
|
||||
# Creates a unique name for each field element(Sure there is a better way to do this)
|
||||
unique_field = str(time.time()).replace('.','') + '.TCombobox.field'
|
||||
# unique_field = str(randint(1,50000000)) + '.TCombobox.field'
|
||||
|
||||
# print(unique_field)
|
||||
# Clones over the TCombobox.field element from the "alt" theme.
|
||||
# This is what will allow us to change the background color without altering the whole programs theme
|
||||
combostyle.element_create(unique_field, "from", "alt")
|
||||
|
||||
# Create widget layout using cloned "alt" field
|
||||
combostyle.layout(style_name, [
|
||||
(unique_field, {'children': [('Combobox.downarrow', {'side': 'right', 'sticky': 'ns'}),
|
||||
('Combobox.padding',
|
||||
{'children': [('Combobox.focus',
|
||||
{'children': [('Combobox.textarea',
|
||||
{'sticky': 'nswe'})],
|
||||
'expand': '1',
|
||||
'sticky': 'nswe'})],
|
||||
'expand': '1',
|
||||
'sticky': 'nswe'})],
|
||||
'sticky': 'nswe'})])
|
||||
|
||||
# Copy default TCombobox settings
|
||||
# Getting an error on this line of code
|
||||
# combostyle.configure(style_name, *combostyle.configure("TCombobox"))
|
||||
|
||||
# Set individual widget options
|
||||
combostyle.configure(style_name, foreground=element.TextColor)
|
||||
combostyle.configure(style_name, selectbackground='gray70')
|
||||
combostyle.configure(style_name, fieldbackground=element.BackgroundColor)
|
||||
combostyle.configure(style_name, selectforeground=element.TextColor)
|
||||
|
||||
element.TKCombo = tkinter.ttk.Combobox(tk_row_frame, width=width, textvariable=element.TKStringVar, font=font, style=style_name)
|
||||
if element.Size[1] != 1 and element.Size[1] is not None:
|
||||
element.TKCombo.configure(height=element.Size[1])
|
||||
# element.TKCombo['state']='readonly'
|
||||
element.TKCombo['values'] = element.Values
|
||||
|
||||
# if element.InitializeAsDisabled:
|
||||
# element.TKCombo['state'] = 'disabled'
|
||||
# if element.BackgroundColor is not None:
|
||||
# element.TKCombo.configure(background=element.BackgroundColor)
|
||||
element.TKCombo.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1])
|
||||
if element.Visible is False:
|
||||
element.TKCombo.pack_forget()
|
||||
|
@ -5071,7 +5107,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKCombo['state'] = 'disabled'
|
||||
if element.Tooltip is not None:
|
||||
element.TooltipObject = ToolTip(element.TKCombo, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
|
||||
# ------------------------- OPTION MENU (Like ComboBox but different) element ------------------------- #
|
||||
# ------------------------- OPTION MENU Element (Like ComboBox but different) element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_OPTION_MENU:
|
||||
max_line_len = max([len(str(l)) for l in element.Values])
|
||||
if auto_size_text is False:
|
||||
|
@ -5170,7 +5206,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
AddMenuItem(top_menu, menu[1], element)
|
||||
element.TKRightClickMenu = top_menu
|
||||
element.TKText.bind('<Button-3>', element.RightClickMenuCallback)
|
||||
# ------------------------- INPUT CHECKBOX element ------------------------- #
|
||||
# ------------------------- CHECKBOX element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_CHECKBOX:
|
||||
width = 0 if auto_size_text else element_size[0]
|
||||
default_value = element.InitialState
|
||||
|
@ -5217,7 +5253,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKProgressBar.TKProgressBarForReal.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1])
|
||||
if element.Visible is False:
|
||||
element.TKProgressBar.TKProgressBarForReal.pack_forget()
|
||||
# ------------------------- INPUT RADIO BUTTON element ------------------------- #
|
||||
# ------------------------- RADIO BUTTON element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_RADIO:
|
||||
width = 0 if auto_size_text else element_size[0]
|
||||
default_value = element.InitialState
|
||||
|
@ -5251,7 +5287,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKRadio.pack_forget()
|
||||
if element.Tooltip is not None:
|
||||
element.TooltipObject = ToolTip(element.TKRadio, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
|
||||
# ------------------------- INPUT SPIN Box element ------------------------- #
|
||||
# ------------------------- SPIN element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_INPUT_SPIN:
|
||||
width, height = element_size
|
||||
width = 0 if auto_size_text else element_size[0]
|
||||
|
@ -5282,7 +5318,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
pad=elementpad)
|
||||
element._TKOut.pack(side=tk.LEFT, expand=True, fill='both')
|
||||
if element.Visible is False:
|
||||
element._TKOut.pack_forget()
|
||||
element._TKOut.frame.pack_forget()
|
||||
if element.Tooltip is not None:
|
||||
element.TooltipObject = ToolTip(element._TKOut, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
|
||||
if element.RightClickMenu or toplevel_form.RightClickMenu:
|
||||
|
@ -5313,7 +5349,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
else:
|
||||
element.tktext_label = tk.Label(tk_row_frame, width=width, height=height, bd=border_depth)
|
||||
if element.BackgroundColor is not None:
|
||||
element.tktext_label.config(background=element.BackgroundColor);
|
||||
element.tktext_label.config(background=element.BackgroundColor)
|
||||
|
||||
element.tktext_label.image = photo
|
||||
# tktext_label.configure(anchor=tk.NW, image=photo)
|
||||
|
@ -5556,6 +5592,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TooltipObject = ToolTip(element.TKScale, text=element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME)
|
||||
# ------------------------- TABLE element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_TABLE:
|
||||
element = element # type: Table
|
||||
frame = tk.Frame(tk_row_frame)
|
||||
|
||||
height = element.NumRows
|
||||
|
@ -5575,7 +5612,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
except:
|
||||
column_widths[i] = col_width
|
||||
if element.ColumnsToDisplay is None:
|
||||
displaycolumns = element.ColumnHeadings
|
||||
displaycolumns = element.ColumnHeadings if element.ColumnHeadings is not None else element.Values[0]
|
||||
else:
|
||||
displaycolumns = []
|
||||
for i, should_display in enumerate(element.ColumnsToDisplay):
|
||||
|
@ -5587,13 +5624,15 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
column_headings = [element.RowHeaderText, ] + element.ColumnHeadings
|
||||
element.TKTreeview = tkinter.ttk.Treeview(frame, columns=column_headings,
|
||||
displaycolumns=displaycolumns, show='headings', height=height,
|
||||
selectmode=element.SelectMode)
|
||||
selectmode=element.SelectMode,)
|
||||
treeview = element.TKTreeview
|
||||
if element.DisplayRowNumbers:
|
||||
treeview.heading(element.RowHeaderText, text=element.RowHeaderText) # make a dummy heading
|
||||
treeview.column(element.RowHeaderText, width=50, anchor=anchor)
|
||||
for i, heading in enumerate(element.ColumnHeadings):
|
||||
treeview.heading(heading, text=heading)
|
||||
|
||||
headings = element.ColumnHeadings if element.ColumnHeadings is not None else element.Values[0]
|
||||
for i, heading in enumerate(headings):
|
||||
# treeview.heading(heading, text=heading)
|
||||
if element.AutoSizeColumns:
|
||||
width = max(column_widths[i], len(heading))
|
||||
else:
|
||||
|
@ -5601,15 +5640,23 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
width = element.ColumnWidths[i]
|
||||
except:
|
||||
width = element.DefaultColumnWidth
|
||||
|
||||
treeview.column(heading, width=width * CharWidthInPixels(), anchor=anchor)
|
||||
|
||||
# Insert values into the tree
|
||||
for i, value in enumerate(element.Values):
|
||||
if element.DisplayRowNumbers:
|
||||
value = [i+element.StartingRowNumber] + value
|
||||
id = treeview.insert('', 'end', text=value, iid=i + 1, values=value, tag=i % 2)
|
||||
if element.AlternatingRowColor is not None:
|
||||
treeview.tag_configure(1, background=element.AlternatingRowColor)
|
||||
id = treeview.insert('', 'end', text=value, iid=i + 1, values=value, tag=i)
|
||||
if element.AlternatingRowColor is not None: # alternating colors
|
||||
for row in range(0, len(element.Values), 2):
|
||||
treeview.tag_configure(row, background=element.AlternatingRowColor)
|
||||
if element.RowColors is not None: # individual row colors
|
||||
for row_def in element.RowColors:
|
||||
if len(row_def) == 2: # only background is specified
|
||||
treeview.tag_configure(row_def[0], background=row_def[1])
|
||||
else:
|
||||
treeview.tag_configure(row_def[0], background=row_def[2], foreground=row_def[1])
|
||||
|
||||
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
|
||||
tkinter.ttk.Style().configure("Treeview", background=element.BackgroundColor,
|
||||
fieldbackground=element.BackgroundColor)
|
||||
|
@ -5622,9 +5669,17 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
if element.BindReturnKey:
|
||||
treeview.bind('<Return>', element.treeview_double_click)
|
||||
treeview.bind('<Double-Button-1>', element.treeview_double_click)
|
||||
|
||||
scrollbar = tk.Scrollbar(frame)
|
||||
scrollbar.pack(side=tk.RIGHT, fill='y')
|
||||
scrollbar.config(command=treeview.yview)
|
||||
|
||||
if not element.VerticalScrollOnly:
|
||||
hscrollbar = tk.Scrollbar(frame, orient=tk.HORIZONTAL)
|
||||
hscrollbar.pack(side=tk.BOTTOM, fill='x')
|
||||
hscrollbar.config(command=treeview.xview)
|
||||
treeview.configure(xscrollcommand=hscrollbar.set)
|
||||
|
||||
treeview.configure(yscrollcommand=scrollbar.set)
|
||||
|
||||
element.TKTreeview.pack(side=tk.LEFT, expand=True, padx=0, pady=0, fill='both')
|
||||
|
@ -5642,6 +5697,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKTreeview.bind('<Button-3>', element.RightClickMenuCallback)
|
||||
# ------------------------- Tree element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_TREE:
|
||||
element = element #type: Tree
|
||||
frame = tk.Frame(tk_row_frame)
|
||||
|
||||
height = element.NumRows
|
||||
|
@ -5663,7 +5719,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
# ------------- GET THE TREEVIEW WIDGET -------------
|
||||
element.TKTreeview = tkinter.ttk.Treeview(frame, columns=column_headings,
|
||||
displaycolumns=displaycolumns, show='tree headings', height=height,
|
||||
selectmode=element.SelectMode, )
|
||||
selectmode=element.SelectMode)
|
||||
treeview = element.TKTreeview
|
||||
for i, heading in enumerate(element.ColumnHeadings): # Configure cols + headings
|
||||
treeview.heading(heading, text=heading)
|
||||
|
@ -5675,11 +5731,19 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
except:
|
||||
width = element.DefaultColumnWidth
|
||||
treeview.column(heading, width=width * CharWidthInPixels(), anchor=anchor)
|
||||
|
||||
def add_treeview_data(node):
|
||||
# print(f'Inserting {node.key} under parent {node.parent}')
|
||||
if node.key != '':
|
||||
treeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values, open=element.ShowExpanded)
|
||||
if node.icon:
|
||||
if type(node.icon) is bytes:
|
||||
photo = tk.PhotoImage(data=node.icon)
|
||||
else:
|
||||
photo = tk.PhotoImage(file=node.icon)
|
||||
node.photo = photo
|
||||
treeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values, open=element.ShowExpanded, image=node.photo)
|
||||
else:
|
||||
treeview.insert(node.parent, 'end', node.key, text=node.text, values=node.values, open=element.ShowExpanded)
|
||||
|
||||
for node in node.children:
|
||||
add_treeview_data(node)
|
||||
|
||||
|
@ -5692,6 +5756,9 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
if element.TextColor is not None and element.TextColor != COLOR_SYSTEM_DEFAULT:
|
||||
tkinter.ttk.Style().configure("Treeview", foreground=element.TextColor)
|
||||
|
||||
tkinter.ttk.Style().configure("Treeview", font=font)
|
||||
if element.RowHeight:
|
||||
tkinter.ttk.Style().configure("Treeview", rowheight=element.RowHeight)
|
||||
scrollbar = tk.Scrollbar(frame)
|
||||
scrollbar.pack(side=tk.RIGHT, fill='y')
|
||||
scrollbar.config(command=treeview.yview)
|
||||
|
@ -5712,6 +5779,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
|
|||
element.TKTreeview.bind('<Button-3>', element.RightClickMenuCallback)
|
||||
# ------------------------- Separator element ------------------------- #
|
||||
elif element_type == ELEM_TYPE_SEPARATOR:
|
||||
element = element # type: VerticalSeparator
|
||||
separator = tkinter.ttk.Separator(tk_row_frame, orient=element.Orientation, )
|
||||
separator.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1], fill='both', expand=True)
|
||||
# ------------------------- StatusBar element ------------------------- #
|
||||
|
@ -5819,7 +5887,6 @@ def ConvertFlexToTK(MyFlexForm):
|
|||
# ----====----====----====----====----==== STARTUP TK ====----====----====----====----====----#
|
||||
def StartupTK(my_flex_form):
|
||||
# global _my_windows
|
||||
|
||||
# ow = _my_windows.NumOpenWindows
|
||||
ow = Window.NumOpenWindows
|
||||
# print('Starting TK open Windows = {}'.format(ow))
|
||||
|
@ -7734,7 +7801,7 @@ def main():
|
|||
|
||||
frame2 = [
|
||||
[Listbox(['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(20, 5))],
|
||||
[Combo(['Combo item 1', ], size=(20, 3))],
|
||||
[Combo(['Combo item 1', ], size=(20, 3), text_color='red', background_color='red')],
|
||||
[Spin([1, 2, 3], size=(4, 3))],
|
||||
]
|
||||
|
||||
|
|
Loading…
Reference in New Issue