Merge pull request #4898 from PySimpleGUI/Dev-latest

More Tab / TabGroup options (can tell when I'm doing a Udemy lesson o…
This commit is contained in:
PySimpleGUI 2021-10-28 18:04:29 -04:00 committed by GitHub
commit aa44f8e84e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 69 additions and 10 deletions

View File

@ -1,5 +1,5 @@
#!/usr/bin/python3 #!/usr/bin/python3
version = __version__ = "4.53.0.4 Unreleased" version = __version__ = "4.53.0.5 Unreleased"
_change_log = """ _change_log = """
@ -19,6 +19,14 @@ _change_log = """
4.53.0.4 4.53.0.4
The proliferation of relative_location across the popups, Print The proliferation of relative_location across the popups, Print
Some new BASE64 images (hearts, check & x) - use image_subsample to resize to your liking Some new BASE64 images (hearts, check & x) - use image_subsample to resize to your liking
4.53.0.5
Changed the Frame element's size description from "Do not use" to "by all means use"
Tab changes
image_source parawmter - Support for an image in the Tab (new image_source parameter of Tab Element)
image_subsample parameter - subsample for image (makes smaller by 1/image_subsample)
TabGroup changes
tab_border_width parameter - sets the border around the tab top portion. Now can set to 0 if you want
Removed the green color for the Multiple Choice Group in sg.main so that it's readable now
""" """
__version__ = version.split()[0] # For PEP 396 and PEP 345 __version__ = version.split()[0] # For PEP 396 and PEP 345
@ -5804,7 +5812,7 @@ class Frame(Element):
:type title_location: (enum) :type title_location: (enum)
:param relief: relief style. Values are same as other elements with reliefs. Choices include RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID :param relief: relief style. Values are same as other elements with reliefs. Choices include RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID
:type relief: (enum) :type relief: (enum)
:param size: (width, height) DO NOT use this. Instead, place your layout in a Column element with the size set on the Column element. Set pad=(0,0) on your Column :param size: (width, height) Sets an initial hard-coded size for the Frame. This used to be a problem, but was fixed in 4.53.0 and works better than Columns when using the size paramter
:type size: (int, int) :type size: (int, int)
:param s: Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used :param s: Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used
:type s: (int, int) | (None, None) | int :type s: (int, int) | (None, None) | int
@ -5834,7 +5842,7 @@ class Frame(Element):
:type visible: (bool) :type visible: (bool)
:param element_justification: All elements inside the Frame will have this justification 'left', 'right', 'center' are valid values :param element_justification: All elements inside the Frame will have this justification 'left', 'right', 'center' are valid values
:type element_justification: (str) :type element_justification: (str)
:param vertical_alignment: Place the column at the 'top', 'center', 'bottom' of the row (can also use t,c,r). Defaults to no setting (tkinter decides) :param vertical_alignment: Place the Frame at the 'top', 'center', 'bottom' of the row (can also use t,c,r). Defaults to no setting (tkinter decides)
:type vertical_alignment: (str) :type vertical_alignment: (str)
:param metadata: User metadata that can be set to ANYTHING :param metadata: User metadata that can be set to ANYTHING
:type metadata: (Any) :type metadata: (Any)
@ -6100,7 +6108,7 @@ class Tab(Element):
""" """
def __init__(self, title, layout, title_color=None, background_color=None, font=None, pad=None, p=None, disabled=False, def __init__(self, title, layout, title_color=None, background_color=None, font=None, pad=None, p=None, disabled=False,
border_width=None, key=None, k=None, tooltip=None, right_click_menu=None, expand_x=False, expand_y=False, visible=True, element_justification='left', metadata=None): border_width=None, key=None, k=None, tooltip=None, right_click_menu=None, expand_x=False, expand_y=False, visible=True, element_justification='left', image_source=None, image_subsample=None, metadata=None):
""" """
:param title: text to show on the tab :param title: text to show on the tab
:type title: (str) :type title: (str)
@ -6136,10 +6144,26 @@ class Tab(Element):
:type visible: (bool) :type visible: (bool)
:param element_justification: All elements inside the Tab will have this justification 'left', 'right', 'center' are valid values :param element_justification: All elements inside the Tab will have this justification 'left', 'right', 'center' are valid values
:type element_justification: (str) :type element_justification: (str)
:param image_source: A filename or a base64 bytes of an image to place on the Tab
:type image_source: str | bytes | None
:param image_subsample: amount to reduce the size of the image. Divides the size by this number. 2=1/2, 3=1/3, 4=1/4, etc
:type image_subsample: (int)
:param metadata: User metadata that can be set to ANYTHING :param metadata: User metadata that can be set to ANYTHING
:type metadata: (Any) :type metadata: (Any)
""" """
filename = data = None
if image_source is not None:
if isinstance(image_source, bytes):
data = image_source
elif isinstance(image_source, str):
filename = image_source
else:
warnings.warn('Image element - source is not a valid type: {}'.format(type(source)), UserWarning)
self.Filename = filename
self.Data = data
self.ImageSubsample = image_subsample
self.UseDictionary = False self.UseDictionary = False
self.ReturnValues = None self.ReturnValues = None
self.ReturnValuesList = [] self.ReturnValuesList = []
@ -6321,7 +6345,7 @@ class TabGroup(Element):
""" """
def __init__(self, layout, tab_location=None, title_color=None, tab_background_color=None, selected_title_color=None, selected_background_color=None, def __init__(self, layout, tab_location=None, title_color=None, tab_background_color=None, selected_title_color=None, selected_background_color=None,
background_color=None, font=None, change_submits=False, enable_events=False, pad=None, p=None, border_width=None, theme=None, key=None, k=None, background_color=None, font=None, change_submits=False, enable_events=False, pad=None, p=None, border_width=None, tab_border_width=None, theme=None, key=None, k=None,
size=(None, None), s=(None, None), tooltip=None, right_click_menu=None, expand_x=False, expand_y=False, visible=True, metadata=None): size=(None, None), s=(None, None), tooltip=None, right_click_menu=None, expand_x=False, expand_y=False, visible=True, metadata=None):
""" """
:param layout: Layout of Tabs. Different than normal layouts. ALL Tabs should be on first row :param layout: Layout of Tabs. Different than normal layouts. ALL Tabs should be on first row
@ -6350,6 +6374,8 @@ class TabGroup(Element):
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int :type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
:param border_width: width of border around element in pixels :param border_width: width of border around element in pixels
:type border_width: (int) :type border_width: (int)
:param tab_border_width: width of border around the tabs
:type tab_border_width: (int)
:param theme: DEPRICATED - You can only specify themes using set options or when window is created. It's not possible to do it on an element basis :param theme: DEPRICATED - You can only specify themes using set options or when window is created. It's not possible to do it on an element basis
:type theme: (enum) :type theme: (enum)
:param key: Value that uniquely identifies this element from all other elements. Used when Finding an element or in return values. Must be unique to the window :param key: Value that uniquely identifies this element from all other elements. Used when Finding an element or in return values. Must be unique to the window
@ -6396,6 +6422,7 @@ class TabGroup(Element):
self.TabLocation = tab_location self.TabLocation = tab_location
self.ElementJustification = 'left' self.ElementJustification = 'left'
self.RightClickMenu = right_click_menu self.RightClickMenu = right_click_menu
self.TabBorderWidth = tab_border_width
key = key if key is not None else k key = key if key is not None else k
sz = size if size != (None, None) else s sz = size if size != (None, None) else s
@ -14665,6 +14692,36 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
if element.visible is False: if element.visible is False:
state = 'hidden' state = 'hidden'
# this code will add an image to the tab. Use it when adding the image on a tab enhancement # this code will add an image to the tab. Use it when adding the image on a tab enhancement
try:
if element.Filename is not None:
photo = tk.PhotoImage(file=element.Filename)
elif element.Data is not None:
photo = tk.PhotoImage(data=element.Data)
else:
photo = None
if element.ImageSubsample and photo is not None:
photo = photo.subsample(element.ImageSubsample)
# print('*ERROR laying out form.... Image Element has no image specified*')
except Exception as e:
photo = None
_error_popup_with_traceback('Your Window has an Tab Element with an IMAGE problem',
'The traceback will show you the Window with the problem layout',
'Look in this Window\'s layout for an Image element that has a key of {}'.format(element.Key),
'The error occuring is:', e)
if photo is not None:
if element_size == (None, None) or element_size is None or element_size == toplevel_form.DefaultElementSize:
width, height = photo.width(), photo.height()
else:
width, height = element_size
element.tktext_label = tk.Label(tk_row_frame, image=photo, width=width, height=height, bd=0)
else:
element.tktext_label = tk.Label(tk_row_frame, bd=0)
element.photo = photo
if photo is not None:
form.TKNotebook.add(element.TKFrame, text=element.Title, compound=tk.LEFT, state=state,image=photo)
# element.photo_image = tk.PhotoImage(data=DEFAULT_BASE64_ICON) # element.photo_image = tk.PhotoImage(data=DEFAULT_BASE64_ICON)
# form.TKNotebook.add(element.TKFrame, text=element.Title, compound=tk.LEFT, state=state,image = element.photo_image) # form.TKNotebook.add(element.TKFrame, text=element.Title, compound=tk.LEFT, state=state,image = element.photo_image)
form.TKNotebook.add(element.TKFrame, text=element.Title, state=state) form.TKNotebook.add(element.TKFrame, text=element.Title, state=state)
@ -14703,7 +14760,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
style.configure(custom_style, tabposition=tab_position) style.configure(custom_style, tabposition=tab_position)
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT: if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
style.configure(custom_style, background=element.BackgroundColor, foreground='purple') style.configure(custom_style, background=element.BackgroundColor)
# FINALLY the proper styling to get tab colors! # FINALLY the proper styling to get tab colors!
if element.SelectedTitleColor is not None and element.SelectedTitleColor != COLOR_SYSTEM_DEFAULT: if element.SelectedTitleColor is not None and element.SelectedTitleColor != COLOR_SYSTEM_DEFAULT:
@ -14716,10 +14773,12 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
style.configure(custom_style + '.Tab', foreground=element.TextColor) style.configure(custom_style + '.Tab', foreground=element.TextColor)
if element.BorderWidth is not None: if element.BorderWidth is not None:
style.configure(custom_style, borderwidth=element.BorderWidth) style.configure(custom_style, borderwidth=element.BorderWidth)
# style.configure(custom_style + '.Tab', borderwidth=0) # if ever want to get rid of border around the TABS themselves if element.TabBorderWidth is not None:
style.configure(custom_style + '.Tab', borderwidth=element.TabBorderWidth) # if ever want to get rid of border around the TABS themselves
style.configure(custom_style + '.Tab', font=font) style.configure(custom_style + '.Tab', font=font)
element.Style = style
element.StyleName = custom_style
element.TKNotebook = element.Widget = ttk.Notebook(tk_row_frame, style=custom_style) element.TKNotebook = element.Widget = ttk.Notebook(tk_row_frame, style=custom_style)
PackFormIntoFrame(element, toplevel_form.TKroot, toplevel_form) PackFormIntoFrame(element, toplevel_form.TKroot, toplevel_form)
@ -22593,8 +22652,8 @@ def _create_main_window():
tab1 = Tab('Graph\n', frame6, tooltip='Graph is in here', title_color='red') tab1 = Tab('Graph\n', frame6, tooltip='Graph is in here', title_color='red')
tab2 = Tab('CB, Radio\nList, Combo', tab2 = Tab('CB, Radio\nList, Combo',
[[Frame('Multiple Choice Group', frame2, title_color='green', tooltip='Checkboxes, radio buttons, etc', vertical_alignment='t', pad=(0, 0)), [[Frame('Multiple Choice Group', frame2, title_color='#FFFFFF', tooltip='Checkboxes, radio buttons, etc', vertical_alignment='t',),
Frame('Binary Choice Group', frame3, title_color='#FFFFFF', tooltip='Binary Choice', vertical_alignment='t'), ]], pad=(0, 0)) Frame('Binary Choice Group', frame3, title_color='#FFFFFF', tooltip='Binary Choice', vertical_alignment='t', ), ]])
# tab3 = Tab('Table and Tree', [[Frame('Structured Data Group', frame5, title_color='red', element_justification='l')]], tooltip='tab 3', title_color='red', ) # tab3 = Tab('Table and Tree', [[Frame('Structured Data Group', frame5, title_color='red', element_justification='l')]], tooltip='tab 3', title_color='red', )
tab3 = Tab('Table &\nTree', [[Column(frame5, element_justification='l', vertical_alignment='t')]], tooltip='tab 3', title_color='red', k='-TAB TABLE-') tab3 = Tab('Table &\nTree', [[Column(frame5, element_justification='l', vertical_alignment='t')]], tooltip='tab 3', title_color='red', k='-TAB TABLE-')
tab4 = Tab('Sliders\n', [[Frame('Variable Choice Group', frame4, title_color='blue')]], tooltip='tab 4', title_color='red', k='-TAB VAR-') tab4 = Tab('Sliders\n', [[Frame('Variable Choice Group', frame4, title_color='blue')]], tooltip='tab 4', title_color='red', k='-TAB VAR-')