diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 89717968..58fe0fff 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1,8 +1,8 @@ #!/usr/bin/python3 -version = __version__ = "4.45.0.15 Unreleased\nAdded autoscroll parameter to Multiline.print & cprint - defaults to True (backward compatible), ButtonMenu use font for button as menu font if none is supplied, make a copy of menu definition when making ButtonMenu, made menu definition optional for ButtonMenu so can change only some other settings, set class_ for Toplevel windows to fix problem with titles on some Linux systems, fix bug when menu shortcut char in first pos and item is disabled !&Item, Sizegrip - fixed expansion problem. Should not have expanded row, added kill application button to error popup. cprint & Multiline.print will now take a single color and use as text color, keep_on_top added to one_line_progress_meter. Deprication warning added to FindElement as first step of moving out of non-PEP8 world, added TabGroup.add_tab, allow modal window on the Mac again as an experiment. set cwd='.' if dir not found in execute_py_file, check for exists in execute_py_file, right_click_menu added to Radio Checkbox Tabgroup Spin Dlider. Elements that don't have a right_click_menu parm now pick up the default from the Window" +version = __version__ = "4.45.0.16 Unreleased\nAdded autoscroll parameter to Multiline.print & cprint - defaults to True (backward compatible), ButtonMenu use font for button as menu font if none is supplied, make a copy of menu definition when making ButtonMenu, made menu definition optional for ButtonMenu so can change only some other settings, set class_ for Toplevel windows to fix problem with titles on some Linux systems, fix bug when menu shortcut char in first pos and item is disabled !&Item, Sizegrip - fixed expansion problem. Should not have expanded row, added kill application button to error popup. cprint & Multiline.print will now take a single color and use as text color, keep_on_top added to one_line_progress_meter. Deprication warning added to FindElement as first step of moving out of non-PEP8 world, added TabGroup.add_tab, allow modal window on the Mac again as an experiment. set cwd='.' if dir not found in execute_py_file, check for exists in execute_py_file, right_click_menu added to Radio Checkbox Tabgroup Spin Dlider. Elements that don't have a right_click_menu parm now pick up the default from the Window. Reformatted all docstrings to line up the desriptions for better readability." -__version__ = version.split()[0] # For PEP 396 and PEP 345 +__version__ = version.split()[0] # For PEP 396 and PEP 345 # The shortened version of version try: @@ -44,9 +44,9 @@ port = 'PySimpleGUI' This software is available for your use under a LGPL3+ license This notice, these first 150 lines of code shall remain unchanged - - - + + + 888 .d8888b. 8888888b. 888 .d8888b. 888 d88P Y88b 888 Y88b 888 d88P Y88b 888 888 888 888 888 888 .d88P @@ -55,43 +55,42 @@ port = 'PySimpleGUI' 888 888 888 888 888 888 888 888 888 Y88b d88P 888 888 Y88b d88P 88888888 "Y8888P88 888 88888888 "Y8888P" - - + + In addition to the normal publishing requirements of LGPL3+, these also apply: 1. These and all comments are to remain in the source code 2. The "Official" version of PySimpleGUI and the associated documentation lives on two (and **only** two) places: 1. GitHub - (http://www.PySimpleGUI.com) currently pointing at: https://github.com/PySimpleGUI/PySimpleGUI 2. PyPI - pip install PySimpleGUI is the customary way of obtaining the latest release - + THE official documentation location is: Read the Docs (via http://www.PySimpleGUI.org). Currently is pointed at: https://pysimplegui.readthedocs.io/en/latest/ If you've obtained this software in any other way, then those listed here, then SUPPORT WILL NOT BE PROVIDED. 3. If you use PySimpleGUI in your project/product, a notice of its use needs to be displayed in your readme file ----------------------------------------------------------------------------------------------------------------- - + How about having FUN with this package?? Terrible note to begin this journey of actually having fun making GUI based applications so I'll try to make it up to you. - + The first bit of good news for you is that literally 100s of pages of documentation await you. 300 Demo Programs have been written as a "jump start" mechanism to get your running as quickly as possible. - + Some general bits of advice: Upgrade your software! python -m pip install --upgrade --no-cache-dir PySimpleGUI If you're thinking of filing an Issue or posting a problem, Upgrade your software first There are constantly something new and interesting coming out of this project so stay current if you can - + The FASTEST WAY to learn PySimpleGUI is to begin to play with it, and to read the documentation. http://www.PySimpleGUI.org http://Calls.PySimpleGUI.org http://Cookbook.PySimpleGUI.org - + The User Manual and the Cookbook are both designed to paint some nice looking GUIs on your screen within 5 minutes of you deciding to PySimpleGUI out. """ - # all of the tkinter involved imports import tkinter as tk from tkinter import filedialog @@ -99,12 +98,12 @@ from tkinter.colorchooser import askcolor from tkinter import ttk import tkinter.scrolledtext as tkst import tkinter.font + # end of tkinter specific imports # get the tkinter detailed version tclversion_detailed = tkinter.Tcl().eval('info patchlevel') framework_version = tclversion_detailed - import time import pickle import calendar @@ -116,8 +115,9 @@ import traceback import difflib import copy -try: # Because Raspberry Pi is still on 3.4....it's not critical if this module isn't imported on the Pi - from typing import List, Any, Union, Tuple, Dict, SupportsAbs, Optional # because this code has to run on 2.7 can't use real type hints. Must do typing only in comments +try: # Because Raspberry Pi is still on 3.4....it's not critical if this module isn't imported on the Pi + from typing import List, Any, Union, Tuple, Dict, SupportsAbs, \ + Optional # because this code has to run on 2.7 can't use real type hints. Must do typing only in comments except: print('*** Skipping import of Typing module. "pip3 install typing" to remove this warning ***') import random @@ -125,18 +125,22 @@ import warnings from math import floor from math import fabs from functools import wraps -try: # Because Raspberry Pi is still on 3.4.... + +try: # Because Raspberry Pi is still on 3.4.... from subprocess import run, PIPE, Popen import subprocess -except: pass +except: + pass import threading import itertools import os import json import queue + try: import webbrowser + webbrowser_available = True except: webbrowser_available = False @@ -152,7 +156,6 @@ import urllib.request import urllib.error import urllib.parse - warnings.simplefilter('always', UserWarning) g_time_start = 0 @@ -180,13 +183,13 @@ def timer_stop(): Time your code easily.... stop the timer and print the number of milliseconds since the timer start :return: delta in milliseconds from timer_start was called - :rtype: int + :rtype: int """ global g_time_delta, g_time_end g_time_end = time.time() g_time_delta = g_time_end - g_time_start - return int(g_time_delta*1000) + return int(g_time_delta * 1000) def _timeit(func): @@ -194,7 +197,7 @@ def _timeit(func): Put @_timeit as a decorator to a function to get the time spent in that function printed out :param func: Decorated function - :return: Execution time for the decorated function + :return: Execution time for the decorated function """ @wraps(func) @@ -202,7 +205,7 @@ def _timeit(func): start = time.time() result = func(*args, **kwargs) end = time.time() - print('{} executed in {:.4f} seconds'.format( func.__name__, end - start)) + print('{} executed in {:.4f} seconds'.format(func.__name__, end - start)) return result return wrapper @@ -219,7 +222,7 @@ def _timeit_summary(func): Put @_timeit_summary as a decorator to a function to get the time spent in that function printed out :param func: Decorated function - :return: Execution time for the decorated function + :return: Execution time for the decorated function """ @wraps(func) @@ -232,7 +235,7 @@ def _timeit_summary(func): _timeit_counter += 1 _timeit_total += end - start if _timeit_counter > MAX_TIMEIT_COUNT: - print('{} executed in {:.4f} seconds'.format( func.__name__, _timeit_total/MAX_TIMEIT_COUNT)) + print('{} executed in {:.4f} seconds'.format(func.__name__, _timeit_total / MAX_TIMEIT_COUNT)) _timeit_counter = 0 _timeit_total = 0 return result @@ -247,7 +250,7 @@ def running_linux(): Returns True if Linux :return: True if sys.platform indicates running Linux - :rtype: (bool) + :rtype: (bool) """ return sys.platform.startswith('linux') @@ -259,7 +262,7 @@ def running_mac(): Returns True if Mac :return: True if sys.platform indicates running Mac - :rtype: (bool) + :rtype: (bool) """ return sys.platform.startswith('darwin') @@ -271,7 +274,7 @@ def running_windows(): Returns True if Windows :return: True if sys.platform indicates running Windows - :rtype: (bool) + :rtype: (bool) """ return sys.platform.startswith('win') @@ -284,14 +287,13 @@ def running_trinket(): Returns True if "Trinket" (in theory) :return: True if sys.platform indicates Linux and the number of environment variables is 1 - :rtype: (bool) + :rtype: (bool) """ if len(os.environ) == 1 and sys.platform.startswith('linux'): return True return False - # Handy python statements to increment and decrement with wrapping that I don't want to forget # count = (count + (MAX - 1)) % MAX # Decrement - roll over to MAX from 0 # count = (count + 1) % MAX # Increment to MAX then roll over to 0 @@ -329,7 +331,6 @@ DEFAULT_BASE64_ICON = b'R0lGODlhIQAgAPcAAAAAADBpmDBqmTFqmjJrmzJsnDNtnTRrmTZtmzZu DEFAULT_BASE64_ICON_16_BY_16 = b'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKCSURBVDhPVZNbSFRRFIb35YwXItBIGtDsiqENEUTRjJlZkJggPSUYBD0UhULElE6hBY6ID/ZSpD1IDxaCEPhUaFLRQyWRNxIJe8syMxCjMCbB07fOsaMt+GftvWf//7/2Whyt1sTei/fCpDqQBTrGOi9Myrk7URwhnQUfQLeOvErJuUQgADlK6gObvAOl5sHx0doHljwARFRiCpxG5J1sjPxALiYNgn9kiQ3gafdYUYzseCd+FICX7sShw7LR++q6cl3XHaXQHFdOJLxFsJtvKHnbUr1nqp01hhStpXAzo7TZZXOjJ+9orT9pY74aY3ZobZZYW8D/GpjM19Ob088fmJxW2tkC4AJt17Oeg2MLrHX6jXWes16w1sbBkrFWBTB2nTLpv5VJg7wGNhRDwCS0tR1cbECkidwMQohAdoScqiz8/FCZUKlPCgSWlQ71elOI1fcco9hCXp1kS7dX3u+qVOm2L4nW8qE4Neetvl8v83NOb++9703BcUI/cU3imuWV7JedKtv5LdFaMRzHLW+N+zJoVDZzRLj6SFNfPlMYwy5bDiRcCojmz15tKx+6hKPv7LvjrG/Q2RoOwjSyzNDlahyzA2dAJeNtFcMHA2cfLn24STNr6P4I728jJ7hvf/lEGuaXLnkRAp0PyFK+hlyLSJGyGWnKyeBi2oJU0IPIjNd15uuL2f2PJgueQBKhVRETCgNeYU+xaeEpnWaw8cQPRM7g/McT8eF0De9u7P+49TqXF7no98BDEEkdvvXem8LAtfJniFRB/A5XeiAiG2+/icgHVQUW5d5KyAhl3M2y+U+ysv1FDukyKGQW3Y+vHJWvU7mz8RJSPZgDd3H2RqiUUn8BSQuaBvGjGpsAAAAASUVORK5CYII=' - DEFAULT_BASE64_LOADING_GIF = b'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' # Old debugger logo @@ -337,7 +338,6 @@ DEFAULT_BASE64_LOADING_GIF = b'R0lGODlhQABAAKUAAAQCBJyenERCRNTS1CQiJGRmZLS2tPTy9 PSG_DEBUGGER_LOGO = b'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' - DEFAULT_WINDOW_ICON = DEFAULT_BASE64_ICON DEFAULT_ELEMENT_SIZE = (45, 1) # In CHARACTERS @@ -411,7 +411,7 @@ RELIEF_GROOVE = 'groove' RELIEF_SOLID = 'solid' # These are the spepific themes that tkinter offers -THEME_DEFAULT = 'default' # this is a TTK theme, not a PSG theme!!! +THEME_DEFAULT = 'default' # this is a TTK theme, not a PSG theme!!! THEME_WINNATIVE = 'winnative' THEME_CLAM = 'clam' THEME_ALT = 'alt' @@ -425,7 +425,7 @@ DEFAULT_TTK_THEME = THEME_DEFAULT USE_TTK_BUTTONS = None DEFAULT_PROGRESS_BAR_COLOR = (GREENS[0], '#D0D0D0') # a nice green progress bar -DEFAULT_PROGRESS_BAR_COMPUTE = ('#000000', '#000000') # Means that the progress bar colors should be computed from other colors +DEFAULT_PROGRESS_BAR_COMPUTE = ('#000000', '#000000') # Means that the progress bar colors should be computed from other colors DEFAULT_PROGRESS_BAR_COLOR_OFFICIAL = (GREENS[0], '#D0D0D0') # a nice green progress bar DEFAULT_PROGRESS_BAR_SIZE = (20, 20) # Size of Progress Bar (characters for length, pixels for width) DEFAULT_PROGRESS_BAR_BORDER_WIDTH = 1 @@ -472,10 +472,8 @@ TEXT_LOCATION_BOTTOM_LEFT = tk.SW TEXT_LOCATION_BOTTOM_RIGHT = tk.SE TEXT_LOCATION_CENTER = tk.CENTER - GRAB_ANYWHERE_IGNORE_THESE_WIDGETS = (ttk.Sizegrip, tk.Scale, ttk.Scrollbar, tk.scrolledtext.ScrolledText, tk.Scrollbar, tk.Entry, tk.Text, tk.PanedWindow) - # ----====----====----==== Constants the user should NOT f-with ====----====----====----# ThisRow = 555666777 # magic number @@ -515,7 +513,6 @@ CUSTOM_TITLEBAR_ICON = None CUSTOM_TITLEBAR_FONT = None TITLEBAR_METADATA_MARKER = 'This window has a titlebar' - CUSTOM_MENUBAR_METADATA_MARKER = 'This is a custom menubar' SUPPRESS_ERROR_POPUPS = False @@ -532,13 +529,13 @@ ALTERNATE_TABLE_AND_TREE_SELECTED_ROW_COLORS = ('SystemHighlightText', 'SystemHi SYMBOL_SQUARE = '█' SYMBOL_CIRCLE = '⚫' SYMBOL_CIRCLE_OUTLINE = '◯' -SYMBOL_UP = '▲' +SYMBOL_UP = '▲' SYMBOL_RIGHT = '►' -SYMBOL_LEFT = '◄' -SYMBOL_DOWN = '▼' +SYMBOL_LEFT = '◄' +SYMBOL_DOWN = '▼' SYMBOL_X = '❎' SYMBOL_CHECK = '✅' -SYMBOL_BALLOT_X ='☒' +SYMBOL_BALLOT_X = '☒' SYMBOL_BALLOT_CHECK = '☑' SYMBOL_LEFT_DOUBLE = '«' SYMBOL_RIGHT_DOUBLE = '»' @@ -562,11 +559,12 @@ else: DEFAULT_USER_SETTINGS_WIN_PATH = r'~\AppData\Local\PySimpleGUI\settings' DEFAULT_USER_SETTINGS_LINUX_PATH = r'~/.config/PySimpleGUI/settings' -DEFAULT_USER_SETTINGS_MAC_PATH =r'~/Library/Application Support/PySimpleGUI/settings' -DEFAULT_USER_SETTINGS_UNKNOWN_OS_PATH =r'~/Library/Application Support/PySimpleGUI/settings' -DEFAULT_USER_SETTINGS_PATH = None # value set by user to override all paths above -DEFAULT_USER_SETTINGS_PYSIMPLEGUI_PATH = None # location of the global PySimpleGUI settings -DEFAULT_USER_SETTINGS_PYSIMPLEGUI_FILENAME = '_PySimpleGUI_settings_global_.json' # location of the global PySimpleGUI settings +DEFAULT_USER_SETTINGS_MAC_PATH = r'~/Library/Application Support/PySimpleGUI/settings' +DEFAULT_USER_SETTINGS_UNKNOWN_OS_PATH = r'~/Library/Application Support/PySimpleGUI/settings' +DEFAULT_USER_SETTINGS_PATH = None # value set by user to override all paths above +DEFAULT_USER_SETTINGS_PYSIMPLEGUI_PATH = None # location of the global PySimpleGUI settings +DEFAULT_USER_SETTINGS_PYSIMPLEGUI_FILENAME = '_PySimpleGUI_settings_global_.json' # location of the global PySimpleGUI settings + # ====================================================================== # # One-liner functions that are handy as f_ck # @@ -574,18 +572,18 @@ DEFAULT_USER_SETTINGS_PYSIMPLEGUI_FILENAME = '_PySimpleGUI_settings_global_.json def rgb(red, green, blue): """ Given integer values of Red, Green, Blue, return a color string "#RRGGBB" - :param red: Red portion from 0 to 255 - :type red: (int) + :param red: Red portion from 0 to 255 + :type red: (int) :param green: Green portion from 0 to 255 - :type green: (int) - :param blue: Blue portion from 0 to 255 - :type blue: (int) - :return: A single RGB String in the format "#RRGGBB" where each pair is a hex number. - :rtype: (str) + :type green: (int) + :param blue: Blue portion from 0 to 255 + :type blue: (int) + :return: A single RGB String in the format "#RRGGBB" where each pair is a hex number. + :rtype: (str) """ - red = min(int(red),255) if red > 0 else 0 - blue = min(int(blue),255) if blue > 0 else 0 - green = min(int(green),255) if green > 0 else 0 + red = min(int(red), 255) if red > 0 else 0 + blue = min(int(blue), 255) if blue > 0 else 0 + green = min(int(green), 255) if green > 0 else 0 return '#%02x%02x%02x' % (red, green, blue) @@ -668,12 +666,12 @@ class ToolTip: def __init__(self, widget, text, timeout=DEFAULT_TOOLTIP_TIME): """ - :param widget: The tkinter widget - :type widget: widget type varies - :param text: text for the tooltip. It can inslude \n - :type text: (str) + :param widget: The tkinter widget + :type widget: widget type varies + :param text: text for the tooltip. It can inslude \n + :type text: (str) :param timeout: Time in milliseconds that mouse must remain still before tip is shown - :type timeout: (int) + :type timeout: (int) """ self.widget = widget self.text = text @@ -689,7 +687,7 @@ class ToolTip: def enter(self, event=None): """ Called by tkinter when mouse enters a widget - :param event: from tkinter. Has x,y coordinates of mouse + :param event: from tkinter. Has x,y coordinates of mouse """ self.x = event.x @@ -699,7 +697,7 @@ class ToolTip: def leave(self, event=None): """ Called by tktiner when mouse exits a widget - :param event: from tkinter. Event info that's not used by function. + :param event: from tkinter. Event info that's not used by function. """ self.unschedule() @@ -737,7 +735,6 @@ class ToolTip: self.tipwindow.wm_geometry("+%d+%d" % (x, y)) self.tipwindow.wm_attributes("-topmost", 1) - label = ttk.Label(self.tipwindow, text=self.text, justify=tk.LEFT, background=TOOLTIP_BACKGROUND_COLOR, relief=tk.SOLID, borderwidth=1) if TOOLTIP_FONT is not None: @@ -771,28 +768,28 @@ class Element(): """ Element base class. Only used internally. User will not create an Element object by itself - :param type: The type of element. These constants all start with "ELEM_TYPE_" - :type type: (int) (could be enum) - :param size: w=characters-wide, h=rows-high - :type size: (int, int) (width, height) - :param auto_size_text: True if the Widget should be shrunk to exactly fit the number of chars to show - :type auto_size_text: bool - :param font: specifies the font family, size, etc (see docs for exact formats) - :type font: str | (str, int) + :param type: The type of element. These constants all start with "ELEM_TYPE_" + :type type: (int) (could be enum) + :param size: w=characters-wide, h=rows-high + :type size: (int, int) (width, height) + :param auto_size_text: True if the Widget should be shrunk to exactly fit the number of chars to show + :type auto_size_text: bool + :param font: specifies the font family, size, etc (see docs for exact formats) + :type font: str | (str, int) :param background_color: color of background. Can be in #RRGGBB format or a color name "black" - :type background_color: (str) - :param text_color: element's text color. Can be in #RRGGBB format or a color name "black" - :type text_color: (str) - :param key: Identifies an Element. Should be UNIQUE to this window. - :type key: str | int | tuple | object - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param visible: set visibility state of the element (Default = True) - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type background_color: (str) + :param text_color: element's text color. Can be in #RRGGBB format or a color name "black" + :type text_color: (str) + :param key: Identifies an Element. Should be UNIQUE to this window. + :type key: str | int | tuple | object + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param visible: set visibility state of the element (Default = True) + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Size = size self.Type = type @@ -820,12 +817,12 @@ class Element(): self._visible = visible self.TKRightClickMenu = None self.Widget = None # Set when creating window. Has the main tkinter widget for element - self.Tearoff = False # needed because of right click menu code + self.Tearoff = False # needed because of right click menu code self.ParentRowFrame = None # type tk.Frame self.metadata = metadata self.user_bind_dict = {} # Used when user defines a tkinter binding using bind method - convert bind string to key modifier self.user_bind_event = None # Used when user defines a tkinter binding using bind method - event data from tkinter - self.pad_used = (0,0) # the amount of pad used when was inserted into the layout + self.pad_used = (0, 0) # the amount of pad used when was inserted into the layout self._popup_menu_location = (None, None) if not hasattr(self, 'DisabledTextColor'): @@ -840,31 +837,28 @@ class Element(): """ Returns visibility state for the element. This is a READONLY property :return: Visibility state for element - :rtype: (bool) + :rtype: (bool) """ return self._visible - @property def metadata(self): """ Metadata is an Element property that you can use at any time to hold any value :return: the current metadata value - :rtype: (Any) + :rtype: (Any) """ return self._metadata - @metadata.setter def metadata(self, value): """ Metadata is an Element property that you can use at any time to hold any value :param value: Anything you want it to be - :type value: (Any) + :type value: (Any) """ self._metadata = value - def _RightClickMenuCallback(self, event): """ Callback function that's called when a right click happens. Shows right click menu as result @@ -877,8 +871,6 @@ class Element(): if self.Type == ELEM_TYPE_GRAPH: self._update_position_for_returned_values(event) - - def _tearoff_menu_callback(self, parent, menu): """ Callback function that's called when a right click menu is torn off. @@ -886,7 +878,7 @@ class Element(): This callback moves the right click menu window to the location of the current window :param parent: information provided by tkinter - the parent of the Meny - :param menu: information provided by tkinter - the menu window + :param menu: information provided by tkinter - the menu window """ if self._popup_menu_location == (None, None): @@ -896,13 +888,12 @@ class Element(): # self.ParentForm.TKroot.update() self.ParentForm.TKroot.tk.call('wm', 'geometry', menu, "+{}+{}".format(winx, winy)) - def _MenuItemChosenCallback(self, item_chosen): # TEXT Menu item callback """ Callback function called when user chooses a menu item from menubar, Button Menu or right click menu :param item_chosen: String holding the value chosen. - :type item_chosen: str + :type item_chosen: str """ # print('IN MENU ITEM CALLBACK', item_chosen) @@ -913,15 +904,14 @@ class Element(): # Window._window_that_exited = self.ParentForm # self.ParentForm.TKroot.quit() # kick the users out of the mainloop - def _FindReturnKeyBoundButton(self, form): """ Searches for which Button has the flag Button.BindReturnKey set. It is called recursively when a "Container Element" is encountered. Func has to walk entire window including these "sub-forms" :param form: the Window object to search - :return: Button Object if a button is found, else None - :rtype: Button | None + :return: Button Object if a button is found, else None + :rtype: Button | None """ for row in form.Rows: for element in row: @@ -950,7 +940,6 @@ class Element(): return rc return None - def _TextClickedHandler(self, event): """ Callback that's called when a text element is clicked on with events enabled on the Text Element. @@ -987,7 +976,6 @@ class Element(): self._generic_callback_handler(self.DisplayText) return - def _titlebar_restore(self, event): if running_linux(): # if self._skip_first_restore_callback: @@ -1004,8 +992,6 @@ class Element(): self.ParentForm.TKroot.wm_overrideredirect(True) self.ParentForm.normal() - - def _ReturnKeyHandler(self, event): """ Internal callback for the ENTER / RETURN key. Results in calling the ButtonCallBack for element that has the return key bound to it, just as if button was clicked. @@ -1018,16 +1004,15 @@ class Element(): if button_element is not None: button_element.ButtonCallBack() - def _generic_callback_handler(self, alternative_to_key=None, force_key_to_be=None): """ Peforms the actions that were in many of the callback functions previously. Combined so that it's easier to modify and is in 1 place now - :param event: From tkinter and is not used - :type event: Any + :param event: From tkinter and is not used + :type event: Any :param alternate_to_key: If key is None, then use this value instead - :type alternate_to_key: Any + :type alternate_to_key: Any """ if force_key_to_be is not None: self.ParentForm.LastButtonClicked = force_key_to_be @@ -1042,8 +1027,6 @@ class Element(): # Window._window_that_exited = self.ParentForm # self.ParentForm.TKroot.quit() # kick the users out of the mainloop - - def _ListboxSelectHandler(self, event): """ Internal callback function for when a listbox item is selected @@ -1061,21 +1044,18 @@ class Element(): """ self._generic_callback_handler('') - def _RadioHandler(self): """ Internal callback for when a radio button is selected and enable events was set for radio """ self._generic_callback_handler('') - def _CheckboxHandler(self): """ Internal callback for when a checkbnox is selected and enable events was set for checkbox """ self._generic_callback_handler('') - def _TabGroupSelectHandler(self, event): """ Internal callback for when a Tab is selected and enable events was set for TabGroup @@ -1084,7 +1064,6 @@ class Element(): """ self._generic_callback_handler('') - def _KeyboardHandler(self, event): """ Internal callback for when a key is pressed andd return keyboard events was set for window @@ -1093,7 +1072,6 @@ class Element(): """ self._generic_callback_handler('') - def _ClickHandler(self, event): """ Internal callback for when a mouse was clicked... I think. @@ -1102,14 +1080,13 @@ class Element(): """ self._generic_callback_handler('') - def _user_bind_callback(self, bind_string, event): """ Used when user binds a tkinter event directly to an element :param bind_string: The event that was bound so can lookup the key modifier - :type bind_string: Mike_please_insert_type_here - :param event: Event data passed in by tkinter (not used) + :type bind_string: Mike_please_insert_type_here + :param event: Event data passed in by tkinter (not used) """ key_suffix = self.user_bind_dict.get(bind_string, '') self.user_bind_event = event @@ -1119,48 +1096,45 @@ class Element(): if isinstance(self.Key, str): key = self.Key + str(key_suffix) else: - key = (self.Key, key_suffix) # old way (pre 2021) was to make a brand new tuple + key = (self.Key, key_suffix) # old way (pre 2021) was to make a brand new tuple # key = self.Key + (key_suffix,) # in 2021 tried this. It will break existing applications though - if key is a tuple, add one more item else: key = bind_string self._generic_callback_handler(force_key_to_be=key) - def bind(self, bind_string, key_modifier): """ Used to add tkinter events to an Element. The tkinter specific data is in the Element's member variable user_bind_event - :param bind_string: The string tkinter expected in its bind function - :type bind_string: (str) + :param bind_string: The string tkinter expected in its bind function + :type bind_string: (str) :param key_modifier: Additional data to be added to the element's key when event is returned - :type key_modifier: (str) + :type key_modifier: (str) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return self.Widget.bind(bind_string, lambda evt: self._user_bind_callback(bind_string, evt)) self.user_bind_dict[bind_string] = key_modifier - def unbind(self, bind_string): """ Removes a previously bound tkinter event from an Element. :param bind_string: The string tkinter expected in its bind function - :type bind_string: (str) + :type bind_string: (str) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return self.Widget.unbind(bind_string) self.user_bind_dict.pop(bind_string, None) - def set_tooltip(self, tooltip_text): """ Called by application to change the tooltip text for an Element. Normally invoked using the Element Object such as: window.Element('key').SetToolTip('New tip'). :param tooltip_text: the text to show in tooltip. - :type tooltip_text: (str) + :type tooltip_text: (str) """ if self.TooltipObject: @@ -1171,13 +1145,12 @@ class Element(): self.TooltipObject = ToolTip(self.Widget, text=tooltip_text, timeout=DEFAULT_TOOLTIP_TIME) - def set_focus(self, force=False): """ Sets the current focus to be on this element :param force: if True will call focus_force otherwise calls focus_set - :type force: bool + :type force: bool """ try: @@ -1188,7 +1161,6 @@ class Element(): except: print('Was unable to set focus. The Widget passed in was perhaps not present in this element? Check your elements .Widget property') - def block_focus(self, block=True): """ Enable or disable the element from getting focus by using the keyboard. @@ -1197,9 +1169,9 @@ class Element(): You CAN click on the element and utilize it. :param block: if True the element will not get focus via the keyboard - :type block: bool + :type block: bool """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return try: self.ParentForm.TKroot.focus_force() @@ -1210,14 +1182,13 @@ class Element(): except: print('Was unable to block the focus. Check your elements .Widget property') - def set_size(self, size=(None, None)): """ Changes the size of an element to a specific size. It's possible to specify None for one of sizes so that only 1 of the element's dimensions are changed. :param size: The size in characters, rows typically. In some cases they are pixels - :type size: (int, int) + :type size: (int, int) """ try: if size[0] != None: @@ -1233,12 +1204,11 @@ class Element(): except: print('Warning, error setting height on element with key=', self.Key) - def get_size(self): """ Return the size of an element in Pixels. Care must be taken as some elements use characters to specify their size but will return pixels when calling this get_size method. :return: width and height of the element - :rtype: (int, int) + :rtype: (int, int) """ try: w = self.Widget.winfo_width() @@ -1248,7 +1218,6 @@ class Element(): w = h = None return w, h - def hide_row(self): """ Hide the entire row an Element is located on. @@ -1259,7 +1228,6 @@ class Element(): except: print('Warning, error hiding element row for key =', self.Key) - def unhide_row(self): """ Unhides (makes visible again) the row container that the Element is located on. @@ -1270,17 +1238,16 @@ class Element(): except: print('Warning, error hiding element row for key =', self.Key) - def expand(self, expand_x=False, expand_y=False, expand_row=True): """ Causes the Element to expand to fill available space in the X and Y directions. Can specify which or both directions - :param expand_x: If True Element will expand in the Horizontal directions - :type expand_x: (bool) - :param expand_y: If True Element will expand in the Vertical directions - :type expand_y: (bool) + :param expand_x: If True Element will expand in the Horizontal directions + :type expand_x: (bool) + :param expand_y: If True Element will expand in the Vertical directions + :type expand_y: (bool) :param expand_row: If True the row containing the element will also expand. Without this your element is "trapped" within the row - :type expand_row: (bool) + :type expand_row: (bool) """ if expand_x and expand_y: fill = tk.BOTH @@ -1298,8 +1265,7 @@ class Element(): if self.element_frame is not None: self.element_frame.pack(expand=True, fill=fill) - - def set_cursor(self,cursor=None, cursor_color=None): + def set_cursor(self, cursor=None, cursor_color=None): """ Sets the cursor for the current Element. "Cursor" is used in 2 different ways in this call. @@ -1307,10 +1273,10 @@ class Element(): If you do not want any mouse pointer, then use the string "none" For the parameter "cursor_color" it's the color of the beam used when typing into an input element - :param cursor: The tkinter cursor name - :type cursor: (str) + :param cursor: The tkinter cursor name + :type cursor: (str) :param cursor_color: color to set the "cursor" to - :type cursor_color: (str) + :type cursor_color: (str) """ if not self._widget_was_created(): return @@ -1327,12 +1293,11 @@ class Element(): print('Warning bad cursor color', cursor_color) print(e) - def set_vscroll_position(self, percent_from_top): """ Attempts to set the vertical scroll postition for an element's Widget :param percent_from_top: From 0 to 1.0, the percentage from the top to move scrollbar to - :type percent_from_top: (float) + :type percent_from_top: (float) """ try: self.Widget.yview_moveto(percent_from_top) @@ -1340,28 +1305,27 @@ class Element(): print('Warning setting the vertical scroll (yview_moveto failed)') print(e) - def _widget_was_created(self): """ Determines if a Widget was created for this element. :return: True if a Widget has been created previously (Widget is not None) - :rtype: (bool) + :rtype: (bool) """ if self.Widget is not None: return True else: - warnings.warn('You cannot Update element with key = {} until the window.read() is called or finalized=True when creating window'.format(self.Key), UserWarning) + warnings.warn('You cannot Update element with key = {} until the window.read() is called or finalized=True when creating window'.format(self.Key), + UserWarning) if not SUPPRESS_ERROR_POPUPS: _error_popup_with_traceback('Unable to complete operation on element with key {}'.format(self.Key), - 'You cannot perform operations (such as calling update) on an Element until:', - ' window.read() is called or finalize=True when Window created.', - 'Adding a "finalize=True" parameter to your Window creation will likely fix this.', - _create_error_message(), - ) + 'You cannot perform operations (such as calling update) on an Element until:', + ' window.read() is called or finalize=True when Window created.', + 'Adding a "finalize=True" parameter to your Window creation will likely fix this.', + _create_error_message(), + ) return False - def _grab_anywhere_on(self): """ Turns on Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet @@ -1371,7 +1335,6 @@ class Element(): self.Widget.bind("", self.ParentForm._StopMove) self.Widget.bind("", self.ParentForm._OnMotion) - def _grab_anywhere_off(self): """ Turns off Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet @@ -1381,7 +1344,6 @@ class Element(): self.Widget.unbind("") self.Widget.unbind("") - def grab_anywhere_exclude(self): """ Excludes this element from being used by the grab_anywhere feature @@ -1389,8 +1351,6 @@ class Element(): """ self.ParentForm._grab_anywhere_ignore_these_list.append(self.Widget) - - def grab_anywhere_include(self): """ Includes this element in the grab_anywhere feature @@ -1398,7 +1358,6 @@ class Element(): """ self.ParentForm._grab_anywhere_include_these_list.append(self.Widget) - def update(self, *args, **kwargs): """ A dummy update call. This will only be called if an element hasn't implemented an update method @@ -1407,9 +1366,6 @@ class Element(): """ print('* Base Element Class update was called. Your element does not seem to have an update method') - - - def __call__(self, *args, **kwargs): """ Makes it possible to "call" an already existing element. When you do make the "call", it actually calls @@ -1432,61 +1388,63 @@ class Input(Element): """ Display a single text input field. Based on the tkinter Widget `Entry` """ + def __init__(self, default_text='', size=(None, None), s=(None, None), disabled=False, password_char='', justification=None, background_color=None, text_color=None, font=None, tooltip=None, border_width=None, change_submits=False, enable_events=False, do_not_clear=True, key=None, k=None, focus=False, pad=None, - use_readonly_for_disable=True, readonly=False, disabled_readonly_background_color=None, disabled_readonly_text_color=None, right_click_menu=None, visible=True, metadata=None): + use_readonly_for_disable=True, readonly=False, disabled_readonly_background_color=None, disabled_readonly_text_color=None, + right_click_menu=None, visible=True, metadata=None): """ - :param default_text: Text initially shown in the input box as a default value(Default value = ''). Will automatically be converted to string - :type default_text: (Any) - :param size: w=characters-wide, h=rows-high - :type size: (int, int) | (None, None) - :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) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param password_char: Password character if this is a password field (Default value = '') - :type password_char: (char) - :param justification: justification for data display. Valid choices - left, right, center - :type justification: (str) - :param background_color: color of background in one of the color formats - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param border_width: width of border around element in pixels - :type border_width: (int) - :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead - :type change_submits: (bool) - :param enable_events: If True then changes to this element are immediately reported as an event. Use this instead of change_submits (Default = False) - :type enable_events: (bool) - :param do_not_clear: If False then the field will be set to blank after ANY event (button, any event) (Default = True) - :type do_not_clear: (bool) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param focus: Determines if initial focus should go to this element. - :type focus: (bool) - :param pad: Amount of padding to put around element. Normally (horizontal pixels, vertical pixels) but can be split apart further into ((horizontal left, horizontal right), (vertical above, vertical below)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param use_readonly_for_disable: If True (the default) tkinter state set to 'readonly'. Otherwise state set to 'disabled' - :type use_readonly_for_disable: (bool) - :param readonly: If True tkinter state set to 'readonly'. Use this in place of use_readonly_for_disable as another way of achieving readonly. Note cannot set BOTH readonly and disabled as tkinter only supplies a single flag - :type readonly: (bool) + :param default_text: Text initially shown in the input box as a default value(Default value = ''). Will automatically be converted to string + :type default_text: (Any) + :param size: w=characters-wide, h=rows-high + :type size: (int, int) | (None, None) + :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) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param password_char: Password character if this is a password field (Default value = '') + :type password_char: (char) + :param justification: justification for data display. Valid choices - left, right, center + :type justification: (str) + :param background_color: color of background in one of the color formats + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param border_width: width of border around element in pixels + :type border_width: (int) + :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead + :type change_submits: (bool) + :param enable_events: If True then changes to this element are immediately reported as an event. Use this instead of change_submits (Default = False) + :type enable_events: (bool) + :param do_not_clear: If False then the field will be set to blank after ANY event (button, any event) (Default = True) + :type do_not_clear: (bool) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param focus: Determines if initial focus should go to this element. + :type focus: (bool) + :param pad: Amount of padding to put around element. Normally (horizontal pixels, vertical pixels) but can be split apart further into ((horizontal left, horizontal right), (vertical above, vertical below)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param use_readonly_for_disable: If True (the default) tkinter state set to 'readonly'. Otherwise state set to 'disabled' + :type use_readonly_for_disable: (bool) + :param readonly: If True tkinter state set to 'readonly'. Use this in place of use_readonly_for_disable as another way of achieving readonly. Note cannot set BOTH readonly and disabled as tkinter only supplies a single flag + :type readonly: (bool) :param disabled_readonly_background_color: If state is set to readonly or disabled, the color to use for the background - :type disabled_readonly_background_color: (str) - :param disabled_readonly_text_color: If state is set to readonly or disabled, the color to use for the text - :type disabled_readonly_text_color: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element (Default = True) - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type disabled_readonly_background_color: (str) + :param disabled_readonly_text_color: If state is set to readonly or disabled, the color to use for the text + :type disabled_readonly_text_color: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element (Default = True) + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.DefaultText = default_text if default_text is not None else '' @@ -1515,24 +1473,24 @@ class Input(Element): """ Changes some of the settings for the Input Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: new text to display as default text in Input field - :type value: (str) - :param disabled: disable or enable state of the element (sets Entry Widget to readonly or normal) - :type disabled: (bool) - :param select: if True, then the text will be selected - :type select: (bool) - :param visible: change visibility of element - :type visible: (bool) - :param text_color: change color of text being typed - :type text_color: (str) + :param value: new text to display as default text in Input field + :type value: (str) + :param disabled: disable or enable state of the element (sets Entry Widget to readonly or normal) + :type disabled: (bool) + :param select: if True, then the text will be selected + :type select: (bool) + :param visible: change visibility of element + :type visible: (bool) + :param text_color: change color of text being typed + :type text_color: (str) :param background_color: change color of the background - :type background_color: (str) - :param move_cursor_to: Moves the cursor to a particular offset. Defaults to 'end' - :type move_cursor_to: int | str - :param password_char: Password character if this is a password field - :type password_char: str + :type background_color: (str) + :param move_cursor_to: Moves the cursor to a particular offset. Defaults to 'end' + :type move_cursor_to: int | str + :param password_char: Password character if this is a password field + :type password_char: str """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if disabled is True: self.TKEntry['state'] = 'readonly' if self.UseReadonlyForDisable else 'disabled' @@ -1565,14 +1523,12 @@ class Input(Element): self.TKEntry.configure(show=password_char) self.PasswordCharacter = password_char - - def get(self): """ Read and return the current value of the input element. Must call `Window.Read` or `Window.Finalize` prior :return: current value of Input field or '' if error encountered - :rtype: (str) + :rtype: (str) """ try: text = self.TKStringVar.get() @@ -1590,7 +1546,6 @@ InputText = Input I = Input - # ---------------------------------------------------------------------- # # Combo # # ---------------------------------------------------------------------- # @@ -1603,44 +1558,44 @@ class Combo(Element): text_color=None, bind_return_key=False, change_submits=False, enable_events=False, disabled=False, key=None, k=None, pad=None, tooltip=None, readonly=False, font=None, visible=True, metadata=None): """ - :param values: values to choose. While displayed as text, the items returned are what the caller supplied, not text - :type values: List[Any] or Tuple[Any] - :param default_value: Choice to be displayed as initial value. Must match one of values variable contents - :type default_value: (Any) - :param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list - :type size: (int, int) | (None, None) - :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) - :param auto_size_text: True if element should be the same size as the contents - :type auto_size_text: (bool) + :param values: values to choose. While displayed as text, the items returned are what the caller supplied, not text + :type values: List[Any] or Tuple[Any] + :param default_value: Choice to be displayed as initial value. Must match one of values variable contents + :type default_value: (Any) + :param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list + :type size: (int, int) | (None, None) + :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) + :param auto_size_text: True if element should be the same size as the contents + :type auto_size_text: (bool) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param bind_return_key: If True, then the return key will cause a the Combo to generate an event - :type bind_return_key: (bool) - :param change_submits: DEPRICATED DO NOT USE. Use `enable_events` instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Combo event is when a choice is made - :type enable_events: (bool) - :param disabled: set disable state for element - :type disabled: (bool) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text that will appear when mouse hovers over this element - :type tooltip: (str) - :param readonly: make element readonly (user can't change). True means user cannot change - :type readonly: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param bind_return_key: If True, then the return key will cause a the Combo to generate an event + :type bind_return_key: (bool) + :param change_submits: DEPRICATED DO NOT USE. Use `enable_events` instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Combo event is when a choice is made + :type enable_events: (bool) + :param disabled: set disable state for element + :type disabled: (bool) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text that will appear when mouse hovers over this element + :type tooltip: (str) + :param readonly: make element readonly (user can't change). True means user cannot change + :type readonly: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Values = values self.DefaultValue = default_value @@ -1663,24 +1618,24 @@ class Combo(Element): Note that the state can be in 3 states only.... enabled, disabled, readonly even though more combinations are available. The easy way to remember is that if you change the readonly parameter then you are enabling the element. - :param value: change which value is current selected based on new list of previous list of choices - :type value: (Any) - :param values: change list of choices - :type values: List[Any] + :param value: change which value is current selected based on new list of previous list of choices + :type value: (Any) + :param values: change list of choices + :type values: List[Any] :param set_to_index: change selection to a particular choice starting with index = 0 - :type set_to_index: (int) - :param disabled: disable or enable state of the element - :type disabled: (bool) - :param readonly: if True make element readonly (user cannot change any choices). Enables the element if either choice are made. - :type readonly: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param visible: control visibility of element - :type visible: (bool) - :param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list - :type size: (int, int) + :type set_to_index: (int) + :param disabled: disable or enable state of the element + :type disabled: (bool) + :param readonly: if True make element readonly (user cannot change any choices). Enables the element if either choice are made. + :type readonly: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param visible: control visibility of element + :type visible: (bool) + :param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list + :type size: (int, int) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if values is not None: try: @@ -1744,7 +1699,7 @@ class Combo(Element): You should be using values from your call to window.read instead. Know what you're doing if you use it. :return: Returns the value of what is currently chosen - :rtype: Any | None + :rtype: Any | None """ try: if self.TKCombo.current() == -1: # if the current value was not in the original list @@ -1780,34 +1735,34 @@ class OptionMenu(Element): def __init__(self, values, default_value=None, size=(None, None), s=(None, None), disabled=False, auto_size_text=None, background_color=None, text_color=None, key=None, k=None, pad=None, tooltip=None, visible=True, metadata=None): """ - :param values: Values to be displayed - :type values: List[Any] or Tuple[Any] - :param default_value: the value to choose by default - :type default_value: (Any) - :param size: (width, height) size in characters (wide), height is ignored and present to be consistent with other elements - :type size: (int, int) (width, UNUSED) - :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) - :param disabled: control enabled / disabled - :type disabled: (bool) - :param auto_size_text: True if size of Element should match the contents of the items - :type auto_size_text: (bool) + :param values: Values to be displayed + :type values: List[Any] or Tuple[Any] + :param default_value: the value to choose by default + :type default_value: (Any) + :param size: (width, height) size in characters (wide), height is ignored and present to be consistent with other elements + :type size: (int, int) (width, UNUSED) + :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) + :param disabled: control enabled / disabled + :type disabled: (bool) + :param auto_size_text: True if size of Element should match the contents of the items + :type auto_size_text: (bool) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text that will appear when mouse hovers over this element - :type tooltip: (str) - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text that will appear when mouse hovers over this element + :type tooltip: (str) + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Values = values self.DefaultValue = default_value @@ -1824,18 +1779,18 @@ class OptionMenu(Element): def update(self, value=None, values=None, disabled=None, visible=None, size=(None, None)): """ Changes some of the settings for the OptionMenu Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: the value to choose by default - :type value: (Any) - :param values: Values to be displayed - :type values: List[Any] + :param value: the value to choose by default + :type value: (Any) + :param values: Values to be displayed + :type values: List[Any] :param disabled: disable or enable state of the element - :type disabled: (bool) - :param visible: control visibility of element - :type visible: (bool) - :param size: (width, height) size in characters (wide), height is ignored and present to be consistent with other elements - :type size: (int, int) (width, UNUSED) + :type disabled: (bool) + :param visible: control visibility of element + :type visible: (bool) + :param size: (width, height) size in characters (wide), height is ignored and present to be consistent with other elements + :type size: (int, int) (width, UNUSED) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if values is not None: @@ -1859,7 +1814,6 @@ class OptionMenu(Element): else: self.TKOptionMenu.configure(width=size[0]) - if value is not None: self.DefaultValue = value self.TKStringVar.set(value) @@ -1896,53 +1850,53 @@ class Listbox(Element): background_color=None, text_color=None, highlight_background_color=None, highlight_text_color=None, key=None, k=None, pad=None, tooltip=None, right_click_menu=None, visible=True, metadata=None): """ - :param values: list of values to display. Can be any type including mixed types as long as they have __str__ method - :type values: List[Any] or Tuple[Any] - :param default_values: which values should be initially selected - :type default_values: List[Any] - :param select_mode: Select modes are used to determine if only 1 item can be selected or multiple and how they can be selected. Valid choices begin with "LISTBOX_SELECT_MODE_" and include: LISTBOX_SELECT_MODE_SINGLE LISTBOX_SELECT_MODE_MULTIPLE LISTBOX_SELECT_MODE_BROWSE LISTBOX_SELECT_MODE_EXTENDED - :type select_mode: [enum] - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Listbox generates events when an item is clicked - :type enable_events: (bool) - :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param size: width = characters-wide, height = rows-high - :type size: (int, int) | (None, None) - :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) - :param disabled: set disable state for element - :type disabled: (bool) - :param auto_size_text: True if element should be the same size as the contents - :type auto_size_text: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param font: specifies the font family, size, etc - :param no_scrollbar: Controls if a scrollbar should be shown. If True, no scrollbar will be shown - :type no_scrollbar: (bool) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) + :param values: list of values to display. Can be any type including mixed types as long as they have __str__ method + :type values: List[Any] or Tuple[Any] + :param default_values: which values should be initially selected + :type default_values: List[Any] + :param select_mode: Select modes are used to determine if only 1 item can be selected or multiple and how they can be selected. Valid choices begin with "LISTBOX_SELECT_MODE_" and include: LISTBOX_SELECT_MODE_SINGLE LISTBOX_SELECT_MODE_MULTIPLE LISTBOX_SELECT_MODE_BROWSE LISTBOX_SELECT_MODE_EXTENDED + :type select_mode: [enum] + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Listbox generates events when an item is clicked + :type enable_events: (bool) + :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param size: width = characters-wide, height = rows-high + :type size: (int, int) | (None, None) + :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) + :param disabled: set disable state for element + :type disabled: (bool) + :param auto_size_text: True if element should be the same size as the contents + :type auto_size_text: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param font: specifies the font family, size, etc + :param no_scrollbar: Controls if a scrollbar should be shown. If True, no scrollbar will be shown + :type no_scrollbar: (bool) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) :param highlight_background_color: color of the background when an item is selected. Defaults to normal text color (a reverse look) - :type highlight_background_color: (str) - :param highlight_text_color: color of the text when an item is selected. Defaults to the normal background color (a rerverse look) - :type highlight_text_color: (str) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type highlight_background_color: (str) + :param highlight_text_color: color of the text when an item is selected. Defaults to the normal background color (a rerverse look) + :type highlight_text_color: (str) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Values = values self.DefaultValues = default_values @@ -1967,7 +1921,7 @@ class Listbox(Element): self.RightClickMenu = right_click_menu self.vsb = None # type: tk.Scrollbar self.TKListbox = self.Widget = None # type: tk.Listbox - self.element_frame = None # type: tk.Frame + self.element_frame = None # type: tk.Frame self.NoScrollbar = no_scrollbar key = key if key is not None else k sz = size if size != (None, None) else s @@ -1978,21 +1932,21 @@ class Listbox(Element): def update(self, values=None, disabled=None, set_to_index=None, scroll_to_index=None, select_mode=None, visible=None): """ Changes some of the settings for the Listbox Element. Must call `Window.Read` or `Window.Finalize` prior - :param values: new list of choices to be shown to user - :type values: List[Any] - :param disabled: disable or enable state of the element - :type disabled: (bool) - :param set_to_index: highlights the item(s) indicated. If parm is an int one entry will be set. If is a list, then each entry in list is highlighted - :type set_to_index: int | list | tuple + :param values: new list of choices to be shown to user + :type values: List[Any] + :param disabled: disable or enable state of the element + :type disabled: (bool) + :param set_to_index: highlights the item(s) indicated. If parm is an int one entry will be set. If is a list, then each entry in list is highlighted + :type set_to_index: int | list | tuple :param scroll_to_index: scroll the listbox so that this index is the first shown - :type scroll_to_index: (int) - :param select_mode: changes the select mode according to tkinter's listbox widget - :type select_mode: (str) - :param visible: control visibility of element - :type visible: (bool) + :type scroll_to_index: (int) + :param select_mode: changes the select mode according to tkinter's listbox widget + :type select_mode: (str) + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if disabled is True: @@ -2041,7 +1995,7 @@ class Listbox(Element): Set listbox highlighted choices :param values: new values to choose based on previously set values - :type values: List[Any] | Tuple[Any] + :type values: List[Any] | Tuple[Any] """ for index, item in enumerate(self.Values): @@ -2060,7 +2014,7 @@ class Listbox(Element): Returns list of Values provided by the user in the user's format :return: List of values. Can be any / mixed types -> [] - :rtype: List[Any] + :rtype: List[Any] """ return self.Values @@ -2069,18 +2023,17 @@ class Listbox(Element): Returns the items currently selected as a list of indexes :return: A list of offsets into values that is currently selected - :rtype: List[int] + :rtype: List[int] """ return self.TKListbox.curselection() - def get(self): """ Returns the list of items currently selected in this listbox. It should be identical to the value you would receive when performing a window.read() call. :return: The list of currently selected items. The actual items are returned, not the indexes - :rtype: List[Any] + :rtype: List[Any] """ try: items = self.TKListbox.curselection() @@ -2089,7 +2042,6 @@ class Listbox(Element): value = [] return value - GetIndexes = get_indexes GetListValues = get_list_values SetValue = set_value @@ -2155,7 +2107,6 @@ class Radio(Element): :type metadata: (Any) """ - self.InitialState = default self.Text = text self.Widget = self.TKRadio = None # type: tk.Radiobutton @@ -2167,14 +2118,14 @@ class Radio(Element): if circle_color is None: # ---- compute color of circle background --- - try: # something in here will fail if a color is not specified in Hex + try: # something in here will fail if a color is not specified in Hex text_hsl = _hex_to_hsl(self.TextColor) background_hsl = _hex_to_hsl(background_color if background_color else theme_background_color()) - l_delta = abs(text_hsl[2] - background_hsl[2])/10 - if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2]-l_delta) + l_delta = abs(text_hsl[2] - background_hsl[2]) / 10 + if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] - l_delta) else: - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1],background_hsl[2]+l_delta) + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] + l_delta) self.CircleBackgroundColor = rgb(*bg_rbg) except: self.CircleBackgroundColor = background_color if background_color else theme_background_color() @@ -2192,23 +2143,23 @@ class Radio(Element): def update(self, value=None, text=None, background_color=None, text_color=None, circle_color=None, disabled=None, visible=None): """ Changes some of the settings for the Radio Button Element. Must call `Window.read` or `Window.finalize` prior - :param value: if True change to selected and set others in group to unselected - :type value: (bool) - :param text: Text to display next to radio button - :type text: (str) + :param value: if True change to selected and set others in group to unselected + :type value: (bool) + :param text: Text to display next to radio button + :type text: (str) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text. Note this also changes the color of the selection dot - :type text_color: (str) - :param circle_color: color of background of the circle that has the dot selection indicator in it - :type circle_color: (str) - :param disabled: disable or enable state of the element - :type disabled: (bool) - :param visible: control visibility of element - :type visible: (bool) + :type background_color: (str) + :param text_color: color of the text. Note this also changes the color of the selection dot + :type text_color: (str) + :param circle_color: color of background of the circle that has the dot selection indicator in it + :type circle_color: (str) + :param disabled: disable or enable state of the element + :type disabled: (bool) + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if value is not None: @@ -2235,15 +2186,16 @@ class Radio(Element): self.CircleBackgroundColor = circle_color self.TKRadio.configure(selectcolor=self.CircleBackgroundColor) # The background of the radio button elif text_color or background_color: - if self.TextColor not in (None, COLOR_SYSTEM_DEFAULT) and self.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT) and self.TextColor.startswith('#') and self.BackgroundColor.startswith('#'): + if self.TextColor not in (None, COLOR_SYSTEM_DEFAULT) and self.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT) and self.TextColor.startswith( + '#') and self.BackgroundColor.startswith('#'): # ---- compute color of circle background --- text_hsl = _hex_to_hsl(self.TextColor) background_hsl = _hex_to_hsl(self.BackgroundColor if self.BackgroundColor else theme_background_color()) - l_delta = abs(text_hsl[2] - background_hsl[2])/10 - if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2]-l_delta) + l_delta = abs(text_hsl[2] - background_hsl[2]) / 10 + if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] - l_delta) else: - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1],background_hsl[2]+l_delta) + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] + l_delta) self.CircleBackgroundColor = rgb(*bg_rbg) self.TKRadio.configure(selectcolor=self.CircleBackgroundColor) # The background of the checkbox @@ -2270,7 +2222,7 @@ class Radio(Element): A snapshot of the value of Radio Button -> (bool) :return: True if this radio button is selected - :rtype: (bool) + :rtype: (bool) """ return self.TKIntVar.get() == self.EncodedRadioValue @@ -2292,46 +2244,47 @@ class Checkbox(Element): """ def __init__(self, text, default=False, size=(None, None), s=(None, None), auto_size_text=None, font=None, background_color=None, - text_color=None, checkbox_color=None, change_submits=False, enable_events=False, disabled=False, key=None, k=None, pad=None, tooltip=None, right_click_menu=None, visible=True, metadata=None): + text_color=None, checkbox_color=None, change_submits=False, enable_events=False, disabled=False, key=None, k=None, pad=None, tooltip=None, + right_click_menu=None, visible=True, metadata=None): """ - :param text: Text to display next to checkbox - :type text: (str) - :param default: Set to True if you want this checkbox initially checked - :type default: (bool) - :param size: (width, height) width = characters-wide, height = rows-high - :type size: (int, int) | (None, None) - :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) - :param auto_size_text: if True will size the element to match the length of the text - :type auto_size_text: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) + :param text: Text to display next to checkbox + :type text: (str) + :param default: Set to True if you want this checkbox initially checked + :type default: (bool) + :param size: (width, height) width = characters-wide, height = rows-high + :type size: (int, int) | (None, None) + :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) + :param auto_size_text: if True will size the element to match the length of the text + :type auto_size_text: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param checkbox_color: color of background of the box that has the check mark in it. The checkmark is the same color as the text - :type checkbox_color: (str) - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Checkbox events happen when an item changes - :type enable_events: (bool) - :param disabled: set disable state - :type disabled: (bool) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param checkbox_color: color of background of the box that has the check mark in it. The checkmark is the same color as the text + :type checkbox_color: (str) + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Checkbox events happen when an item changes + :type enable_events: (bool) + :param disabled: set disable state + :type disabled: (bool) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Text = text @@ -2344,14 +2297,14 @@ class Checkbox(Element): # ---- compute color of circle background --- if checkbox_color is None: - try: # something in here will fail if a color is not specified in Hex + try: # something in here will fail if a color is not specified in Hex text_hsl = _hex_to_hsl(self.TextColor) background_hsl = _hex_to_hsl(background_color if background_color else theme_background_color()) - l_delta = abs(text_hsl[2] - background_hsl[2])/10 - if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2]-l_delta) + l_delta = abs(text_hsl[2] - background_hsl[2]) / 10 + if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] - l_delta) else: - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1],background_hsl[2]+l_delta) + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] + l_delta) self.CheckboxBackgroundColor = rgb(*bg_rbg) except: self.CheckboxBackgroundColor = background_color if background_color else theme_background_color() @@ -2371,7 +2324,7 @@ class Checkbox(Element): Return the current state of this checkbox :return: Current state of checkbox - :rtype: (bool) + :rtype: (bool) """ return self.TKIntVar.get() != 0 @@ -2379,21 +2332,21 @@ class Checkbox(Element): """ Changes some of the settings for the Checkbox Element. Must call `Window.Read` or `Window.Finalize` prior. Note that changing visibility may cause element to change locations when made visible after invisible - :param value: if True checks the checkbox, False clears it - :type value: (bool) - :param text: Text to display next to checkbox - :type text: (str) + :param value: if True checks the checkbox, False clears it + :type value: (bool) + :param text: Text to display next to checkbox + :type text: (str) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text. Note this also changes the color of the checkmark - :type text_color: (str) - :param disabled: disable or enable element - :type disabled: (bool) - :param visible: control visibility of element - :type visible: (bool) + :type background_color: (str) + :param text_color: color of the text. Note this also changes the color of the checkmark + :type text_color: (str) + :param disabled: disable or enable element + :type disabled: (bool) + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if value is not None: @@ -2421,15 +2374,16 @@ class Checkbox(Element): self.CheckboxBackgroundColor = checkbox_color self.TKCheckbutton.configure(selectcolor=self.CheckboxBackgroundColor) # The background of the checkbox elif text_color or background_color: - if self.CheckboxBackgroundColor is not None and self.TextColor is not None and self.BackgroundColor is not None and self.TextColor.startswith('#') and self.BackgroundColor.startswith('#'): + if self.CheckboxBackgroundColor is not None and self.TextColor is not None and self.BackgroundColor is not None and self.TextColor.startswith( + '#') and self.BackgroundColor.startswith('#'): # ---- compute color of checkbox background --- text_hsl = _hex_to_hsl(self.TextColor) background_hsl = _hex_to_hsl(self.BackgroundColor if self.BackgroundColor else theme_background_color()) - l_delta = abs(text_hsl[2] - background_hsl[2])/10 - if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2]-l_delta) + l_delta = abs(text_hsl[2] - background_hsl[2]) / 10 + if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] - l_delta) else: - bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1],background_hsl[2]+l_delta) + bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] + l_delta) self.CheckboxBackgroundColor = rgb(*bg_rbg) self.TKCheckbutton.configure(selectcolor=self.CheckboxBackgroundColor) # The background of the checkbox @@ -2460,46 +2414,47 @@ class Spin(Element): """ def __init__(self, values, initial_value=None, disabled=False, change_submits=False, enable_events=False, readonly=False, - size=(None, None), s=(None, None), auto_size_text=None, font=None, background_color=None, text_color=None, key=None, k=None, pad=None, tooltip=None, right_click_menu=None, visible=True, metadata=None): + size=(None, None), s=(None, None), auto_size_text=None, font=None, background_color=None, text_color=None, key=None, k=None, pad=None, + tooltip=None, right_click_menu=None, visible=True, metadata=None): """ - :param values: List of valid values - :type values: Tuple[Any] or List[Any] - :param initial_value: Initial item to show in window. Choose from list of values supplied - :type initial_value: (Any) - :param disabled: set disable state - :type disabled: (bool) - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Spin events happen when an item changes - :type enable_events: (bool) - :param readonly: Turns on the element specific events. Spin events happen when an item changes - :type readonly: (bool) - :param size: (width, height) width = characters-wide, height = rows-high - :type size: (int, int) | (None, None) - :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) - :param auto_size_text: if True will size the element to match the length of the text - :type auto_size_text: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) + :param values: List of valid values + :type values: Tuple[Any] or List[Any] + :param initial_value: Initial item to show in window. Choose from list of values supplied + :type initial_value: (Any) + :param disabled: set disable state + :type disabled: (bool) + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Spin events happen when an item changes + :type enable_events: (bool) + :param readonly: Turns on the element specific events. Spin events happen when an item changes + :type readonly: (bool) + :param size: (width, height) width = characters-wide, height = rows-high + :type size: (int, int) | (None, None) + :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) + :param auto_size_text: if True will size the element to match the length of the text + :type auto_size_text: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Values = values @@ -2525,19 +2480,19 @@ class Spin(Element): Note that the state can be in 3 states only.... enabled, disabled, readonly even though more combinations are available. The easy way to remember is that if you change the readonly parameter then you are enabling the element. - :param value: set the current value from list of choices - :type value: (Any) - :param values: set available choices - :type values: List[Any] + :param value: set the current value from list of choices + :type value: (Any) + :param values: set available choices + :type values: List[Any] :param disabled: disable. Note disabled and readonly cannot be mixed. It must be one OR the other - :type disabled: (bool) + :type disabled: (bool) :param readonly: make element readonly. Note disabled and readonly cannot be mixed. It must be one OR the other - :type readonly: (bool) - :param visible: control visibility of element - :type visible: (bool) + :type readonly: (bool) + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if values != None: @@ -2597,7 +2552,7 @@ class Spin(Element): item returned will be an int (not a string) :return: The currently visible entry - :rtype: (Any) + :rtype: (Any) """ value = self.TKStringVar.get() for v in self.Values: @@ -2608,7 +2563,10 @@ class Spin(Element): Get = get Update = update -Sp = Spin # type: Spin + + +Sp = Spin # type: Spin + # ---------------------------------------------------------------------- # # Multiline # @@ -2622,73 +2580,75 @@ class Multiline(Element): def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, border_width=None, size=(None, None), s=(None, None), auto_size_text=None, background_color=None, text_color=None, change_submits=False, - enable_events=False, do_not_clear=True, key=None, k=None, write_only=False, auto_refresh=False, reroute_stdout=False, reroute_stderr=False, reroute_cprint=False, echo_stdout_stderr=False, focus=False, font=None, pad=None, tooltip=None, justification=None, no_scrollbar=False, expand_x=False, expand_y=False, + enable_events=False, do_not_clear=True, key=None, k=None, write_only=False, auto_refresh=False, reroute_stdout=False, reroute_stderr=False, + reroute_cprint=False, echo_stdout_stderr=False, focus=False, font=None, pad=None, tooltip=None, justification=None, no_scrollbar=False, + expand_x=False, expand_y=False, right_click_menu=None, visible=True, metadata=None): """ - :param default_text: Initial text to show - :type default_text: (str) - :param enter_submits: if True, the Window.Read call will return is enter key is pressed in this element - :type enter_submits: (bool) - :param disabled: set disable state - :type disabled: (bool) - :param autoscroll: If True the contents of the element will automatically scroll as more data added to the end - :type autoscroll: (bool) - :param border_width: width of border around element in pixels - :type border_width: (int) - :param size: (width, height) width = characters-wide, height = rows-high - :type size: (int, int) | (None, None) - :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) - :param auto_size_text: if True will size the element to match the length of the text - :type auto_size_text: (bool) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Spin events happen when an item changes - :type enable_events: (bool) - :param do_not_clear: if False the element will be cleared any time the Window.Read call returns - :type do_not_clear: (bool) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param write_only: If True then no entry will be added to the values dictionary when the window is read - :type write_only: bool - :param auto_refresh: If True then anytime the element is updated, the window will be refreshed so that the change is immediately displayed - :type auto_refresh: (bool) - :param reroute_stdout: If True then all output to stdout will be output to this element - :type reroute_stdout: (bool) - :param reroute_stderr: If True then all output to stderr will be output to this element - :type reroute_stderr: (bool) - :param reroute_cprint: If True your cprint calls will output to this element. It's the same as you calling cprint_set_output_destination - :type reroute_cprint: (bool) + :param default_text: Initial text to show + :type default_text: (str) + :param enter_submits: if True, the Window.Read call will return is enter key is pressed in this element + :type enter_submits: (bool) + :param disabled: set disable state + :type disabled: (bool) + :param autoscroll: If True the contents of the element will automatically scroll as more data added to the end + :type autoscroll: (bool) + :param border_width: width of border around element in pixels + :type border_width: (int) + :param size: (width, height) width = characters-wide, height = rows-high + :type size: (int, int) | (None, None) + :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) + :param auto_size_text: if True will size the element to match the length of the text + :type auto_size_text: (bool) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Spin events happen when an item changes + :type enable_events: (bool) + :param do_not_clear: if False the element will be cleared any time the Window.Read call returns + :type do_not_clear: (bool) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param write_only: If True then no entry will be added to the values dictionary when the window is read + :type write_only: bool + :param auto_refresh: If True then anytime the element is updated, the window will be refreshed so that the change is immediately displayed + :type auto_refresh: (bool) + :param reroute_stdout: If True then all output to stdout will be output to this element + :type reroute_stdout: (bool) + :param reroute_stderr: If True then all output to stderr will be output to this element + :type reroute_stderr: (bool) + :param reroute_cprint: If True your cprint calls will output to this element. It's the same as you calling cprint_set_output_destination + :type reroute_cprint: (bool) :param echo_stdout_stderr: If True then output to stdout and stderr will be output to this element AND also to the normal console location - :type echo_stdout_stderr: (bool) - :param focus: if True initial focus will go to this element - :type focus: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param justification: text justification. left, right, center. Can use single characters l, r, c. - :type justification: (str) - :param no_scrollbar: If False then a scrollbar will be shown (the default) - :type no_scrollbar: (bool) - :param expand_x: If True the Multiline will automatically expand in the X direction to fill available space - :type expand_x: (bool) - :param expand_y: If True the Multiline will automatically expand in the Y direction to fill available space - :type expand_y: (bool) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type echo_stdout_stderr: (bool) + :param focus: if True initial focus will go to this element + :type focus: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param justification: text justification. left, right, center. Can use single characters l, r, c. + :type justification: (str) + :param no_scrollbar: If False then a scrollbar will be shown (the default) + :type no_scrollbar: (bool) + :param expand_x: If True the Multiline will automatically expand in the X direction to fill available space + :type expand_x: (bool) + :param expand_y: If True the Multiline will automatically expand in the Y direction to fill available space + :type expand_y: (bool) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.DefaultText = default_text @@ -2727,36 +2687,37 @@ class Multiline(Element): text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT, visible=visible, metadata=metadata) return - def update(self, value=None, disabled=None, append=False, font=None, text_color=None, background_color=None, text_color_for_value=None, background_color_for_value=None, visible=None, autoscroll=None, justification=None, font_for_value=None): + def update(self, value=None, disabled=None, append=False, font=None, text_color=None, background_color=None, text_color_for_value=None, + background_color_for_value=None, visible=None, autoscroll=None, justification=None, font_for_value=None): """ Changes some of the settings for the Multiline Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: new text to display - :type value: (str) - :param disabled: disable or enable state of the element - :type disabled: (bool) - :param append: if True then new value will be added onto the end of the current value. if False then contents will be replaced. - :type append: (bool) - :param font: specifies the font family, size, etc for the entire element - :type font: str | (str, int) - :param text_color: color of the text - :type text_color: (str) - :param background_color: color of background - :type background_color: (str) - :param text_color_for_value: color of the new text being added (the value paramter) - :type text_color_for_value: (str) + :param value: new text to display + :type value: (str) + :param disabled: disable or enable state of the element + :type disabled: (bool) + :param append: if True then new value will be added onto the end of the current value. if False then contents will be replaced. + :type append: (bool) + :param font: specifies the font family, size, etc for the entire element + :type font: str | (str, int) + :param text_color: color of the text + :type text_color: (str) + :param background_color: color of background + :type background_color: (str) + :param text_color_for_value: color of the new text being added (the value paramter) + :type text_color_for_value: (str) :param background_color_for_value: color of the new background of the text being added (the value paramter) - :type background_color_for_value: (str) - :param visible: set visibility state of the element - :type visible: (bool) - :param autoscroll: if True then contents of element are scrolled down when new text is added to the end - :type autoscroll: (bool) - :param justification: text justification. left, right, center. Can use single characters l, r, c. Sets only for this value, not entire element - :type justification: (str) - :param font_for_value: specifies the font family, size, etc for the value being updated - :type font_for_value: str | (str, int) + :type background_color_for_value: (str) + :param visible: set visibility state of the element + :type visible: (bool) + :param autoscroll: if True then contents of element are scrolled down when new text is added to the end + :type autoscroll: (bool) + :param justification: text justification. left, right, center. Can use single characters l, r, c. Sets only for this value, not entire element + :type justification: (str) + :param font_for_value: specifies the font family, size, etc for the value being updated + :type font_for_value: str | (str, int) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if autoscroll is not None: @@ -2778,8 +2739,8 @@ class Multiline(Element): value = str(value) if background_color_for_value is not None or text_color_for_value is not None or font_for_value is not None: try: - tag = 'Multiline(' + str(text_color_for_value) + ','+ str(background_color_for_value)+ ',' + str(font_for_value) + ')' - if tag not in self.tags: + tag = 'Multiline(' + str(text_color_for_value) + ',' + str(background_color_for_value) + ',' + str(font_for_value) + ')' + if tag not in self.tags: self.tags.add(tag) if background_color_for_value is not None: self.TKText.tag_configure(tag, background=background_color_for_value) @@ -2827,26 +2788,24 @@ class Multiline(Element): self.TKText.pack(padx=self.pad_used[0], pady=self.pad_used[1]) if self.AutoRefresh and self.ParentForm: - try: # in case the window was destroyed + try: # in case the window was destroyed self.ParentForm.refresh() except: pass if visible is not None: self._visible = visible - def get(self): """ Return current contents of the Multiline Element :return: current contents of the Multiline Element (used as an input type of Multiline - :rtype: (str) + :rtype: (str) """ return self.TKText.get(1.0, tk.END) - - - def print(self, *args, end=None, sep=None, text_color=None, background_color=None, justification=None, font=None, colors=None, t=None, b=None, c=None, autoscroll=True): + def print(self, *args, end=None, sep=None, text_color=None, background_color=None, justification=None, font=None, colors=None, t=None, b=None, c=None, + autoscroll=True): """ Print like Python normally prints except route the output to a multiline element and also add colors if desired @@ -2864,30 +2823,30 @@ class Multiline(Element): cprint('This will print white text on red background', text_color='white', background_color='red') cprint('This will print white text on red background', t='white', b='red') - :param args: The arguments to print - :type args: (Any) - :param end: The end char to use just like print uses - :type end: (str) - :param sep: The separation character like print uses - :type sep: (str) - :param text_color: The color of the text - :type text_color: (str) + :param args: The arguments to print + :type args: (Any) + :param end: The end char to use just like print uses + :type end: (str) + :param sep: The separation character like print uses + :type sep: (str) + :param text_color: The color of the text + :type text_color: (str) :param background_color: The background color of the line - :type background_color: (str) - :param justification: text justification. left, right, center. Can use single characters l, r, c. Sets only for this value, not entire element - :type justification: (str) - :param font: specifies the font family, size, etc for the args being printed - :type font: str | (str, int) | (str, int, str) - :param colors: Either a tuple or a string that has both the text and background colors. Or just the text color - :type colors: (str) or (str, str) - :param t: Color of the text - :type t: (str) - :param b: The background color of the line - :type b: (str) - :param c: Either a tuple or a string that has both the text and background colors or just tex color (same as the color parm) - :type c: (str) or (str, str) - :param autoscroll: If True the contents of the element will automatically scroll as more data added to the end - :type autoscroll: (bool) + :type background_color: (str) + :param justification: text justification. left, right, center. Can use single characters l, r, c. Sets only for this value, not entire element + :type justification: (str) + :param font: specifies the font family, size, etc for the args being printed + :type font: str | (str, int) | (str, int, str) + :param colors: Either a tuple or a string that has both the text and background colors. Or just the text color + :type colors: (str) or (str, str) + :param t: Color of the text + :type t: (str) + :param b: The background color of the line + :type b: (str) + :param c: Either a tuple or a string that has both the text and background colors or just tex color (same as the color parm) + :type c: (str) or (str, str) + :param autoscroll: If True the contents of the element will automatically scroll as more data added to the end + :type autoscroll: (bool) """ kw_text_color = text_color or t @@ -2898,17 +2857,16 @@ class Multiline(Element): kw_text_color = dual_color[0] kw_background_color = dual_color[1] elif isinstance(dual_color, str): - if ' on ' in dual_color: # if has "on" in the string, then have both text and background + if ' on ' in dual_color: # if has "on" in the string, then have both text and background kw_text_color = dual_color.split(' on ')[0] kw_background_color = dual_color.split(' on ')[1] - else: # if no "on" then assume the color string is just the text color + else: # if no "on" then assume the color string is just the text color kw_text_color = dual_color except Exception as e: print('* multiline print warning * you messed up with color formatting', e) - - _print_to_element(self, *args, end=end, sep=sep, text_color=kw_text_color, background_color=kw_background_color, justification=justification, autoscroll=autoscroll, font=font ) - + _print_to_element(self, *args, end=end, sep=sep, text_color=kw_text_color, background_color=kw_background_color, justification=justification, + autoscroll=autoscroll, font=font) def reroute_stdout_to_here(self): """ @@ -2917,7 +2875,6 @@ class Multiline(Element): self.previous_stdout = sys.stdout sys.stdout = self - def reroute_stderr_to_here(self): """ Sends stderr to this element @@ -2925,14 +2882,13 @@ class Multiline(Element): self.previous_stderr = sys.stderr sys.stderr = self - def restore_stdout(self): """ Restore a previously re-reouted stdout back to the original destination """ if self.previous_stdout: sys.stdout = self.previous_stdout - self.previous_stdout = None # indicate no longer routed here + self.previous_stdout = None # indicate no longer routed here def restore_stderr(self): """ @@ -2940,14 +2896,14 @@ class Multiline(Element): """ if self.previous_stderr: sys.stderr = self.previous_stderr - self.previous_stderr = None # indicate no longer routed here + self.previous_stderr = None # indicate no longer routed here def write(self, txt): """ Called by Python (not tkinter?) when stdout or stderr wants to write :param txt: text of output - :type txt: (str) + :type txt: (str) """ try: self.update(txt, append=True) @@ -2956,7 +2912,6 @@ class Multiline(Element): except: pass - def flush(self): """ Flush parameter was passed into a print statement. @@ -2967,7 +2922,6 @@ class Multiline(Element): except: pass - def __del__(self): """ If this Widget is deleted, be sure and restore the old stdout, stderr @@ -2983,8 +2937,6 @@ class Multiline(Element): except: pass - - Get = get Update = update @@ -3001,48 +2953,50 @@ class Text(Element): Text - Display some text in the window. Usually this means a single line of text. However, the text can also be multiple lines. If multi-lined there are no scroll bars. """ - def __init__(self, text='', size=(None, None), s=(None, None), auto_size_text=None, click_submits=False, enable_events=False, relief=None, font=None, text_color=None, background_color=None, border_width=None, justification=None, pad=None, key=None, k=None, right_click_menu=None, grab=None, tooltip=None, visible=True, metadata=None): + def __init__(self, text='', size=(None, None), s=(None, None), auto_size_text=None, click_submits=False, enable_events=False, relief=None, font=None, + text_color=None, background_color=None, border_width=None, justification=None, pad=None, key=None, k=None, right_click_menu=None, grab=None, + tooltip=None, visible=True, metadata=None): """ - :param text: The text to display. Can include /n to achieve multiple lines. Will convert (optional) parameter into a string - :type text: Any - :param size: (width, height) width = characters-wide, height = rows-high - :type size: (int, int) | (int, None) | (None, None) - :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) | (int, None) | (None, None) - :param auto_size_text: if True size of the Text Element will be sized to fit the string provided in 'text' parm - :type auto_size_text: (bool) - :param click_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type click_submits: (bool) - :param enable_events: Turns on the element specific events. Text events happen when the text is clicked - :type enable_events: (bool) - :param relief: relief style around the text. Values are same as progress meter relief values. Should be a constant that is defined at starting with "RELIEF_" - `RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID` - :type relief: (str/enum) - :param font: specifies the font family, size, etc - :type font: (str or (str, int) or None) - :param text_color: color of the text - :type text_color: (str) + :param text: The text to display. Can include /n to achieve multiple lines. Will convert (optional) parameter into a string + :type text: Any + :param size: (width, height) width = characters-wide, height = rows-high + :type size: (int, int) | (int, None) | (None, None) + :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) | (int, None) | (None, None) + :param auto_size_text: if True size of the Text Element will be sized to fit the string provided in 'text' parm + :type auto_size_text: (bool) + :param click_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type click_submits: (bool) + :param enable_events: Turns on the element specific events. Text events happen when the text is clicked + :type enable_events: (bool) + :param relief: relief style around the text. Values are same as progress meter relief values. Should be a constant that is defined at starting with "RELIEF_" - `RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID` + :type relief: (str/enum) + :param font: specifies the font family, size, etc + :type font: (str or (str, int) or None) + :param text_color: color of the text + :type text_color: (str) :param background_color: color of background - :type background_color: (str) - :param border_width: number of pixels for the border (if using a relief) - :type border_width: (int) - :param justification: how string should be aligned within space provided by size. Valid choices = `left`, `right`, `center` - :type justification: (str) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str or int or tuple or object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object + :type background_color: (str) + :param border_width: number of pixels for the border (if using a relief) + :type border_width: (int) + :param justification: how string should be aligned within space provided by size. Valid choices = `left`, `right`, `center` + :type justification: (str) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str or int or tuple or object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param grab: If True can grab this element and move the window around. Default is False - :type grab: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param grab: If True can grab this element and move the window around. Default is False + :type grab: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.DisplayText = str(text) @@ -3061,24 +3015,25 @@ class Text(Element): key = key if key is not None else k sz = size if size != (None, None) else s - super().__init__(ELEM_TYPE_TEXT, auto_size_text=auto_size_text, size=sz, background_color=bg, font=font if font else DEFAULT_FONT, text_color=self.TextColor, pad=pad, key=key, tooltip=tooltip, visible=visible, metadata=metadata) + super().__init__(ELEM_TYPE_TEXT, auto_size_text=auto_size_text, size=sz, background_color=bg, font=font if font else DEFAULT_FONT, + text_color=self.TextColor, pad=pad, key=key, tooltip=tooltip, visible=visible, metadata=metadata) def update(self, value=None, background_color=None, text_color=None, font=None, visible=None): """ Changes some of the settings for the Text Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: new text to show - :type value: (str) + :param value: new text to show + :type value: (str) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param visible: set visibility state of the element - :type visible: (bool) + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param visible: set visibility state of the element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if value is not None: self.DisplayText = str(value) @@ -3101,7 +3056,7 @@ class Text(Element): Gets the current value of the displayed text :return: The current value - :rtype: (str) + :rtype: (str) """ return self.DisplayText @@ -3112,12 +3067,12 @@ class Text(Element): the character of your choosing if "W" is not a good representative character. Cannot be used until a window has been created. If an error occurs, 0 will be returned - :param font: specifies the font family, size, etc, to be measured - :type font: (str or (str, int) or None) + :param font: specifies the font family, size, etc, to be measured + :type font: (str or (str, int) or None) :param character: specifies a SINGLE CHARACTER character to measure - :type character: (str) - :return: Width in pixels of "A" - :rtype: (int) + :type character: (str) + :return: Width in pixels of "A" + :rtype: (int) """ size = 0 try: @@ -3126,7 +3081,6 @@ class Text(Element): print('Error retrieving font information', e) return size - @classmethod def char_height_in_pixels(cls, font): """ @@ -3134,9 +3088,9 @@ class Text(Element): Cannot be used until a window has been created. If an error occurs, 0 will be returned :param font: specifies the font family, size, etc, to be measured - :type font: (str or (str, int) or None) - :return: Height in pixels of "A" - :rtype: (int) + :type font: (str or (str, int) or None) + :return: Height in pixels of "A" + :rtype: (int) """ size = 0 try: @@ -3145,19 +3099,18 @@ class Text(Element): print('Error retrieving font information', e) return size - @classmethod def string_width_in_pixels(cls, font, string): """ Get the with of the supplied string in pixels for the font being passed in. Cannot be used until a window has been created. If an error occurs, 0 will be returned - :param font: specifies the font family, size, etc, to be measured - :type font: (str or (str, int) or None) + :param font: specifies the font family, size, etc, to be measured + :type font: (str or (str, int) or None) :param string: the string to measure - :type string: str - :return: Width in pixels of string - :rtype: (int) + :type string: str + :return: Width in pixels of string + :rtype: (int) """ size = 0 try: @@ -3166,7 +3119,6 @@ class Text(Element): print('Error retrieving font information', e) return size - Get = get Update = update @@ -3189,42 +3141,42 @@ class StatusBar(Element): relief=RELIEF_SUNKEN, font=None, text_color=None, background_color=None, justification=None, pad=None, key=None, k=None, right_click_menu=None, tooltip=None, visible=True, metadata=None): """ - :param text: Text that is to be displayed in the widget - :type text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :type size: (int, int) | (None, None) - :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) - :param auto_size_text: True if size should fit the text length - :type auto_size_text: (bool) - :param click_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type click_submits: (bool) - :param enable_events: Turns on the element specific events. StatusBar events occur when the bar is clicked - :type enable_events: (bool) - :param relief: relief style. Values are same as progress meter relief values. Can be a constant or a string: `RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID` - :type relief: (enum) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param text_color: color of the text - :type text_color: (str) + :param text: Text that is to be displayed in the widget + :type text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :type size: (int, int) | (None, None) + :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) + :param auto_size_text: True if size should fit the text length + :type auto_size_text: (bool) + :param click_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type click_submits: (bool) + :param enable_events: Turns on the element specific events. StatusBar events occur when the bar is clicked + :type enable_events: (bool) + :param relief: relief style. Values are same as progress meter relief values. Can be a constant or a string: `RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID` + :type relief: (enum) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param text_color: color of the text + :type text_color: (str) :param background_color: color of background - :type background_color: (str) - :param justification: how string should be aligned within space provided by size. Valid choices = `left`, `right`, `center` - :type justification: (str) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object + :type background_color: (str) + :param justification: how string should be aligned within space provided by size. Valid choices = `left`, `right`, `center` + :type justification: (str) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.DisplayText = text @@ -3249,19 +3201,19 @@ class StatusBar(Element): def update(self, value=None, background_color=None, text_color=None, font=None, visible=None): """ Changes some of the settings for the Status Bar Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: new text to show - :type value: (str) + :param value: new text to show + :type value: (str) :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param visible: set visibility state of the element - :type visible: (bool) + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param visible: set visibility state of the element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if value is not None: @@ -3283,41 +3235,42 @@ class StatusBar(Element): Update = update + SBar = StatusBar + # ---------------------------------------------------------------------- # # TKProgressBar # # Emulate the TK ProgressBar using canvas and rectangles # ---------------------------------------------------------------------- # class TKProgressBar(): - uniqueness_counter = 0 def __init__(self, root, max, length=400, width=DEFAULT_PROGRESS_BAR_SIZE[1], style=DEFAULT_TTK_THEME, relief=DEFAULT_PROGRESS_BAR_RELIEF, border_width=DEFAULT_PROGRESS_BAR_BORDER_WIDTH, orientation='horizontal', BarColor=(None, None), key=None): """ - :param root: The root window bar is to be shown in - :type root: tk.Tk | tk.TopLevel - :param max: Maximum value the bar will be measuring - :type max: (int) - :param length: length in pixels of the bar - :type length: (int) - :param width: width in pixels of the bar - :type width: (int) - :param style: Progress bar style defined as one of these 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' - :type style: (str) - :param relief: relief style. Values are same as progress meter relief values. Can be a constant or a string: `RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID` (Default value = DEFAULT_PROGRESS_BAR_RELIEF) - :type relief: (str) + :param root: The root window bar is to be shown in + :type root: tk.Tk | tk.TopLevel + :param max: Maximum value the bar will be measuring + :type max: (int) + :param length: length in pixels of the bar + :type length: (int) + :param width: width in pixels of the bar + :type width: (int) + :param style: Progress bar style defined as one of these 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' + :type style: (str) + :param relief: relief style. Values are same as progress meter relief values. Can be a constant or a string: `RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID` (Default value = DEFAULT_PROGRESS_BAR_RELIEF) + :type relief: (str) :param border_width: The amount of pixels that go around the outside of the bar - :type border_width: (int) - :param orientation: 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical') - :type orientation: (str) - :param BarColor: The 2 colors that make up a progress bar. One is the background, the other is the bar - :type BarColor: (str, str) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object + :type border_width: (int) + :param orientation: 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical') + :type orientation: (str) + :param BarColor: The 2 colors that make up a progress bar. One is the background, the other is the bar + :type BarColor: (str, str) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object """ self.Length = length @@ -3364,9 +3317,9 @@ class TKProgressBar(): """ Update the current value of the bar and/or update the maximum value the bar can reach :param count: current value - :type count: (int) - :param max: the maximum value - :type max: (int) + :type count: (int) + :param max: the maximum value + :type max: (int) """ if max is not None: self.Max = max @@ -3397,24 +3350,24 @@ class TKOutput(tk.Frame): def __init__(self, parent, width, height, bd, background_color=None, text_color=None, echo_stdout_stderr=False, font=None, pad=None): """ - :param parent: The "Root" that the Widget will be in - :type parent: tk.Tk | tk.Toplevel - :param width: Width in characters - :type width: (int) - :param height: height in rows - :type height: (int) - :param bd: Border Depth. How many pixels of border to show - :type bd: (int) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) + :param parent: The "Root" that the Widget will be in + :type parent: tk.Tk | tk.Toplevel + :param width: Width in characters + :type width: (int) + :param height: height in rows + :type height: (int) + :param bd: Border Depth. How many pixels of border to show + :type bd: (int) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) :param echo_stdout_stderr: If True then output to stdout will be output to this element AND also to the normal console location - :type echo_stdout_stderr: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :type echo_stdout_stderr: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) """ self.frame = tk.Frame(parent) tk.Frame.__init__(self, self.frame) @@ -3444,7 +3397,7 @@ class TKOutput(tk.Frame): Refreshes the window after the write so that the change is immediately displayed :param txt: text of output - :type txt: (str) + :type txt: (str) """ try: self.output.insert(tk.END, str(txt)) @@ -3477,8 +3430,6 @@ class TKOutput(tk.Frame): except: pass - - def __del__(self): """ If this Widget is deleted, be sure and restore the old stdout, stderr @@ -3502,34 +3453,35 @@ class Output(Element): features such as routing the cprint output to the element. """ - def __init__(self, size=(None, None), s=(None, None), background_color=None, text_color=None, pad=None, echo_stdout_stderr=False, font=None, tooltip=None, key=None, k=None, right_click_menu=None, visible=True, metadata=None): + def __init__(self, size=(None, None), s=(None, None), background_color=None, text_color=None, pad=None, echo_stdout_stderr=False, font=None, tooltip=None, + key=None, k=None, right_click_menu=None, visible=True, metadata=None): """ - :param size: (width, height) w=characters-wide, h=rows-high - :type size: (int, int) | (None, None) - :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) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param size: (width, height) w=characters-wide, h=rows-high + :type size: (int, int) | (None, None) + :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) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) :param echo_stdout_stderr: If True then output to stdout will be output to this element AND also to the normal console location - :type echo_stdout_stderr: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type echo_stdout_stderr: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self._TKOut = self.Widget = None # type: TKOutput @@ -3549,7 +3501,7 @@ class Output(Element): Returns the TKOutput object used to create the element :return: The TKOutput object - :rtype: (TKOutput) + :rtype: (TKOutput) """ if self._TKOut is None: print('*** Did you forget to call Finalize()? Your code should look something like: ***') @@ -3560,12 +3512,12 @@ class Output(Element): """ Changes some of the settings for the Output Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: string that will replace current contents of the output area - :type value: (str) + :param value: string that will replace current contents of the output area + :type value: (str) :param visible: control visibility of element - :type visible: (bool) + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if value is not None: @@ -3582,7 +3534,7 @@ class Output(Element): """ Returns the current contents of the output. Similar to Get method other Elements :return: the current value of the output - :rtype: (str) + :rtype: (str) """ return self._TKOut.output.get(1.0, tk.END) @@ -3591,9 +3543,9 @@ class Output(Element): Causes the Element to expand to fill available space in the X and Y directions. Can specify which or both directions :param expand_x: If True Element will expand in the Horizontal directions - :type expand_x: (bool) + :type expand_x: (bool) :param expand_y: If True Element will expand in the Vertical directions - :type expand_y: (bool) + :type expand_y: (bool) """ if expand_x and expand_y: @@ -3632,73 +3584,75 @@ class Button(Element): def __init__(self, button_text='', button_type=BUTTON_TYPE_READ_FORM, target=(None, None), tooltip=None, file_types=(("ALL Files", "*.*"),), initial_folder=None, default_extension='', disabled=False, change_submits=False, enable_events=False, image_filename=None, image_data=None, image_size=(None, None), - image_subsample=None, border_width=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, disabled_button_color=None, - highlight_colors=None, mouseover_colors=(None,None), use_ttk_buttons=None, font=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, right_click_menu=None, visible=True, metadata=None): + image_subsample=None, border_width=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, + disabled_button_color=None, + highlight_colors=None, mouseover_colors=(None, None), use_ttk_buttons=None, font=None, bind_return_key=False, focus=False, pad=None, key=None, + k=None, right_click_menu=None, visible=True, metadata=None): """ - :param button_text: Text to be displayed on the button - :type button_text: (str) - :param button_type: You should NOT be setting this directly. ONLY the shortcut functions set this - :type button_type: (int) - :param target: key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button - :type target: str | (int, int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param file_types: the filetypes that will be used to match files. To indicate all files: (("ALL Files", "*.*"),). Note - NOT SUPPORTED ON MAC - :type file_types: Tuple[(str, str), ...] - :param initial_folder: starting path for folders and files - :type initial_folder: (str) - :param default_extension: If no extension entered by user, add this to filename (only used in saveas dialogs) - :type default_extension: (str) - :param disabled: If True button will be created disabled. If BUTTON_DISABLED_MEANS_IGNORE then the button will be ignored rather than disabled using tkinter - :type disabled: (bool | str) - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. If this button is a target, should it generate an event when filled in - :type enable_events: (bool) - :param image_filename: image filename if there is a button image. GIFs and PNGs only. - :type image_filename: (str) - :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data - :type image_data: bytes | str - :param image_size: Size of the image in pixels (width, height) - :type image_size: (int, int) - :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 border_width: width of border around button in pixels - :type border_width: (int) - :param size: (width, height) of the button in characters wide, rows high - :type size: (int, int) | (None, None) - :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) - :param auto_size_button: if True the button size is sized to fit the text - :type auto_size_button: (bool) - :param button_color: Color of button. default is from theme or the window. Easy to remember which is which if you say "ON" between colors. "red" on "green". Normally a tuple, but can be a simplified-button-color-string "foreground on background". Can be a single color if want to set only the background. - :type button_color: (str, str) | str | (int, int) | None + :param button_text: Text to be displayed on the button + :type button_text: (str) + :param button_type: You should NOT be setting this directly. ONLY the shortcut functions set this + :type button_type: (int) + :param target: key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button + :type target: str | (int, int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param file_types: the filetypes that will be used to match files. To indicate all files: (("ALL Files", "*.*"),). Note - NOT SUPPORTED ON MAC + :type file_types: Tuple[(str, str), ...] + :param initial_folder: starting path for folders and files + :type initial_folder: (str) + :param default_extension: If no extension entered by user, add this to filename (only used in saveas dialogs) + :type default_extension: (str) + :param disabled: If True button will be created disabled. If BUTTON_DISABLED_MEANS_IGNORE then the button will be ignored rather than disabled using tkinter + :type disabled: (bool | str) + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. If this button is a target, should it generate an event when filled in + :type enable_events: (bool) + :param image_filename: image filename if there is a button image. GIFs and PNGs only. + :type image_filename: (str) + :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data + :type image_data: bytes | str + :param image_size: Size of the image in pixels (width, height) + :type image_size: (int, int) + :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 border_width: width of border around button in pixels + :type border_width: (int) + :param size: (width, height) of the button in characters wide, rows high + :type size: (int, int) | (None, None) + :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) + :param auto_size_button: if True the button size is sized to fit the text + :type auto_size_button: (bool) + :param button_color: Color of button. default is from theme or the window. Easy to remember which is which if you say "ON" between colors. "red" on "green". Normally a tuple, but can be a simplified-button-color-string "foreground on background". Can be a single color if want to set only the background. + :type button_color: (str, str) | str | (int, int) | None :param disabled_button_color: colors to use when button is disabled (text, background). Use None for a color if don't want to change. Only ttk buttons support both text and background colors. tk buttons only support changing text color - :type disabled_button_color: (str, str) | str - :param highlight_colors: colors to use when button has focus (has focus, does not have focus). None will use colors based on theme. Only used by Linux and only for non-TTK button - :type highlight_colors: (str, str) - :param mouseover_colors: Important difference between Linux & Windows! Linux - Colors when mouse moved over button. Windows - colors when button is pressed. The default is to switch the text and background colors (an inverse effect) - :type mouseover_colors: (str, str) | str - :param use_ttk_buttons: True = use ttk buttons. False = do not use ttk buttons. None (Default) = use ttk buttons only if on a Mac and not with button images - :type use_ttk_buttons: (bool) - :param font: specifies the font family, size, etc - :type font: str | (str, int) - :param bind_return_key: If True the return key will cause this button to be pressed - :type bind_return_key: (bool) - :param focus: if True, initial focus will be put on this button - :type focus: (bool) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type disabled_button_color: (str, str) | str + :param highlight_colors: colors to use when button has focus (has focus, does not have focus). None will use colors based on theme. Only used by Linux and only for non-TTK button + :type highlight_colors: (str, str) + :param mouseover_colors: Important difference between Linux & Windows! Linux - Colors when mouse moved over button. Windows - colors when button is pressed. The default is to switch the text and background colors (an inverse effect) + :type mouseover_colors: (str, str) | str + :param use_ttk_buttons: True = use ttk buttons. False = do not use ttk buttons. None (Default) = use ttk buttons only if on a Mac and not with button images + :type use_ttk_buttons: (bool) + :param font: specifies the font family, size, etc + :type font: str | (str, int) + :param bind_return_key: If True the return key will cause this button to be pressed + :type bind_return_key: (bool) + :param focus: if True, initial focus will be put on this button + :type focus: (bool) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.AutoSizeButton = auto_size_button @@ -3707,7 +3661,7 @@ class Button(Element): self.Widget = self.TKButton = None # type: tk.Button self.Target = target self.ButtonText = str(button_text) - self.RightClickMenu=right_click_menu + self.RightClickMenu = right_click_menu # Button colors can be a tuple (text, background) or a string with format "text on background" # bc = button_color # if button_color is None: @@ -3756,7 +3710,7 @@ class Button(Element): self.Disabled = disabled self.ChangeSubmits = change_submits or enable_events self.UseTtkButtons = use_ttk_buttons - self._files_delimiter = BROWSE_FILES_DELIMITER # used by the file browse button. used when multiple files are selected by user + self._files_delimiter = BROWSE_FILES_DELIMITER # used by the file browse button. used when multiple files are selected by user if use_ttk_buttons is None and running_mac(): self.UseTtkButtons = True # if image_filename or image_data: @@ -3771,22 +3725,21 @@ class Button(Element): self.HighlightColors = self._compute_highlight_colors() if mouseover_colors != (None, None): - self.MouseOverColors = button_color_to_tuple(mouseover_colors) + self.MouseOverColors = button_color_to_tuple(mouseover_colors) elif button_color != None: self.MouseOverColors = (self.ButtonColor[1], self.ButtonColor[0]) else: - self.MouseOverColors =(theme_button_color()[1], theme_button_color()[0]) + self.MouseOverColors = (theme_button_color()[1], theme_button_color()[0]) sz = size if size != (None, None) else s super().__init__(ELEM_TYPE_BUTTON, size=sz, font=font, pad=pad, key=_key, tooltip=tooltip, visible=visible, metadata=metadata) return - def _compute_highlight_colors(self): """ Determines the color to use to indicate the button has focus. This setting is only used by Linux. :return: Pair of colors. (Highlight, Highlight Background) - :rtype: (str, str) + :rtype: (str, str) """ highlight_color = highlight_background = COLOR_SYSTEM_DEFAULT if self.ButtonColor != COLOR_SYSTEM_DEFAULT and theme_background_color() != COLOR_SYSTEM_DEFAULT: @@ -3799,6 +3752,7 @@ class Button(Element): return (highlight_color, highlight_background) # Realtime button release callback + def ButtonReleaseCallBack(self, parm): """ Not a user callable function. Called by tkinter when a "realtime" button is released @@ -3827,8 +3781,6 @@ class Button(Element): # self.ParentForm.TKroot.quit() # kick out of loop if read was called _exit_mainloop(self.ParentForm) - - def _find_target(self): target = self.Target target_element = None @@ -3904,7 +3856,7 @@ class Button(Element): filetypes = (("ALL Files", "*.*"),) if self.FileTypes is None else self.FileTypes if self.BType == BUTTON_TYPE_BROWSE_FOLDER: - if running_mac(): # macs don't like seeing the parent window (go firgure) + if running_mac(): # macs don't like seeing the parent window (go firgure) folder_name = tk.filedialog.askdirectory(initialdir=self.InitialFolder) # show the 'get folder' dialog box else: folder_name = tk.filedialog.askdirectory(initialdir=self.InitialFolder, parent=self.ParentForm.TKroot) # show the 'get folder' dialog box @@ -3942,7 +3894,8 @@ class Button(Element): if running_mac(): file_name = tk.filedialog.asksaveasfilename(defaultextension=self.DefaultExtension, initialdir=self.InitialFolder) else: - file_name = tk.filedialog.asksaveasfilename(filetypes=filetypes,defaultextension=self.DefaultExtension, initialdir=self.InitialFolder, parent=self.ParentForm.TKroot) + file_name = tk.filedialog.asksaveasfilename(filetypes=filetypes, defaultextension=self.DefaultExtension, initialdir=self.InitialFolder, + parent=self.ParentForm.TKroot) if file_name: strvar.set(file_name) self.TKStringVar.set(file_name) @@ -3972,11 +3925,11 @@ class Button(Element): _exit_mainloop(self.ParentForm) elif self.BType == BUTTON_TYPE_CLOSES_WIN_ONLY: # special kind of button that does not exit main loop self.ParentForm._Close(without_event=True) - self.ParentForm.TKroot.destroy() # close the window with tkinter + self.ParentForm.TKroot.destroy() # close the window with tkinter Window._DecrementOpenCount() elif self.BType == BUTTON_TYPE_CALENDAR_CHOOSER: # this is a return type button so GET RESULTS and destroy window # ------------ new chooser code ------------- - self.ParentForm.LastButtonClicked = self.Key # key should have been generated already if not set by user + self.ParentForm.LastButtonClicked = self.Key # key should have been generated already if not set by user self.ParentForm.FormRemainedOpen = True should_submit_window = False _exit_mainloop(self.ParentForm) @@ -3990,37 +3943,33 @@ class Button(Element): self.ParentForm.FormRemainedOpen = True _exit_mainloop(self.ParentForm) - return - - - def update(self, text=None, button_color=(None, None), disabled=None, image_data=None, image_filename=None, visible=None, image_subsample=None, disabled_button_color=(None, None), image_size=None): """ Changes some of the settings for the Button Element. Must call `Window.Read` or `Window.Finalize` prior - :param text: sets button text - :type text: (str) - :param button_color: Color of button. default is from theme or the window. Easy to remember which is which if you say "ON" between colors. "red" on "green". Normally a tuple, but can be a simplified-button-color-string "foreground on background". Can be a single color if want to set only the background. - :type button_color: (str, str) | str | (int, int) | None - :param disabled: True/False to enable/disable at the GUI level. Use BUTTON_DISABLED_MEANS_IGNORE to ignore clicks (won't change colors) - :type disabled: (bool | str) - :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data - :type image_data: bytes | str - :param image_filename: image filename if there is a button image. GIFs and PNGs only. - :type image_filename: (str) + :param text: sets button text + :type text: (str) + :param button_color: Color of button. default is from theme or the window. Easy to remember which is which if you say "ON" between colors. "red" on "green". Normally a tuple, but can be a simplified-button-color-string "foreground on background". Can be a single color if want to set only the background. + :type button_color: (str, str) | str | (int, int) | None + :param disabled: True/False to enable/disable at the GUI level. Use BUTTON_DISABLED_MEANS_IGNORE to ignore clicks (won't change colors) + :type disabled: (bool | str) + :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data + :type image_data: bytes | str + :param image_filename: image filename if there is a button image. GIFs and PNGs only. + :type image_filename: (str) :param disabled_button_color: colors to use when button is disabled (text, background). Use None for a color if don't want to change. Only ttk buttons support both text and background colors. tk buttons only support changing text color - :type disabled_button_color: (str, str) - :param visible: control visibility of element - :type visible: (bool) - :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 image_size: Size of the image in pixels (width, height) - :type image_size: (int, int) + :type disabled_button_color: (str, str) + :param visible: control visibility of element + :type visible: (bool) + :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 image_size: Size of the image in pixels (width, height) + :type image_size: (int, int) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if self.UseTtkButtons: @@ -4100,13 +4049,12 @@ class Button(Element): if visible is not None: self._visible = visible - def get_text(self): """ Returns the current text shown on a button :return: The text currently displayed on the button - :rtype: (str) + :rtype: (str) """ return self.ButtonText @@ -4140,56 +4088,57 @@ class ButtonMenu(Element): def __init__(self, button_text, menu_def, tooltip=None, disabled=False, image_filename=None, image_data=None, image_size=(None, None), image_subsample=None, border_width=None, - size=(None, None), s=(None, None), auto_size_button=None, button_color=None, text_color=None, background_color=None, disabled_text_color=None, font=None, item_font=None, pad=None, key=None, k=None, tearoff=False, visible=True, metadata=None): + size=(None, None), s=(None, None), auto_size_button=None, button_color=None, text_color=None, background_color=None, disabled_text_color=None, + font=None, item_font=None, pad=None, key=None, k=None, tearoff=False, visible=True, metadata=None): """ - :param button_text: Text to be displayed on the button - :type button_text: (str) - :param menu_def: A list of lists of Menu items to show when this element is clicked. See docs for format as they are the same for all menu types - :type menu_def: List[List[str]] - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param disabled: If True button will be created disabled - :type disabled: (bool) - :param image_filename: image filename if there is a button image. GIFs and PNGs only. - :type image_filename: (str) - :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data - :type image_data: bytes | str - :param image_size: Size of the image in pixels (width, height) - :type image_size: (int, int) - :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 border_width: width of border around button in pixels - :type border_width: (int) - :param size:(width, height) of the button in characters wide, rows high - :type size: (int, int) | (None, None) - :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) - :param auto_size_button: if True the button size is sized to fit the text - :type auto_size_button: (bool) - :param button_color: of button. Easy to remember which is which if you say "ON" between colors. "red" on "green" - :type button_color: (str, str) or str - :param background_color: color of the background - :type background_color: (str) - :param text_color: element's text color. Can be in #RRGGBB format or a color name "black" - :type text_color: (str) + :param button_text: Text to be displayed on the button + :type button_text: (str) + :param menu_def: A list of lists of Menu items to show when this element is clicked. See docs for format as they are the same for all menu types + :type menu_def: List[List[str]] + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param disabled: If True button will be created disabled + :type disabled: (bool) + :param image_filename: image filename if there is a button image. GIFs and PNGs only. + :type image_filename: (str) + :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data + :type image_data: bytes | str + :param image_size: Size of the image in pixels (width, height) + :type image_size: (int, int) + :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 border_width: width of border around button in pixels + :type border_width: (int) + :param size: (width, height) of the button in characters wide, rows high + :type size: (int, int) | (None, None) + :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) + :param auto_size_button: if True the button size is sized to fit the text + :type auto_size_button: (bool) + :param button_color: of button. Easy to remember which is which if you say "ON" between colors. "red" on "green" + :type button_color: (str, str) or str + :param background_color: color of the background + :type background_color: (str) + :param text_color: element's text color. Can be in #RRGGBB format or a color name "black" + :type text_color: (str) :param disabled_text_color: color to use for text when item is disabled. Can be in #RRGGBB format or a color name "black" - :type disabled_text_color: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param item_font: specifies the font family, size, etc, for the menu items - :type item_font: str | Tuple[str, int] - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tearoff: Determines if menus should allow them to be torn off - :type tearoff: (bool) - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type disabled_text_color: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param item_font: specifies the font family, size, etc, for the menu items + :type item_font: str | Tuple[str, int] + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tearoff: Determines if menus should allow them to be torn off + :type tearoff: (bool) + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.MenuDefinition = copy.deepcopy(menu_def) @@ -4222,13 +4171,12 @@ class ButtonMenu(Element): text_color=self.TextColor, background_color=self.BackgroundColor, visible=visible, metadata=metadata) self.Tearoff = tearoff - def _MenuItemChosenCallback(self, item_chosen): # ButtonMenu Menu Item Chosen Callback """ Not a user callable function. Called by tkinter when an item is chosen from the menu. :param item_chosen: The menu item chosen. - :type item_chosen: (str) + :type item_chosen: (str) """ # print('IN MENU ITEM CALLBACK', item_chosen) self.MenuItemChosen = item_chosen @@ -4238,18 +4186,17 @@ class ButtonMenu(Element): # self.ParentForm.TKroot.quit() # kick the users out of the mainloop _exit_mainloop(self.ParentForm) - def update(self, menu_definition=None, visible=None): """ Changes some of the settings for the ButtonMenu Element. Must call `Window.Read` or `Window.Finalize` prior :param menu_definition: (New menu definition (in menu definition format) - :type menu_definition: List[List] - :param visible: control visibility of element - :type visible: (bool) + :type menu_definition: List[List] + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if menu_definition is not None: @@ -4289,6 +4236,7 @@ class ButtonMenu(Element): BMenu = ButtonMenu BM = ButtonMenu + # ---------------------------------------------------------------------- # # ProgreessBar # # ---------------------------------------------------------------------- # @@ -4297,38 +4245,39 @@ class ProgressBar(Element): Progress Bar Element - Displays a colored bar that is shaded as progress of some operation is made """ - def __init__(self, max_value, orientation=None, size=(None, None), s=(None, None), auto_size_text=None, bar_color=None, style=None, border_width=None, relief=None, key=None, k=None, pad=None, right_click_menu=None,visible=True, metadata=None): + def __init__(self, max_value, orientation=None, size=(None, None), s=(None, None), auto_size_text=None, bar_color=None, style=None, border_width=None, + relief=None, key=None, k=None, pad=None, right_click_menu=None, visible=True, metadata=None): """ - :param max_value: max value of progressbar - :type max_value: (int) - :param orientation: 'horizontal' or 'vertical' - :type orientation: (str) - :param size: Size of the bar. If horizontal (chars wide, pixels high), vert (pixels wide, rows high) - :type size: (int, int) | (None, None) - :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) - :param auto_size_text: Not sure why this is here - :type auto_size_text: (bool) - :param bar_color: The 2 colors that make up a progress bar. Easy to remember which is which if you say "ON" between colors. "red" on "green". - :type bar_color: (str, str) or str - :param style: Progress bar style defined as one of these 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' - :type style: (str) - :param border_width: The amount of pixels that go around the outside of the bar - :type border_width: (int) - :param relief: relief style. Values are same as progress meter relief values. Can be a constant or a string: `RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID` (Default value = DEFAULT_PROGRESS_BAR_RELIEF) - :type relief: (str) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param max_value: max value of progressbar + :type max_value: (int) + :param orientation: 'horizontal' or 'vertical' + :type orientation: (str) + :param size: Size of the bar. If horizontal (chars wide, pixels high), vert (pixels wide, rows high) + :type size: (int, int) | (None, None) + :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) + :param auto_size_text: Not sure why this is here + :type auto_size_text: (bool) + :param bar_color: The 2 colors that make up a progress bar. Easy to remember which is which if you say "ON" between colors. "red" on "green". + :type bar_color: (str, str) or str + :param style: Progress bar style defined as one of these 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' + :type style: (str) + :param border_width: The amount of pixels that go around the outside of the bar + :type border_width: (int) + :param relief: relief style. Values are same as progress meter relief values. Can be a constant or a string: `RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID` (Default value = DEFAULT_PROGRESS_BAR_RELIEF) + :type relief: (str) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.MaxValue = max_value @@ -4343,12 +4292,12 @@ class ProgressBar(Element): bar_color = DEFAULT_PROGRESS_BAR_COLOR else: try: - if isinstance(bar_color,str): + if isinstance(bar_color, str): bar_color = bar_color.split(' on ') except Exception as e: print('* ProgressBar warning * you messed up with color formatting', e) - self.BarColor = bar_color # should be a tuple at this point + self.BarColor = bar_color # should be a tuple at this point self.BarStyle = style if style else DEFAULT_TTK_THEME self.BorderWidth = border_width if border_width else DEFAULT_PROGRESS_BAR_BORDER_WIDTH self.Relief = relief if relief else DEFAULT_PROGRESS_BAR_RELIEF @@ -4366,9 +4315,9 @@ class ProgressBar(Element): Change what the bar shows by changing the current count and optionally the max count :param current_count: sets the current value - :type current_count: (int) - :param max: changes the max value - :type max: (int) + :type current_count: (int) + :param max: changes the max value + :type max: (int) """ if self.ParentForm.TKrootDestroyed: @@ -4382,22 +4331,21 @@ class ProgressBar(Element): return False return True - def update(self, current_count, max=None, visible=None): """ Changes some of the settings for the ProgressBar Element. Must call `Window.Read` or `Window.Finalize` prior Now has the ability to modify the count so that the update_bar method is not longer needed separately :param current_count: sets the current value - :type current_count: (int) - :param max: changes the max value - :type max: (int) - :param visible: control visibility of element - :type visible: (bool) - :return: Returns True if update was OK. False means something wrong with window or it was closed - :rtype: (bool) + :type current_count: (int) + :param max: changes the max value + :type max: (int) + :param visible: control visibility of element + :type visible: (bool) + :return: Returns True if update was OK. False means something wrong with window or it was closed + :rtype: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return False if self.ParentForm.TKrootDestroyed: @@ -4419,7 +4367,6 @@ class ProgressBar(Element): return False return True - Update = update UpdateBar = update_bar @@ -4437,39 +4384,40 @@ class Image(Element): Image Element - show an image in the window. Should be a GIF or a PNG only """ - def __init__(self, filename=None, data=None, background_color=None, size=(None, None), s=(None, None), pad=None, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, enable_events=False, metadata=None): + def __init__(self, filename=None, data=None, background_color=None, size=(None, None), s=(None, None), pad=None, key=None, k=None, tooltip=None, + right_click_menu=None, visible=True, enable_events=False, metadata=None): """ - :param filename: image filename if there is a button image. GIFs and PNGs only. - :type filename: str | None - :param data: Raw or Base64 representation of the image to put on button. Choose either filename or data - :type data: bytes | str | None + :param filename: image filename if there is a button image. GIFs and PNGs only. + :type filename: str | None + :param data: Raw or Base64 representation of the image to put on button. Choose either filename or data + :type data: bytes | str | None :param background_color: color of background :type background_color: - :param size: (width, height) size of image in pixels - :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 - :type s: (int, int) | (None, None) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) + :param size: (width, height) size of image in pixels + :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 + :type s: (int, int) | (None, None) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param enable_events: Turns on the element specific events. For an Image element, the event is "image clicked" - :type enable_events: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param enable_events: Turns on the element specific events. For an Image element, the event is "image clicked" + :type enable_events: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Filename = filename self.Data = data - self.Widget = self.tktext_label = None # type: tk.Label + self.Widget = self.tktext_label = None # type: tk.Label self.BackgroundColor = background_color if data is None and filename is None: self.Filename = '' @@ -4494,16 +4442,16 @@ class Image(Element): To clear an image that's been displayed, call with NONE of the options set. A blank update call will delete the previously shown image. :param filename: filename to the new image to display. - :type filename: (str) - :param data: Base64 encoded string OR a tk.PhotoImage object - :type data: str | tkPhotoImage - :param size: size of a image (w,h) w=characters-wide, h=rows-high - :type size: Tuple[int,int] - :param visible: control visibility of element - :type visible: (bool) + :type filename: (str) + :param data: Base64 encoded string OR a tk.PhotoImage object + :type data: str | tkPhotoImage + :param size: size of a image (w,h) w=characters-wide, h=rows-high + :type size: Tuple[int,int] + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return image = None @@ -4537,15 +4485,14 @@ class Image(Element): if visible is not None: self._visible = visible - def update_animation(self, source, time_between_frames=0): """ Show an Animated GIF. Call the function as often as you like. The function will determine when to show the next frame and will automatically advance to the next frame at the right time. NOTE - does NOT perform a sleep call to delay - :param source: Filename or Base64 encoded string containing Animated GIF - :type source: str | bytes | None + :param source: Filename or Base64 encoded string containing Animated GIF + :type source: str | bytes | None :param time_between_frames: Number of milliseconds to wait between showing frames - :type time_between_frames: (int) + :type time_between_frames: (int) """ if self.Source != source: @@ -4569,7 +4516,7 @@ class Image(Element): break self.TotalAnimatedFrames = len(self.AnimatedFrames) self.LastFrameTime = time.time() - self.CurrentFrameNumber = -1 # start at -1 because it is incremented before every frame is shown + self.CurrentFrameNumber = -1 # start at -1 because it is incremented before every frame is shown # show the frame now = time.time() @@ -4588,16 +4535,14 @@ class Image(Element): except Exception as e: print('Exception in update_animation', e) - - def update_animation_no_buffering(self, source, time_between_frames=0): """ Show an Animated GIF. Call the function as often as you like. The function will determine when to show the next frame and will automatically advance to the next frame at the right time. NOTE - does NOT perform a sleep call to delay - :param source: Filename or Base64 encoded string containing Animated GIF - :type source: str | bytes + :param source: Filename or Base64 encoded string containing Animated GIF + :type source: str | bytes :param time_between_frames: Number of milliseconds to wait between showing frames - :type time_between_frames: (int) + :type time_between_frames: (int) """ if self.Source != source: @@ -4636,14 +4581,13 @@ class Image(Element): except: pass - - - - Update = update UpdateAnimation = update_animation + + Im = Image + # ---------------------------------------------------------------------- # # Canvas # # ---------------------------------------------------------------------- # @@ -4652,30 +4596,30 @@ class Canvas(Element): def __init__(self, canvas=None, background_color=None, size=(None, None), s=(None, None), pad=None, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, border_width=0, metadata=None): """ - :param canvas: Your own tk.Canvas if you already created it. Leave blank to create a Canvas - :type canvas: (tk.Canvas) + :param canvas: Your own tk.Canvas if you already created it. Leave blank to create a Canvas + :type canvas: (tk.Canvas) :param background_color: color of background - :type background_color: (str) - :param size: (width in char, height in rows) size in pixels to make canvas - :type size: (int,int) | (None, None) - :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) - :param pad: Amount of padding to put around element - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) + :type background_color: (str) + :param size: (width in char, height in rows) size in pixels to make canvas + :type size: (int,int) | (None, None) + :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) + :param pad: Amount of padding to put around element + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param border_width: width of border around element in pixels. Not normally used with Canvas element - :type border_width: (int) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param border_width: width of border around element in pixels. Not normally used with Canvas element + :type border_width: (int) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.BackgroundColor = background_color if background_color is not None else DEFAULT_BACKGROUND_COLOR @@ -4695,7 +4639,7 @@ class Canvas(Element): Returns the underlying tkiner Canvas widget :return: The tkinter canvas widget - :rtype: (tk.Canvas) + :rtype: (tk.Canvas) """ if self._TKCanvas is None: print('*** Did you forget to call Finalize()? Your code should look something like: ***') @@ -4725,38 +4669,38 @@ class Graph(Element): change_submits=False, drag_submits=False, enable_events=False, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, float_values=False, border_width=0, metadata=None): """ - :param canvas_size: size of the canvas area in pixels - :type canvas_size: (int, int) + :param canvas_size: size of the canvas area in pixels + :type canvas_size: (int, int) :param graph_bottom_left: (x,y) The bottoms left corner of your coordinate system - :type graph_bottom_left: (int, int) - :param graph_top_right: (x,y) The top right corner of your coordinate system - :type graph_top_right: (int, int) - :param background_color: background color of the drawing area - :type background_color: (str) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead - :type change_submits: (bool) - :param drag_submits: if True and Events are enabled for the Graph, will report Events any time the mouse moves while button down - :type drag_submits: (bool) - :param enable_events: If True then clicks on the Graph are immediately reported as an event. Use this instead of change_submits - :type enable_events: (bool) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element (Default = True) - :type visible: (bool) - :param float_values: If True x,y coordinates are returned as floats, not ints - :type float_values: (bool) - :param border_width: width of border around element in pixels. Not normally used for Graph Elements - :type border_width: (int) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type graph_bottom_left: (int, int) + :param graph_top_right: (x,y) The top right corner of your coordinate system + :type graph_top_right: (int, int) + :param background_color: background color of the drawing area + :type background_color: (str) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead + :type change_submits: (bool) + :param drag_submits: if True and Events are enabled for the Graph, will report Events any time the mouse moves while button down + :type drag_submits: (bool) + :param enable_events: If True then clicks on the Graph are immediately reported as an event. Use this instead of change_submits + :type enable_events: (bool) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element (Default = True) + :type visible: (bool) + :param float_values: If True x,y coordinates are returned as floats, not ints + :type float_values: (bool) + :param border_width: width of border around element in pixels. Not normally used for Graph Elements + :type border_width: (int) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.CanvasSize = canvas_size @@ -4774,7 +4718,6 @@ class Graph(Element): self.BorderWidth = border_width key = key if key is not None else k - super().__init__(ELEM_TYPE_GRAPH, background_color=background_color, size=canvas_size, pad=pad, key=key, tooltip=tooltip, visible=visible, metadata=metadata) return @@ -4783,11 +4726,11 @@ class Graph(Element): """ Not user callable. Used to convert user's coordinates into the ones used by tkinter :param x_in: The x coordinate to convert - :type x_in: int | float + :type x_in: int | float :param y_in: The y coordinate to convert - :type y_in: int | float - :return: (int, int) The converted canvas coordinates - :rtype: (int, int) + :type y_in: int | float + :return: (int, int) The converted canvas coordinates + :rtype: (int, int) """ if None in (x_in, y_in): return None, None @@ -4806,11 +4749,11 @@ class Graph(Element): Not user callable. Used to convert tkinter Canvas coords into user's coordinates :param x_in: The x coordinate in canvas coordinates - :type x_in: (int) + :type x_in: (int) :param y_in: (int) The y coordinate in canvas coordinates :type y_in: - :return: The converted USER coordinates - :rtype: (int, int) | Tuple[float, float] + :return: The converted USER coordinates + :rtype: (int, int) | Tuple[float, float] """ if None in (x_in, y_in): return None, None @@ -4828,15 +4771,15 @@ class Graph(Element): """ Draws a line from one point to another point using USER'S coordinates. Can set the color and width of line :param point_from: Starting point for line - :type point_from: (int, int) | Tuple[float, float] - :param point_to: Ending point for line - :type point_to: (int, int) | Tuple[float, float] - :param color: Color of the line - :type color: (str) - :param width: width of line in pixels - :type width: (int) - :return: id returned from tktiner or None if user closed the window. id is used when you - :rtype: int | None + :type point_from: (int, int) | Tuple[float, float] + :param point_to: Ending point for line + :type point_to: (int, int) | Tuple[float, float] + :param color: Color of the line + :type color: (str) + :param width: width of line in pixels + :type width: (int) + :return: id returned from tktiner or None if user closed the window. id is used when you + :rtype: int | None """ if point_from == (None, None): return @@ -4857,13 +4800,13 @@ class Graph(Element): Draw a series of lines given list of points :param points: list of points that define the polygon - :type points: List[(int, int) | Tuple[float, float]] - :param color: Color of the line - :type color: (str) - :param width: width of line in pixels - :type width: (int) - :return: id returned from tktiner or None if user closed the window. id is used when you - :rtype: int | None + :type points: List[(int, int) | Tuple[float, float]] + :param color: Color of the line + :type color: (str) + :param width: width of line in pixels + :type width: (int) + :return: id returned from tktiner or None if user closed the window. id is used when you + :rtype: int | None """ converted_points = [self._convert_xy_to_canvas_xy(point[0], point[1]) for point in points] @@ -4880,19 +4823,19 @@ class Graph(Element): """ Draws a "dot" at the point you specify using the USER'S coordinate system :param point: Center location using USER'S coordinate system - :type point: (int, int) | Tuple[float, float] - :param size: Radius? (Or is it the diameter?) in user's coordinate values. - :type size: int | float + :type point: (int, int) | Tuple[float, float] + :param size: Radius? (Or is it the diameter?) in user's coordinate values. + :type size: int | float :param color: color of the point to draw - :type color: (str) - :return: id returned from tkinter that you'll need if you want to manipulate the point - :rtype: int | None + :type color: (str) + :return: id returned from tkinter that you'll need if you want to manipulate the point + :rtype: int | None """ if point == (None, None): return converted_point = self._convert_xy_to_canvas_xy(point[0], point[1]) - size_converted = self._convert_xy_to_canvas_xy(point[0]+size, point[1]) - size = size_converted[0]-converted_point[0] + size_converted = self._convert_xy_to_canvas_xy(point[0] + size, point[1]) + size = size_converted[0] - converted_point[0] if self._TKCanvas2 is None: print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***') print('Call Window.Finalize() prior to this operation') @@ -4913,23 +4856,23 @@ class Graph(Element): """ Draws a circle, cenetered at the location provided. Can set the fill and outline colors :param center_location: Center location using USER'S coordinate system - :type center_location: (int, int) | Tuple[float, float] - :param radius: Radius in user's coordinate values. - :type radius: int | float - :param fill_color: color of the point to draw - :type fill_color: (str) - :param line_color: color of the outer line that goes around the circle (sorry, can't set thickness) - :type line_color: (str) - :param line_width: width of the line around the circle, the outline, in pixels - :type line_width: (int) - :return: id returned from tkinter that you'll need if you want to manipulate the circle - :rtype: int | None + :type center_location: (int, int) | Tuple[float, float] + :param radius: Radius in user's coordinate values. + :type radius: int | float + :param fill_color: color of the point to draw + :type fill_color: (str) + :param line_color: color of the outer line that goes around the circle (sorry, can't set thickness) + :type line_color: (str) + :param line_width: width of the line around the circle, the outline, in pixels + :type line_width: (int) + :return: id returned from tkinter that you'll need if you want to manipulate the circle + :rtype: int | None """ if center_location == (None, None): return converted_point = self._convert_xy_to_canvas_xy(center_location[0], center_location[1]) - radius_converted = self._convert_xy_to_canvas_xy(center_location[0]+radius, center_location[1]) - radius = radius_converted[0]-converted_point[0] + radius_converted = self._convert_xy_to_canvas_xy(center_location[0] + radius, center_location[1]) + radius = radius_converted[0] - converted_point[0] # radius = radius_converted[1]-5 if self._TKCanvas2 is None: print('*** WARNING - The Graph element has not been finalized and cannot be drawn upon ***') @@ -4948,18 +4891,18 @@ class Graph(Element): def draw_oval(self, top_left, bottom_right, fill_color=None, line_color=None, line_width=1): """ Draws an oval based on coordinates in user coordinate system. Provide the location of a "bounding rectangle" - :param top_left: the top left point of bounding rectangle - :type top_left: (int, int) | Tuple[float, float] + :param top_left: the top left point of bounding rectangle + :type top_left: (int, int) | Tuple[float, float] :param bottom_right: the bottom right point of bounding rectangle - :type bottom_right: (int, int) | Tuple[float, float] - :param fill_color: color of the interrior - :type fill_color: (str) - :param line_color: color of outline of oval - :type line_color: (str) - :param line_width: width of the line around the oval, the outline, in pixels - :type line_width: (int) - :return: id returned from tkinter that you'll need if you want to manipulate the oval - :rtype: int | None + :type bottom_right: (int, int) | Tuple[float, float] + :param fill_color: color of the interrior + :type fill_color: (str) + :param line_color: color of outline of oval + :type line_color: (str) + :param line_width: width of the line around the oval, the outline, in pixels + :type line_width: (int) + :return: id returned from tkinter that you'll need if you want to manipulate the oval + :rtype: int | None """ converted_top_left = self._convert_xy_to_canvas_xy(top_left[0], top_left[1]) converted_bottom_right = self._convert_xy_to_canvas_xy(bottom_right[0], bottom_right[1]) @@ -4969,7 +4912,7 @@ class Graph(Element): return None try: # in case windows close with X id = self._TKCanvas2.create_oval(converted_top_left[0], converted_top_left[1], converted_bottom_right[0], - converted_bottom_right[1], fill=fill_color, outline=line_color, width=line_width ) + converted_bottom_right[1], fill=fill_color, outline=line_color, width=line_width) except: id = None @@ -4978,22 +4921,22 @@ class Graph(Element): def draw_arc(self, top_left, bottom_right, extent, start_angle, style=None, arc_color='black', line_width=1, fill_color=None): """ Draws different types of arcs. Uses a "bounding box" to define location - :param top_left: the top left point of bounding rectangle - :type top_left: (int, int) | Tuple[float, float] + :param top_left: the top left point of bounding rectangle + :type top_left: (int, int) | Tuple[float, float] :param bottom_right: the bottom right point of bounding rectangle - :type bottom_right: (int, int) | Tuple[float, float] - :param extent: Andle to end drawing. Used in conjunction with start_angle - :type extent: (float) - :param start_angle: Angle to begin drawing. Used in conjunction with extent - :type start_angle: (float) - :param style: Valid choices are One of these Style strings- 'pieslice', 'chord', 'arc', 'first', 'last', 'butt', 'projecting', 'round', 'bevel', 'miter' - :type style: (str) - :param arc_color: color to draw arc with - :type arc_color: (str) - :param fill_color: color to fill the area - :type fill_color: (str) - :return: id returned from tkinter that you'll need if you want to manipulate the arc - :rtype: int | None + :type bottom_right: (int, int) | Tuple[float, float] + :param extent: Andle to end drawing. Used in conjunction with start_angle + :type extent: (float) + :param start_angle: Angle to begin drawing. Used in conjunction with extent + :type start_angle: (float) + :param style: Valid choices are One of these Style strings- 'pieslice', 'chord', 'arc', 'first', 'last', 'butt', 'projecting', 'round', 'bevel', 'miter' + :type style: (str) + :param arc_color: color to draw arc with + :type arc_color: (str) + :param fill_color: color to fill the area + :type fill_color: (str) + :return: id returned from tkinter that you'll need if you want to manipulate the arc + :rtype: int | None """ converted_top_left = self._convert_xy_to_canvas_xy(top_left[0], top_left[1]) converted_bottom_right = self._convert_xy_to_canvas_xy(bottom_right[0], bottom_right[1]) @@ -5007,7 +4950,7 @@ class Graph(Element): converted_bottom_right[1], extent=extent, start=start_angle, style=tkstyle, outline=arc_color, width=line_width, fill=fill_color) except Exception as e: - print('Error encountered drawing arc.',e) + print('Error encountered drawing arc.', e) id = None return id @@ -5015,18 +4958,18 @@ class Graph(Element): """ Draw a rectangle given 2 points. Can control the line and fill colors - :param top_left: the top left point of rectangle - :type top_left: (int, int) | Tuple[float, float] + :param top_left: the top left point of rectangle + :type top_left: (int, int) | Tuple[float, float] :param bottom_right: the bottom right point of rectangle - :type bottom_right: (int, int) | Tuple[float, float] - :param fill_color: color of the interior - :type fill_color: (str) - :param line_color: color of outline - :type line_color: (str) - :param line_width: width of the line in pixels - :type line_width: (int) - :return: int | None id returned from tkinter that you'll need if you want to manipulate the rectangle - :rtype: int | None + :type bottom_right: (int, int) | Tuple[float, float] + :param fill_color: color of the interior + :type fill_color: (str) + :param line_color: color of outline + :type line_color: (str) + :param line_width: width of the line in pixels + :type line_width: (int) + :return: int | None id returned from tkinter that you'll need if you want to manipulate the rectangle + :rtype: int | None """ converted_top_left = self._convert_xy_to_canvas_xy(top_left[0], top_left[1]) @@ -5045,21 +4988,20 @@ class Graph(Element): id = None return id - def draw_polygon(self, points, fill_color=None, line_color=None, line_width=None): """ Draw a polygon given list of points - :param points: list of points that define the polygon - :type points: List[(int, int) | Tuple[float, float]] + :param points: list of points that define the polygon + :type points: List[(int, int) | Tuple[float, float]] :param fill_color: color of the interior - :type fill_color: (str) + :type fill_color: (str) :param line_color: color of outline - :type line_color: (str) + :type line_color: (str) :param line_width: width of the line in pixels - :type line_width: (int) - :return: id returned from tkinter that you'll need if you want to manipulate the rectangle - :rtype: int | None + :type line_width: (int) + :return: id returned from tkinter that you'll need if you want to manipulate the rectangle + :rtype: int | None """ converted_points = [self._convert_xy_to_canvas_xy(point[0], point[1]) for point in points] @@ -5073,26 +5015,24 @@ class Graph(Element): id = None return id - - def draw_text(self, text, location, color='black', font=None, angle=0, text_location=TEXT_LOCATION_CENTER): """ Draw some text on your graph. This is how you label graph number lines for example - :param text: text to display - :type text: (Any) - :param location: location to place first letter - :type location: (int, int) | Tuple[float, float] - :param color: text color - :type color: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param angle: Angle 0 to 360 to draw the text. Zero represents horizontal text - :type angle: (float) + :param text: text to display + :type text: (Any) + :param location: location to place first letter + :type location: (int, int) | Tuple[float, float] + :param color: text color + :type color: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param angle: Angle 0 to 360 to draw the text. Zero represents horizontal text + :type angle: (float) :param text_location: "anchor" location for the text. Values start with TEXT_LOCATION_ - :type text_location: (enum) - :return: id returned from tkinter that you'll need if you want to manipulate the text - :rtype: int | None + :type text_location: (enum) + :return: id returned from tkinter that you'll need if you want to manipulate the text + :rtype: int | None """ text = str(text) if location == (None, None): @@ -5113,13 +5053,13 @@ class Graph(Element): Places an image onto your canvas. It's a really important method for this element as it enables so much :param filename: if image is in a file, path and filename for the image. (GIF and PNG only!) - :type filename: (str) - :param data: if image is in Base64 format or raw? format then use instead of filename - :type data: str | bytes + :type filename: (str) + :param data: if image is in Base64 format or raw? format then use instead of filename + :type data: str | bytes :param location: the (x,y) location to place image's top left corner - :type location: (int, int) | Tuple[float, float] - :return: id returned from tkinter that you'll need if you want to manipulate the image - :rtype: int | None + :type location: (int, int) | Tuple[float, float] + :return: id returned from tkinter that you'll need if you want to manipulate the image + :rtype: int | None """ if location == (None, None): return @@ -5162,7 +5102,7 @@ class Graph(Element): Remove from the Graph the figure represented by id. The id is given to you anytime you call a drawing primitive :param id: the id returned to you when calling one of the drawing methods - :type id: (int) + :type id: (int) """ try: self._TKCanvas2.delete(id) @@ -5178,11 +5118,11 @@ class Graph(Element): Changes some of the settings for the Graph Element. Must call `Window.Read` or `Window.Finalize` prior :param background_color: color of background - :type background_color: ??? - :param visible: control visibility of element - :type visible: (bool) + :type background_color: ??? + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if background_color is not None and background_color != COLOR_SYSTEM_DEFAULT: @@ -5199,9 +5139,9 @@ class Graph(Element): Moves the entire drawing area (the canvas) by some delta from the current position. Units are indicated in your coordinate system indicated number of ticks in your coordinate system :param x_direction: how far to move in the "X" direction in your coordinates - :type x_direction: int | float + :type x_direction: int | float :param y_direction: how far to move in the "Y" direction in your coordinates - :type y_direction: int | float + :type y_direction: int | float """ zero_converted = self._convert_xy_to_canvas_xy(0, 0) shift_converted = self._convert_xy_to_canvas_xy(x_direction, y_direction) @@ -5216,12 +5156,12 @@ class Graph(Element): """ Moves a previously drawn figure using a "delta" from current position - :param figure: Previously obtained figure-id. These are returned from all Draw methods - :type figure: (id) + :param figure: Previously obtained figure-id. These are returned from all Draw methods + :type figure: (id) :param x_direction: delta to apply to position in the X direction - :type x_direction: int | float + :type x_direction: int | float :param y_direction: delta to apply to position in the Y direction - :type y_direction: int | float + :type y_direction: int | float """ zero_converted = self._convert_xy_to_canvas_xy(0, 0) shift_converted = self._convert_xy_to_canvas_xy(x_direction, y_direction) @@ -5237,11 +5177,11 @@ class Graph(Element): uses absolute coordinates versus relative for Move :param figure: Previously obtained figure-id. These are returned from all Draw methods - :type figure: (id) - :param x: location on X axis (in user coords) to move the upper left corner of the figure - :type x: int | float - :param y: location on Y axis (in user coords) to move the upper left corner of the figure - :type y: int | float + :type figure: (id) + :param x: location on X axis (in user coords) to move the upper left corner of the figure + :type x: int | float + :param y: location on Y axis (in user coords) to move the upper left corner of the figure + :type y: int | float """ zero_converted = self._convert_xy_to_canvas_xy(0, 0) @@ -5259,7 +5199,7 @@ class Graph(Element): Changes Z-order of figures on the Graph. Sends the indicated figure to the back of all other drawn figures :param figure: value returned by tkinter when creating the figure / drawing - :type figure: (int) + :type figure: (int) """ self.TKCanvas.tag_lower(figure) # move figure to the "bottom" of all other figure @@ -5268,22 +5208,21 @@ class Graph(Element): Changes Z-order of figures on the Graph. Brings the indicated figure to the front of all other drawn figures :param figure: value returned by tkinter when creating the figure / drawing - :type figure: (int) + :type figure: (int) """ self.TKCanvas.tag_raise(figure) # move figure to the "top" of all other figures - def get_figures_at_location(self, location): """ Returns a list of figures located at a particular x,y location within the Graph :param location: point to check - :type location: (int, int) | Tuple[float, float] - :return: a list of previously drawn "Figures" (returned from the drawing primitives) - :rtype: List[int] + :type location: (int, int) | Tuple[float, float] + :return: a list of previously drawn "Figures" (returned from the drawing primitives) + :rtype: List[int] """ x, y = self._convert_xy_to_canvas_xy(location[0], location[1]) - ids = self.TKCanvas.find_overlapping(x,y,x,y) + ids = self.TKCanvas.find_overlapping(x, y, x, y) return ids def get_bounding_box(self, figure): @@ -5291,15 +5230,14 @@ class Graph(Element): Given a figure, returns the upper left and lower right bounding box coordinates :param figure: a previously drawing figure - :type figure: object - :return: upper left x, upper left y, lower right x, lower right y - :rtype: Tuple[int, int, int, int] | Tuple[float, float, float, float] + :type figure: object + :return: upper left x, upper left y, lower right x, lower right y + :rtype: Tuple[int, int, int, int] | Tuple[float, float, float, float] """ box = self.TKCanvas.bbox(figure) top_left = self._convert_canvas_xy_to_xy(box[0], box[1]) bottom_right = self._convert_canvas_xy_to_xy(box[2], box[3]) - return top_left,bottom_right - + return top_left, bottom_right def change_coordinates(self, graph_bottom_left, graph_top_right): """ @@ -5307,21 +5245,20 @@ class Graph(Element): system - the bottom left and the top right values of your graph. :param graph_bottom_left: The bottoms left corner of your coordinate system - :type graph_bottom_left: (int, int) (x,y) - :param graph_top_right: The top right corner of your coordinate system - :type graph_top_right: (int, int) (x,y) + :type graph_bottom_left: (int, int) (x,y) + :param graph_top_right: The top right corner of your coordinate system + :type graph_top_right: (int, int) (x,y) """ self.BottomLeft = graph_bottom_left self.TopRight = graph_top_right - @property def tk_canvas(self): """ Returns the underlying tkiner Canvas widget :return: The tkinter canvas widget - :rtype: (tk.Canvas) + :rtype: (tk.Canvas) """ if self._TKCanvas2 is None: print('*** Did you forget to call Finalize()? Your code should look something like: ***') @@ -5373,7 +5310,6 @@ class Graph(Element): _exit_mainloop(self.ParentForm) self.MouseButtonDown = True - def _update_position_for_returned_values(self, event): """ Updates the variable that's used when the values dictionary is returned from a window read. @@ -5388,12 +5324,11 @@ class Graph(Element): Not called by the user. It's called from another method/function that tkinter calledback :param event: (event) event info from tkinter. Contains the x and y coordinates of a click - :type event: + :type event: """ self.ClickPosition = self._convert_canvas_xy_to_xy(event.x, event.y) - # button callback def motion_call_back(self, event): """ @@ -5439,8 +5374,10 @@ class Graph(Element): TKCanvas = tk_canvas Update = update + G = Graph + # ---------------------------------------------------------------------- # # Frame # # ---------------------------------------------------------------------- # @@ -5453,44 +5390,44 @@ class Frame(Element): relief=DEFAULT_FRAME_RELIEF, size=(None, None), s=(None, None), font=None, pad=None, border_width=None, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, element_justification='left', vertical_alignment=None, metadata=None): """ - :param title: text that is displayed as the Frame's "label" or title - :type title: (str) - :param layout: The layout to put inside the Frame - :type layout: List[List[Elements]] - :param title_color: color of the title text - :type title_color: (str) - :param background_color: background color of the Frame - :type background_color: (str) - :param title_location: location to place the text title. Choices include: TITLE_LOCATION_TOP TITLE_LOCATION_BOTTOM TITLE_LOCATION_LEFT TITLE_LOCATION_RIGHT TITLE_LOCATION_TOP_LEFT TITLE_LOCATION_TOP_RIGHT TITLE_LOCATION_BOTTOM_LEFT TITLE_LOCATION_BOTTOM_RIGHT - :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 - :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 - :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 - :type s: (int, int) | (None, None) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param border_width: width of border around element in pixels - :type border_width: (int) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) + :param title: text that is displayed as the Frame's "label" or title + :type title: (str) + :param layout: The layout to put inside the Frame + :type layout: List[List[Elements]] + :param title_color: color of the title text + :type title_color: (str) + :param background_color: background color of the Frame + :type background_color: (str) + :param title_location: location to place the text title. Choices include: TITLE_LOCATION_TOP TITLE_LOCATION_BOTTOM TITLE_LOCATION_LEFT TITLE_LOCATION_RIGHT TITLE_LOCATION_TOP_LEFT TITLE_LOCATION_TOP_RIGHT TITLE_LOCATION_BOTTOM_LEFT TITLE_LOCATION_BOTTOM_RIGHT + :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 + :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 + :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 + :type s: (int, int) | (None, None) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param border_width: width of border around element in pixels + :type border_width: (int) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) :param element_justification: All elements inside the Frame will have this justification 'left', 'right', 'center' are valid values - :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) - :type vertical_alignment: (str) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :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) + :type vertical_alignment: (str) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.UseDictionary = False @@ -5511,7 +5448,7 @@ class Frame(Element): self.ContainerElemementNumber = Window._GetAContainerNumber() self.ElementJustification = element_justification self.VerticalAlignment = vertical_alignment - self.Widget = None # type: tk.LabelFrame + self.Widget = None # type: tk.LabelFrame self.Layout(layout) key = key if key is not None else k sz = size if size != (None, None) else s @@ -5525,7 +5462,7 @@ class Frame(Element): Not recommended user call. Used to add rows of Elements to the Frame Element. :param *args: The list of elements for this row - :type *args: List[Element] + :type *args: List[Element] """ NumRows = len(self.Rows) # number of existing rows is our row number CurrentRowNumber = NumRows # this row's number @@ -5552,16 +5489,18 @@ class Frame(Element): keep_on_top=True) continue if element.ParentContainer is not None: - warnings.warn('*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', UserWarning) + warnings.warn( + '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', + UserWarning) _error_popup_with_traceback('Error creating Frame layout', - 'The layout specified has already been used', - 'You MUST start witha "clean", unused layout every time you create a window', - 'The offensive Element = ', - element, - 'and has a key = ', element.Key, - 'This item will be stripped from your layout', - 'Hint - try printing your layout and matching the IDs "print(layout)"', - ) + 'The layout specified has already been used', + 'You MUST start witha "clean", unused layout every time you create a window', + 'The offensive Element = ', + element, + 'and has a key = ', element.Key, + 'This item will be stripped from your layout', + 'Hint - try printing your layout and matching the IDs "print(layout)"', + ) continue element.Position = (CurrentRowNumber, i) element.ParentContainer = self @@ -5576,9 +5515,9 @@ class Frame(Element): Can use like the Window.Layout method, but it's better to use the layout parameter when creating :param rows: The rows of Elements - :type rows: List[List[Element]] - :return: Used for chaining - :rtype: (Frame) + :type rows: List[List[Element]] + :return: Used for chaining + :rtype: (Frame) """ for row in rows: @@ -5600,9 +5539,9 @@ class Frame(Element): Not user callable. Used to find the Element at a row, col position within the layout :param location: (row, column) position of the element to find in layout - :type location: (int, int) - :return: (Element) The element found at the location - :rtype: (Element) + :type location: (int, int) + :return: (Element) The element found at the location + :rtype: (Element) """ (row_num, col_num) = location @@ -5614,12 +5553,12 @@ class Frame(Element): """ Changes some of the settings for the Frame Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: New text value to show on frame - :type value: (Any) + :param value: New text value to show on frame + :type value: (Any) :param visible: control visibility of element - :type visible: (bool) + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if visible is False: @@ -5634,8 +5573,11 @@ class Frame(Element): AddRow = add_row Layout = layout Update = update + + Fr = Frame + # ---------------------------------------------------------------------- # # Vertical Separator # # ---------------------------------------------------------------------- # @@ -5648,13 +5590,13 @@ class VerticalSeparator(Element): def __init__(self, color=None, pad=None, key=None, k=None): """ :param color: Color of the line. Defaults to theme's text color. Can be name or #RRGGBB format - :type color: (str) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object + :type color: (str) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object """ key = key if key is not None else k @@ -5679,13 +5621,13 @@ class HorizontalSeparator(Element): def __init__(self, color=None, pad=None, key=None, k=None): """ :param color: Color of the line. Defaults to theme's text color. Can be name or #RRGGBB format - :type color: (str) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object + :type color: (str) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object """ self.Orientation = 'horizontal' # for now only vertical works @@ -5695,12 +5637,10 @@ class HorizontalSeparator(Element): super().__init__(ELEM_TYPE_SEPARATOR, pad=pad, key=key) - HSeparator = HorizontalSeparator HSep = HorizontalSeparator - # ---------------------------------------------------------------------- # # Sizegrip # # ---------------------------------------------------------------------- # @@ -5715,7 +5655,7 @@ class Sizegrip(Element): """ :param background_color: color to use for the background of the grip - :type background_color: str + :type background_color: str """ bg = background_color if background_color is not None else theme_background_color() @@ -5725,9 +5665,6 @@ class Sizegrip(Element): SGrip = Sizegrip - - - # ---------------------------------------------------------------------- # # Tab # # ---------------------------------------------------------------------- # @@ -5740,36 +5677,36 @@ class Tab(Element): def __init__(self, title, layout, title_color=None, background_color=None, font=None, pad=None, disabled=False, border_width=None, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, element_justification='left', metadata=None): """ - :param title: text to show on the tab - :type title: (str) - :param layout: The element layout that will be shown in the tab - :type layout: List[List[Element]] - :param title_color: color of the tab text (note not currently working on tkinter) - :type title_color: (str) - :param background_color: color of background of the entire layout - :type background_color: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param disabled: If True button will be created disabled - :type disabled: (bool) - :param border_width: width of border around element in pixels - :type border_width: (int) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) + :param title: text to show on the tab + :type title: (str) + :param layout: The element layout that will be shown in the tab + :type layout: List[List[Element]] + :param title_color: color of the tab text (note not currently working on tkinter) + :type title_color: (str) + :param background_color: color of background of the entire layout + :type background_color: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param disabled: If True button will be created disabled + :type disabled: (bool) + :param border_width: width of border around element in pixels + :type border_width: (int) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) :param element_justification: All elements inside the Tab will have this justification 'left', 'right', 'center' are valid values - :type element_justification: (str) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type element_justification: (str) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.UseDictionary = False @@ -5780,7 +5717,7 @@ class Tab(Element): self.ParentWindow = None self.Rows = [] self.TKFrame = None - self.Widget = None # type: tk.Frame + self.Widget = None # type: tk.Frame self.Title = title self.BorderWidth = border_width self.Disabled = disabled @@ -5794,7 +5731,8 @@ class Tab(Element): self.Layout(layout) - super().__init__(ELEM_TYPE_TAB, background_color=background_color, text_color=title_color, font=font, pad=pad, key=key, tooltip=tooltip, visible=visible, metadata=metadata) + super().__init__(ELEM_TYPE_TAB, background_color=background_color, text_color=title_color, font=font, pad=pad, key=key, tooltip=tooltip, + visible=visible, metadata=metadata) return def add_row(self, *args): @@ -5802,7 +5740,7 @@ class Tab(Element): Not recommended use call. Used to add rows of Elements to the Frame Element. :param *args: The list of elements for this row - :type *args: List[Element] + :type *args: List[Element] """ NumRows = len(self.Rows) # number of existing rows is our row number CurrentRowNumber = NumRows # this row's number @@ -5815,7 +5753,7 @@ class Tab(Element): 'This means you have a badly placed ]', 'The offensive list is:', element, - 'This list will be stripped from your layout' , keep_on_top=True, image=_random_error_emoji() + 'This list will be stripped from your layout', keep_on_top=True, image=_random_error_emoji() ) continue elif callable(element) and not isinstance(element, Element): @@ -5827,7 +5765,9 @@ class Tab(Element): 'This item will be stripped from your layout', keep_on_top=True, image=_random_error_emoji()) continue if element.ParentContainer is not None: - warnings.warn('*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', UserWarning) + warnings.warn( + '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', + UserWarning) PopupError('Error creating Tab layout', 'The layout specified has already been used', 'You MUST start witha "clean", unused layout every time you create a window', @@ -5850,8 +5790,8 @@ class Tab(Element): Not user callable. Use layout parameter instead. Creates the layout using the supplied rows of Elements :param rows: List[List[Element]] The list of rows - :type rows: List[List[Element]] - :return: (Tab) used for chaining + :type rows: List[List[Element]] + :return: (Tab) used for chaining """ for row in rows: @@ -5868,19 +5808,18 @@ class Tab(Element): self.AddRow(*row) return self - def update(self, title=None, disabled=None, visible=None): """ Changes some of the settings for the Tab Element. Must call `Window.Read` or `Window.Finalize` prior - :param title: tab title - :type title: (str) + :param title: tab title + :type title: (str) :param disabled: disable or enable state of the element - :type disabled: (bool) - :param visible: control visibility of element - :type visible: (bool) + :type disabled: (bool) + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return state = 'normal' @@ -5911,9 +5850,9 @@ class Tab(Element): Not user callable. Used to find the Element at a row, col position within the layout :param location: (row, column) position of the element to find in layout - :type location: (int, int) - :return: The element found at the location - :rtype: (Element) + :type location: (int, int) + :return: The element found at the location + :rtype: (Element) """ (row_num, col_num) = location @@ -5932,12 +5871,12 @@ class Tab(Element): except Exception as e: print('Exception Selecting Tab {}'.format(e)) - AddRow = add_row Layout = layout Select = select Update = update + # ---------------------------------------------------------------------- # # TabGroup # # ---------------------------------------------------------------------- # @@ -5946,50 +5885,52 @@ class TabGroup(Element): TabGroup Element groups together your tabs into the group of tabs you see displayed in your window """ - 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, border_width=None, theme=None, key=None, k=None, size=(None, None), s=(None, None), tooltip=None, right_click_menu=None, visible=True, metadata=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, border_width=None, theme=None, key=None, k=None, + size=(None, None), s=(None, None), tooltip=None, right_click_menu=None, visible=True, metadata=None): """ - :param layout: Layout of Tabs. Different than normal layouts. ALL Tabs should be on first row - :type layout: List[List[Tab]] - :param tab_location: location that tabs will be displayed. Choices are left, right, top, bottom, lefttop, leftbottom, righttop, rightbottom, bottomleft, bottomright, topleft, topright - :type tab_location: (str) - :param title_color: color of text on tabs - :type title_color: (str) - :param tab_background_color: color of all tabs that are not selected - :type tab_background_color: (str) - :param selected_title_color: color of tab text when it is selected - :type selected_title_color: (str) + :param layout: Layout of Tabs. Different than normal layouts. ALL Tabs should be on first row + :type layout: List[List[Tab]] + :param tab_location: location that tabs will be displayed. Choices are left, right, top, bottom, lefttop, leftbottom, righttop, rightbottom, bottomleft, bottomright, topleft, topright + :type tab_location: (str) + :param title_color: color of text on tabs + :type title_color: (str) + :param tab_background_color: color of all tabs that are not selected + :type tab_background_color: (str) + :param selected_title_color: color of tab text when it is selected + :type selected_title_color: (str) :param selected_background_color: color of tab when it is selected - :type selected_background_color: (str) - :param background_color: color of background area that tabs are located on - :type background_color: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead - :type change_submits: (bool) - :param enable_events: If True then switching tabs will generate an Event - :type enable_events: (bool) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param border_width: width of border around element in pixels - :type 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 - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param size: (width, height) w=pixels-wide, h=pixels-high. Either item in tuple can be None to indicate use the computed value and set only 1 direction - :type size: (int|None, int|None) - :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|None, int|None) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type selected_background_color: (str) + :param background_color: color of background area that tabs are located on + :type background_color: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead + :type change_submits: (bool) + :param enable_events: If True then switching tabs will generate an Event + :type enable_events: (bool) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param border_width: width of border around element in pixels + :type 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 + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param size: (width, height) w=pixels-wide, h=pixels-high. Either item in tuple can be None to indicate use the computed value and set only 1 direction + :type size: (int|None, int|None) + :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|None, int|None) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.UseDictionary = False @@ -6027,7 +5968,7 @@ class TabGroup(Element): """ Not recommended user call. Used to add rows of Elements to the Frame Element. - :param *args: The list of elements for this row + :param *args: The list of elements for this row :typeparam *args: List[Element] """ @@ -6042,7 +5983,7 @@ class TabGroup(Element): 'This means you have a badly placed ]', 'The offensive list is:', element, - 'This list will be stripped from your layout' , keep_on_top=True, image=_random_error_emoji() + 'This list will be stripped from your layout', keep_on_top=True, image=_random_error_emoji() ) continue elif callable(element) and not isinstance(element, Element): @@ -6054,7 +5995,9 @@ class TabGroup(Element): 'This item will be stripped from your layout', keep_on_top=True, image=_random_error_emoji()) continue if element.ParentContainer is not None: - warnings.warn('*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', UserWarning) + warnings.warn( + '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', + UserWarning) PopupError('Error creating Tab layout', 'The layout specified has already been used', 'You MUST start witha "clean", unused layout every time you create a window', @@ -6077,9 +6020,9 @@ class TabGroup(Element): Can use like the Window.Layout method, but it's better to use the layout parameter when creating :param rows: The rows of Elements - :type rows: List[List[Element]] - :return: Used for chaining - :rtype: (Frame) + :type rows: List[List[Element]] + :return: Used for chaining + :rtype: (Frame) """ for row in rows: try: @@ -6095,15 +6038,14 @@ class TabGroup(Element): self.AddRow(*row) return self - def _GetElementAtLocation(self, location): """ Not user callable. Used to find the Element at a row, col position within the layout :param location: (row, column) position of the element to find in layout - :type location: (int, int) - :return: The element found at the location - :rtype: (Element) + :type location: (int, int) + :return: The element found at the location + :rtype: (Element) """ (row_num, col_num) = location @@ -6116,9 +6058,9 @@ class TabGroup(Element): Searches through the layout to find the key that matches the text on the tab. Implies names should be unique :param tab_name: name of a tab - :type tab_name: str - :return: Returns the key or None if no key found - :rtype: key | None + :type tab_name: str + :return: Returns the key or None if no key found + :rtype: key | None """ for row in self.Rows: for element in row: @@ -6133,8 +6075,8 @@ class TabGroup(Element): Note that this is exactly the same data that would be returned from a call to Window.Read. Are you sure you are using this method correctly? - :return: The key of the currently selected tab or the tab's text if it has no key - :rtype: Any | None + :return: The key of the currently selected tab or the tab's text if it has no key + :rtype: Any | None """ try: @@ -6146,7 +6088,6 @@ class TabGroup(Element): value = None return value - def add_tab(self, tab_element): self.add_row(tab_element) tab_element.TKFrame = tab_element.Widget = tk.Frame(self.TKNotebook) @@ -6164,14 +6105,14 @@ class TabGroup(Element): tab_element.TabID = self.TabCount self.TabCount += 1 if tab_element.BackgroundColor != COLOR_SYSTEM_DEFAULT and tab_element.BackgroundColor is not None: - tab_element.TKFrame.configure(background=tab_element.BackgroundColor, highlightbackground=tab_element.BackgroundColor, highlightcolor=tab_element.BackgroundColor) + tab_element.TKFrame.configure(background=tab_element.BackgroundColor, highlightbackground=tab_element.BackgroundColor, + highlightcolor=tab_element.BackgroundColor) if tab_element.BorderWidth is not None: tab_element.TKFrame.configure(borderwidth=tab_element.BorderWidth) if tab_element.Tooltip is not None: tab_element.TooltipObject = ToolTip(tab_element.TKFrame, text=tab_element.Tooltip, timeout=DEFAULT_TOOLTIP_TIME) _add_right_click_menu(tab_element, form) - AddRow = add_row FindKeyFromTabName = find_key_from_tab_name Get = get @@ -6191,52 +6132,52 @@ class Slider(Element): enable_events=False, disabled=False, size=(None, None), s=(None, None), font=None, background_color=None, text_color=None, trough_color=None, key=None, k=None, pad=None, tooltip=None, visible=True, metadata=None): """ - :param range: slider's range (min value, max value) - :type range: (int, int) | Tuple[float, float] - :param default_value: starting value for the slider - :type default_value: int | float - :param resolution: the smallest amount the slider can be moved - :type resolution: int | float - :param tick_interval: how often a visible tick should be shown next to slider - :type tick_interval: int | float - :param orientation: 'horizontal' or 'vertical' ('h' or 'v' also work) - :type orientation: (str) + :param range: slider's range (min value, max value) + :type range: (int, int) | Tuple[float, float] + :param default_value: starting value for the slider + :type default_value: int | float + :param resolution: the smallest amount the slider can be moved + :type resolution: int | float + :param tick_interval: how often a visible tick should be shown next to slider + :type tick_interval: int | float + :param orientation: 'horizontal' or 'vertical' ('h' or 'v' also work) + :type orientation: (str) :param disable_number_display: if True no number will be displayed by the Slider Element - :type disable_number_display: (bool) - :param border_width: width of border around element in pixels - :type border_width: (int) - :param relief: relief style. Use constants - RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID - :type relief: str | None - :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead - :type change_submits: (bool) - :param enable_events: If True then moving the slider will generate an Event - :type enable_events: (bool) - :param disabled: set disable state for element - :type disabled: (bool) - :param size: (w=characters-wide, h=rows-high) - :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 - :type s: (int, int) | (None, None) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param background_color: color of slider's background - :type background_color: (str) - :param text_color: color of the slider's text - :type text_color: (str) - :param trough_color: color of the slider's trough - :type trough_color: (str) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type disable_number_display: (bool) + :param border_width: width of border around element in pixels + :type border_width: (int) + :param relief: relief style. Use constants - RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID + :type relief: str | None + :param change_submits: * DEPRICATED DO NOT USE. Use `enable_events` instead + :type change_submits: (bool) + :param enable_events: If True then moving the slider will generate an Event + :type enable_events: (bool) + :param disabled: set disable state for element + :type disabled: (bool) + :param size: (w=characters-wide, h=rows-high) + :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 + :type s: (int, int) | (None, None) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param background_color: color of slider's background + :type background_color: (str) + :param text_color: color of the slider's text + :type text_color: (str) + :param trough_color: color of the slider's trough + :type trough_color: (str) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.TKScale = self.Widget = None # type: tk.Scale @@ -6265,16 +6206,16 @@ class Slider(Element): """ Changes some of the settings for the Slider Element. Must call `Window.Read` or `Window.Finalize` prior - :param value: sets current slider value - :type value: int | float - :param range: Sets a new range for slider - :type range: (int, int) | Tuple[float, float + :param value: sets current slider value + :type value: int | float + :param range: Sets a new range for slider + :type range: (int, int) | Tuple[float, float :param disabled: disable or enable state of the element - :type disabled: (bool) - :param visible: control visibility of element - :type visible: (bool) + :type disabled: (bool) + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if value is not None: @@ -6314,8 +6255,10 @@ class Slider(Element): Update = update + Sl = Slider + # ---------------------------------------------------------------------- # # TkFixedFrame (Used by Column) # # ---------------------------------------------------------------------- # @@ -6326,8 +6269,8 @@ class TkFixedFrame(tk.Frame): def __init__(self, master, **kwargs): """ - :param master: The parent widget - :type master: (tk.Widget) + :param master: The parent widget + :type master: (tk.Widget) :param **kwargs: The keyword args """ tk.Frame.__init__(self, master, **kwargs) @@ -6358,10 +6301,10 @@ class TkScrollableFrame(tk.Frame): def __init__(self, master, vertical_only, **kwargs): """ - :param master: The parent widget - :type master: (tk.Widget) + :param master: The parent widget + :type master: (tk.Widget) :param vertical_only: if True the only a vertical scrollbar will be shown - :type vertical_only: (bool) + :type vertical_only: (bool) """ tk.Frame.__init__(self, master, **kwargs) # create a canvas object and a vertical scrollbar for scrolling it @@ -6412,7 +6355,7 @@ class TkScrollableFrame(tk.Frame): # Chr0nic def hookMouseWheel(self, e): - #print("enter") + # print("enter") VarHolder.canvas_holder = self.canvas self.TKFrame.bind_all('<4>', self.yscroll, add='+') self.TKFrame.bind_all('<5>', self.yscroll, add='+') @@ -6421,7 +6364,7 @@ class TkScrollableFrame(tk.Frame): # Chr0nic def unhookMouseWheel(self, e): - #print("leave") + # print("leave") VarHolder.canvas_holder = None self.TKFrame.unbind_all('<4>') self.TKFrame.unbind_all('<5>') @@ -6466,44 +6409,45 @@ class Column(Element): """ def __init__(self, layout, background_color=None, size=(None, None), s=(None, None), pad=None, scrollable=False, - vertical_scroll_only=False, right_click_menu=None, key=None, k=None, visible=True, justification=None, element_justification=None, vertical_alignment=None, grab=None, expand_x=None, expand_y=None, metadata=None): + vertical_scroll_only=False, right_click_menu=None, key=None, k=None, visible=True, justification=None, element_justification=None, + vertical_alignment=None, grab=None, expand_x=None, expand_y=None, metadata=None): """ - :param layout: Layout that will be shown in the Column container - :type layout: List[List[Element]] - :param background_color: color of background of entire Column - :type background_color: (str) - :param size: (width, height) size in pixels (doesn't work quite right, sometimes only 1 dimension is set by tkinter - :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 - :type s: (int, int) | (None, None) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param scrollable: if True then scrollbars will be added to the column - :type scrollable: (bool) - :param vertical_scroll_only: if Truen then no horizontal scrollbar will be shown - :type vertical_scroll_only: (bool) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param visible: set visibility state of the element - :type visible: (bool) - :param justification: set justification for the Column itself. Note entire row containing the Column will be affected - :type justification: (str) + :param layout: Layout that will be shown in the Column container + :type layout: List[List[Element]] + :param background_color: color of background of entire Column + :type background_color: (str) + :param size: (width, height) size in pixels (doesn't work quite right, sometimes only 1 dimension is set by tkinter + :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 + :type s: (int, int) | (None, None) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param scrollable: if True then scrollbars will be added to the column + :type scrollable: (bool) + :param vertical_scroll_only: if Truen then no horizontal scrollbar will be shown + :type vertical_scroll_only: (bool) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param visible: set visibility state of the element + :type visible: (bool) + :param justification: set justification for the Column itself. Note entire row containing the Column will be affected + :type justification: (str) :param element_justification: All elements inside the Column will have this justification 'left', 'right', 'center' are valid values - :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) - :type vertical_alignment: (str) - :param grab: If True can grab this element and move the window around. Default is False - :type grab: (bool) - :param expand_x: If True the column will automatically expand in the X direction to fill available space - :type expand_x: (bool) - :param expand_y: If True the column will automatically expand in the Y direction to fill available space - :type expand_y: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :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) + :type vertical_alignment: (str) + :param grab: If True can grab this element and move the window around. Default is False + :type grab: (bool) + :param expand_x: If True the column will automatically expand in the X direction to fill available space + :type expand_x: (bool) + :param expand_y: If True the column will automatically expand in the Y direction to fill available space + :type expand_y: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.UseDictionary = False @@ -6515,7 +6459,7 @@ class Column(Element): self.ParentPanedWindow = None self.Rows = [] self.TKFrame = None - self.TKColFrame = None # type: tk.Frame + self.TKColFrame = None # type: tk.Frame self.Scrollable = scrollable self.VerticalScrollOnly = vertical_scroll_only @@ -6540,7 +6484,7 @@ class Column(Element): Not recommended user call. Used to add rows of Elements to the Column Element. :param *args: The list of elements for this row - :type *args: List[Element] + :type *args: List[Element] """ NumRows = len(self.Rows) # number of existing rows is our row number @@ -6554,7 +6498,7 @@ class Column(Element): 'This means you have a badly placed ]', 'The offensive list is:', element, - 'This list will be stripped from your layout' , keep_on_top=True, image=_random_error_emoji() + 'This list will be stripped from your layout', keep_on_top=True, image=_random_error_emoji() ) continue elif callable(element) and not isinstance(element, Element): @@ -6566,7 +6510,9 @@ class Column(Element): 'This item will be stripped from your layout', keep_on_top=True, image=_random_error_emoji()) continue if element.ParentContainer is not None: - warnings.warn('*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', UserWarning) + warnings.warn( + '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', + UserWarning) PopupError('Error creating Column layout', 'The layout specified has already been used', 'You MUST start witha "clean", unused layout every time you create a window', @@ -6589,9 +6535,9 @@ class Column(Element): Can use like the Window.Layout method, but it's better to use the layout parameter when creating :param rows: The rows of Elements - :type rows: List[List[Element]] - :return: Used for chaining - :rtype: (Column) + :type rows: List[List[Element]] + :return: Used for chaining + :rtype: (Column) """ for row in rows: @@ -6608,15 +6554,14 @@ class Column(Element): self.AddRow(*row) return self - def _GetElementAtLocation(self, location): """ Not user callable. Used to find the Element at a row, col position within the layout - :param location: (row, column) position of the element to find in layout + :param location: (row, column) position of the element to find in layout :typeparam location: (int, int) - :return: The element found at the location - :rtype: (Element) + :return: The element found at the location + :rtype: (Element) """ (row_num, col_num) = location @@ -6629,9 +6574,9 @@ class Column(Element): Changes some of the settings for the Column Element. Must call `Window.Read` or `Window.Finalize` prior :param visible: control visibility of element - :type visible: (bool) + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if self.ExpandX and self.ExpandY: @@ -6656,7 +6601,6 @@ class Column(Element): if visible is not None: self._visible = visible - def contents_changed(self): """ When a scrollable column has part of its layout changed by making elements visible or invisible or the @@ -6665,8 +6609,6 @@ class Column(Element): """ self.TKColFrame.canvas.config(scrollregion=self.TKColFrame.canvas.bbox('all')) - - AddRow = add_row Layout = layout Update = update @@ -6686,34 +6628,34 @@ class Pane(Element): def __init__(self, pane_list, background_color=None, size=(None, None), s=(None, None), pad=None, orientation='vertical', show_handle=True, relief=RELIEF_RAISED, handle_size=None, border_width=None, key=None, k=None, visible=True, metadata=None): """ - :param pane_list: Must be a list of Column Elements. Each Column supplied becomes one pane that's shown - :type pane_list: List[Column] + :param pane_list: Must be a list of Column Elements. Each Column supplied becomes one pane that's shown + :type pane_list: List[Column] :param background_color: color of background - :type background_color: (str) - :param size: (width, height) w=characters-wide, h=rows-high How much room to reserve for the Pane - :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 - :type s: (int, int) | (None, None) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param orientation: 'horizontal' or 'vertical' or ('h' or 'v'). Direction the Pane should slide - :type orientation: (str) - :param show_handle: if True, the handle is drawn that makes it easier to grab and slide - :type show_handle: (bool) - :param relief: relief style. Values are same as other elements that use relief values. RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID - :type relief: (enum) - :param handle_size: Size of the handle in pixels - :type handle_size: (int) - :param border_width: width of border around element in pixels - :type border_width: (int) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type background_color: (str) + :param size: (width, height) w=characters-wide, h=rows-high How much room to reserve for the Pane + :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 + :type s: (int, int) | (None, None) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param orientation: 'horizontal' or 'vertical' or ('h' or 'v'). Direction the Pane should slide + :type orientation: (str) + :param show_handle: if True, the handle is drawn that makes it easier to grab and slide + :type show_handle: (bool) + :param relief: relief style. Values are same as other elements that use relief values. RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID + :type relief: (enum) + :param handle_size: Size of the handle in pixels + :type handle_size: (int) + :param border_width: width of border around element in pixels + :type border_width: (int) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.UseDictionary = False @@ -6745,9 +6687,9 @@ class Pane(Element): Changes some of the settings for the Pane Element. Must call `Window.Read` or `Window.Finalize` prior :param visible: control visibility of element - :type visible: (bool) + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if visible is False: @@ -7004,34 +6946,35 @@ class Menu(Element): menu is shown. The key portion is returned as part of the event. """ - def __init__(self, menu_definition, background_color=None, text_color=None, disabled_text_color=None, size=(None, None), s=(None, None), tearoff=False, font=None, pad=None, key=None, k=None, visible=True, metadata=None): + def __init__(self, menu_definition, background_color=None, text_color=None, disabled_text_color=None, size=(None, None), s=(None, None), tearoff=False, + font=None, pad=None, key=None, k=None, visible=True, metadata=None): """ - :param menu_definition: The Menu definition specified using lists (docs explain the format) - :type menu_definition: List[List[Tuple[str, List[str]]] - :param background_color: color of the background - :type background_color: (str) - :param text_color: element's text color. Can be in #RRGGBB format or a color name "black" - :type text_color: (str) + :param menu_definition: The Menu definition specified using lists (docs explain the format) + :type menu_definition: List[List[Tuple[str, List[str]]] + :param background_color: color of the background + :type background_color: (str) + :param text_color: element's text color. Can be in #RRGGBB format or a color name "black" + :type text_color: (str) :param disabled_text_color: color to use for text when item is disabled. Can be in #RRGGBB format or a color name "black" - :type disabled_text_color: (str) - :param size: Not used in the tkinter port - :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 - :type s: (int, int) | (None, None) - :param tearoff: if True, then can tear the menu off from the window ans use as a floating window. Very cool effect - :type tearoff: (bool) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type disabled_text_color: (str) + :param size: Not used in the tkinter port + :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 + :type s: (int, int) | (None, None) + :param tearoff: if True, then can tear the menu off from the window ans use as a floating window. Very cool effect + :type tearoff: (bool) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.BackgroundColor = background_color if background_color is not None else theme_input_background_color() @@ -7044,12 +6987,12 @@ class Menu(Element): key = key if key is not None else k sz = size if size != (None, None) else s - super().__init__(ELEM_TYPE_MENUBAR, background_color=self.BackgroundColor, text_color=self.TextColor, size=sz, pad=pad, key=key, visible=visible, font=font, metadata=metadata) + super().__init__(ELEM_TYPE_MENUBAR, background_color=self.BackgroundColor, text_color=self.TextColor, size=sz, pad=pad, key=key, visible=visible, + font=font, metadata=metadata) # super().__init__(ELEM_TYPE_MENUBAR, background_color=COLOR_SYSTEM_DEFAULT, text_color=COLOR_SYSTEM_DEFAULT, size=sz, pad=pad, key=key, visible=visible, font=None, metadata=metadata) self.Tearoff = tearoff - return def _MenuItemChosenCallback(self, item_chosen): # Menu Menu Item Chosen Callback @@ -7057,7 +7000,7 @@ class Menu(Element): Not user callable. Called when some end-point on the menu (an item) has been clicked. Send the information back to the application as an event. Before event can be sent :param item_chosen: the text that was clicked on / chosen from the menu - :type item_chosen: (str) + :type item_chosen: (str) """ # print('IN MENU ITEM CALLBACK', item_chosen) self.MenuItemChosen = item_chosen @@ -7072,11 +7015,11 @@ class Menu(Element): Update a menubar - can change the menu definition and visibility. The entire menu has to be specified :param menu_definition: ??? - :type menu_definition: List[List[Tuple[str, List[str]]] - :param visible: control visibility of element - :type visible: (bool) + :type menu_definition: List[List[Tuple[str, List[str]]] + :param visible: control visibility of element + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if menu_definition is not None: @@ -7126,8 +7069,6 @@ MenuBar = Menu # another name for Menu to make it clear it's the Menu Bar Menubar = Menu # another name for Menu to make it clear it's the Menu Bar - - # ---------------------------------------------------------------------- # # Table # # ---------------------------------------------------------------------- # @@ -7136,78 +7077,79 @@ 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, selected_row_colors=(None, None), header_text_color=None, header_background_color=None, header_font=None, row_colors=None, vertical_scroll_only=True, hide_vertical_scroll=False, + alternating_row_color=None, selected_row_colors=(None, None), header_text_color=None, header_background_color=None, header_font=None, + row_colors=None, vertical_scroll_only=True, hide_vertical_scroll=False, size=(None, None), s=(None, None), change_submits=False, enable_events=False, bind_return_key=False, pad=None, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, metadata=None): """ - :param values: ??? - :type values: List[List[str | int | float]] - :param headings: The headings to show on the top line - :type headings: List[str] - :param visible_column_map: One entry for each column. False indicates the column is not shown - :type visible_column_map: List[bool] - :param col_widths: Number of characters that each column will occupy - :type col_widths: List[int] - :param def_col_width: Default column width in characters - :type def_col_width: (int) - :param auto_size_columns: if True columns will be sized automatically - :type auto_size_columns: (bool) - :param max_col_width: Maximum width for all columns in characters - :type max_col_width: (int) - :param select_mode: Select Mode. Valid values start with "TABLE_SELECT_MODE_". Valid values are: TABLE_SELECT_MODE_NONE TABLE_SELECT_MODE_BROWSE TABLE_SELECT_MODE_EXTENDED - :type select_mode: (enum) - :param display_row_numbers: if True, the first column of the table will be the row # - :type display_row_numbers: (bool) - :param num_rows: The number of rows of the table to display at a time - :type num_rows: (int) - :param row_height: height of a single row in pixels - :type row_height: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param justification: 'left', 'right', 'center' are valid choices - :type justification: (str) - :param text_color: color of the text - :type text_color: (str) - :param background_color: color of background - :type background_color: (str) - :param alternating_row_color: if set then every other row will have this color in the background. - :type alternating_row_color: (str) - :param selected_row_colors: Sets the text color and background color for a selected row. Same format as button colors - tuple ('red', 'yellow') or string 'red on yellow'. Defaults to theme's button color - :type selected_row_colors: str or (str, str) - :param header_text_color: sets the text color for the header - :type header_text_color: (str) + :param values: ??? + :type values: List[List[str | int | float]] + :param headings: The headings to show on the top line + :type headings: List[str] + :param visible_column_map: One entry for each column. False indicates the column is not shown + :type visible_column_map: List[bool] + :param col_widths: Number of characters that each column will occupy + :type col_widths: List[int] + :param def_col_width: Default column width in characters + :type def_col_width: (int) + :param auto_size_columns: if True columns will be sized automatically + :type auto_size_columns: (bool) + :param max_col_width: Maximum width for all columns in characters + :type max_col_width: (int) + :param select_mode: Select Mode. Valid values start with "TABLE_SELECT_MODE_". Valid values are: TABLE_SELECT_MODE_NONE TABLE_SELECT_MODE_BROWSE TABLE_SELECT_MODE_EXTENDED + :type select_mode: (enum) + :param display_row_numbers: if True, the first column of the table will be the row # + :type display_row_numbers: (bool) + :param num_rows: The number of rows of the table to display at a time + :type num_rows: (int) + :param row_height: height of a single row in pixels + :type row_height: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param justification: 'left', 'right', 'center' are valid choices + :type justification: (str) + :param text_color: color of the text + :type text_color: (str) + :param background_color: color of background + :type background_color: (str) + :param alternating_row_color: if set then every other row will have this color in the background. + :type alternating_row_color: (str) + :param selected_row_colors: Sets the text color and background color for a selected row. Same format as button colors - tuple ('red', 'yellow') or string 'red on yellow'. Defaults to theme's button color + :type selected_row_colors: str or (str, str) + :param header_text_color: sets the text color for the header + :type header_text_color: (str) :param header_background_color: sets the background color for the header - :type header_background_color: (str) - :param header_font: specifies the font family, size, etc - :type header_font: str | Tuple[str, int] - :param row_colors: list of tuples of (row, background color) OR (row, foreground color, background color). Sets the colors of listed rows to the color(s) provided (note the optional foreground color) - :type row_colors: List[Tuple[int, str] | Tuple[Int, str, str]] - :param vertical_scroll_only: if True only the vertical scrollbar will be visible - :type vertical_scroll_only: (bool) - :param hide_vertical_scroll: if True vertical scrollbar will be hidden - :type hide_vertical_scroll: (bool) - :param size: DO NOT USE! Use num_rows instead - :type size: (int, int) - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Table events happen when row is clicked - :type enable_events: (bool) - :param bind_return_key: if True, pressing return key will cause event coming from Table, ALSO a left button double click will generate an event if this parameter is True - :type bind_return_key: (bool) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type header_background_color: (str) + :param header_font: specifies the font family, size, etc + :type header_font: str | Tuple[str, int] + :param row_colors: list of tuples of (row, background color) OR (row, foreground color, background color). Sets the colors of listed rows to the color(s) provided (note the optional foreground color) + :type row_colors: List[Tuple[int, str] | Tuple[Int, str, str]] + :param vertical_scroll_only: if True only the vertical scrollbar will be visible + :type vertical_scroll_only: (bool) + :param hide_vertical_scroll: if True vertical scrollbar will be hidden + :type hide_vertical_scroll: (bool) + :param size: DO NOT USE! Use num_rows instead + :type size: (int, int) + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Table events happen when row is clicked + :type enable_events: (bool) + :param bind_return_key: if True, pressing return key will cause event coming from Table, ALSO a left button double click will generate an event if this parameter is True + :type bind_return_key: (bool) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.Values = values @@ -7263,20 +7205,20 @@ class Table(Element): """ Changes some of the settings for the Table Element. Must call `Window.Read` or `Window.Finalize` prior - :param values: A new 2-dimensional table to show - :type values: List[List[str | int | float]] - :param num_rows: How many rows to display at a time - :type num_rows: (int) - :param visible: if True then will be visible - :type visible: (bool) - :param select_rows: List of rows to select as if user did - :type select_rows: List[int] + :param values: A new 2-dimensional table to show + :type values: List[List[str | int | float]] + :param num_rows: How many rows to display at a time + :type num_rows: (int) + :param visible: if True then will be visible + :type visible: (bool) + :param select_rows: List of rows to select as if user did + :type select_rows: List[int] :param alternating_row_color: the color to make every other row - :type alternating_row_color: (str) - :param row_colors: list of tuples of (row, background color) OR (row, foreground color, background color). Changes the colors of listed rows to the color(s) provided (note the optional foreground color) - :type row_colors: List[Tuple[int, str] | Tuple[Int, str, str]] + :type alternating_row_color: (str) + :param row_colors: list of tuples of (row, background color) OR (row, foreground color, background color). Changes the colors of listed rows to the color(s) provided (note the optional foreground color) + :type row_colors: List[Tuple[int, str] | Tuple[Int, str, str]] """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if values is not None: @@ -7341,7 +7283,7 @@ class Table(Element): Stores the selected rows in Element as they are being selected. If events enabled, then returns from Read :param event: event information from tkinter - :type event: (unknown) + :type event: (unknown) """ selections = self.TKTreeview.selection() self.SelectedRows = [int(x) - 1 for x in selections] @@ -7361,7 +7303,7 @@ class Table(Element): Stores the selected rows in Element as they are being selected. If events enabled, then returns from Read :param event: event information from tkinter - :type event: (unknown) + :type event: (unknown) """ selections = self.TKTreeview.selection() self.SelectedRows = [int(x) - 1 for x in selections] @@ -7382,7 +7324,7 @@ class Table(Element): user when Table was created or Updated. :return: the current table values (for now what was originally provided up updated) - :rtype: List[List[Any]] + :rtype: List[List[Any]] """ return self.Values @@ -7399,71 +7341,71 @@ class Tree(Element): to hold the user's data and pass to the element for display. """ - 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, selected_row_colors=(None,None), header_text_color=None, header_background_color=None, header_font=None, num_rows=None, row_height=None, pad=None, key=None, k=None, tooltip=None, + background_color=None, selected_row_colors=(None, None), header_text_color=None, header_background_color=None, header_font=None, num_rows=None, + row_height=None, pad=None, key=None, k=None, tooltip=None, right_click_menu=None, visible=True, metadata=None): """ - :param data: The data represented using a PySimpleGUI provided TreeData class - :type data: (TreeData) - :param headings: List of individual headings for each column - :type headings: List[str] - :param visible_column_map: Determines if a column should be visible. If left empty, all columns will be shown - :type visible_column_map: List[bool] - :param col_widths: List of column widths so that individual column widths can be controlled - :type col_widths: List[int] - :param col0_width: Size of Column 0 which is where the row numbers will be optionally shown - :type col0_width: (int) - :param def_col_width: default column width - :type def_col_width: (int) - :param auto_size_columns: if True, the size of a column is determined using the contents of the column - :type auto_size_columns: (bool) - :param max_col_width: the maximum size a column can be - :type max_col_width: (int) - :param select_mode: Use same values as found on Table Element. Valid values include: TABLE_SELECT_MODE_NONE TABLE_SELECT_MODE_BROWSE TABLE_SELECT_MODE_EXTENDED - :type select_mode: (enum) - :param show_expanded: if True then the tree will be initially shown with all nodes completely expanded - :type show_expanded: (bool) - :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead - :type change_submits: (bool) - :param enable_events: Turns on the element specific events. Tree events happen when row is clicked - :type enable_events: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param justification: 'left', 'right', 'center' are valid choices - :type justification: (str) - :param text_color: color of the text - :type text_color: (str) - :param background_color: color of background - :type background_color: (str) - :param selected_row_colors: Sets the text color and background color for a selected row. Same format as button colors - tuple ('red', 'yellow') or string 'red on yellow'. Defaults to theme's button color - :type selected_row_colors: str or (str, str) - :param header_text_color: sets the text color for the header - :type header_text_color: (str) + :param data: The data represented using a PySimpleGUI provided TreeData class + :type data: (TreeData) + :param headings: List of individual headings for each column + :type headings: List[str] + :param visible_column_map: Determines if a column should be visible. If left empty, all columns will be shown + :type visible_column_map: List[bool] + :param col_widths: List of column widths so that individual column widths can be controlled + :type col_widths: List[int] + :param col0_width: Size of Column 0 which is where the row numbers will be optionally shown + :type col0_width: (int) + :param def_col_width: default column width + :type def_col_width: (int) + :param auto_size_columns: if True, the size of a column is determined using the contents of the column + :type auto_size_columns: (bool) + :param max_col_width: the maximum size a column can be + :type max_col_width: (int) + :param select_mode: Use same values as found on Table Element. Valid values include: TABLE_SELECT_MODE_NONE TABLE_SELECT_MODE_BROWSE TABLE_SELECT_MODE_EXTENDED + :type select_mode: (enum) + :param show_expanded: if True then the tree will be initially shown with all nodes completely expanded + :type show_expanded: (bool) + :param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead + :type change_submits: (bool) + :param enable_events: Turns on the element specific events. Tree events happen when row is clicked + :type enable_events: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param justification: 'left', 'right', 'center' are valid choices + :type justification: (str) + :param text_color: color of the text + :type text_color: (str) + :param background_color: color of background + :type background_color: (str) + :param selected_row_colors: Sets the text color and background color for a selected row. Same format as button colors - tuple ('red', 'yellow') or string 'red on yellow'. Defaults to theme's button color + :type selected_row_colors: str or (str, str) + :param header_text_color: sets the text color for the header + :type header_text_color: (str) :param header_background_color: sets the background color for the header - :type header_background_color: (str) - :param header_font: specifies the font family, size, etc - :type header_font: str | Tuple[str, int] - :param num_rows: The number of rows of the table to display at a time - :type num_rows: (int) - :param row_height: height of a single row in pixels - :type row_height: (int) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[str] | str]] - :param visible: set visibility state of the element - :type visible: (bool) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type header_background_color: (str) + :param header_font: specifies the font family, size, etc + :type header_font: str | Tuple[str, int] + :param num_rows: The number of rows of the table to display at a time + :type num_rows: (int) + :param row_height: height of a single row in pixels + :type row_height: (int) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[str] | str]] + :param visible: set visibility state of the element + :type visible: (bool) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self.image_dict = {} @@ -7498,8 +7440,8 @@ class Tree(Element): self.ShowExpanded = show_expanded self.NumRows = num_rows self.Col0Width = col0_width - self.TKTreeview = None # type: ttk.Treeview - self.element_frame = None # type: tk.Frame + self.TKTreeview = None # type: ttk.Treeview + self.element_frame = None # type: tk.Frame self.SelectedRows = [] self.ChangeSubmits = change_submits or enable_events self.RightClickMenu = right_click_menu @@ -7509,7 +7451,8 @@ class Tree(Element): self.KeyToID = {'': ''} key = key if key is not None else k - super().__init__(ELEM_TYPE_TREE, text_color=text_color, background_color=background_color, font=font, pad=pad, key=key, tooltip=tooltip, visible=visible, metadata=metadata) + super().__init__(ELEM_TYPE_TREE, text_color=text_color, background_color=background_color, font=font, pad=pad, key=key, tooltip=tooltip, + visible=visible, metadata=metadata) return def _treeview_selected(self, event): @@ -7518,7 +7461,7 @@ class Tree(Element): method, it saves away the reported selections so they can be properly returned. :param event: An event parameter passed in by tkinter. Not used - :type event: (Any) + :type event: (Any) """ selections = self.TKTreeview.selection() @@ -7540,7 +7483,7 @@ class Tree(Element): Not a user function. Recursive method that inserts tree data into the tkinter treeview widget. :param node: The node to insert. Will insert all nodes from starting point downward, recursively - :type node: (TreeData) + :type node: (TreeData) """ if node.key != '': if node.icon: @@ -7574,20 +7517,20 @@ class Tree(Element): """ Changes some of the settings for the Tree Element. Must call `Window.Read` or `Window.Finalize` prior - :param values: Representation of the tree - :type values: (TreeData) - :param key: identifies a particular item in tree to update - :type key: str | int | tuple | object - :param value: sets the node identified by key to a particular value - :type value: (Any) - :param text: sets the node identified by ket to this string - :type text: (str) - :param icon: can be either a base64 icon or a filename for the icon - :type icon: bytes | str + :param values: Representation of the tree + :type values: (TreeData) + :param key: identifies a particular item in tree to update + :type key: str | int | tuple | object + :param value: sets the node identified by key to a particular value + :type value: (Any) + :param text: sets the node identified by ket to this string + :type text: (str) + :param icon: can be either a base64 icon or a filename for the icon + :type icon: bytes | str :param visible: control visibility of element - :type visible: (bool) + :type visible: (bool) """ - if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow + if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow return if values is not None: @@ -7656,15 +7599,15 @@ class TreeData(object): Represents a node within the TreeData class :param parent: The parent Node - :type parent: (TreeData.Node) - :param key: Used to uniquely identify this node - :type key: str | int | tuple | object - :param text: The text that is displayed at this node's location - :type text: (str) + :type parent: (TreeData.Node) + :param key: Used to uniquely identify this node + :type key: str | int | tuple | object + :param text: The text that is displayed at this node's location + :type text: (str) :param values: The list of values that are displayed at this node - :type values: List[Any] - :param icon: just a icon - :type icon: str | bytes + :type values: List[Any] + :param icon: just a icon + :type icon: str | bytes """ self.parent = parent # type: TreeData.Node @@ -7689,10 +7632,10 @@ class TreeData(object): """ Adds a node to tree dictionary (not user callable) - :param key: Uniquely identifies this Node - :type key: (str) + :param key: Uniquely identifies this Node + :type key: (str) :param node: Node being added - :type node: (TreeData.Node) + :type node: (TreeData.Node) """ self.tree_dict[key] = node @@ -7702,15 +7645,15 @@ class TreeData(object): This is the ONLY user callable method in the TreeData class :param parent: the parent Node - :type parent: (Node) - :param key: Used to uniquely identify this node - :type key: str | int | tuple | object - :param text: The text that is displayed at this node's location - :type text: (str) + :type parent: (Node) + :param key: Used to uniquely identify this node + :type key: str | int | tuple | object + :param text: The text that is displayed at this node's location + :type text: (str) :param values: The list of values that are displayed at this node - :type values: List[Any] - :param icon: icon - :type icon: str | bytes + :type values: List[Any] + :param icon: icon + :type icon: str | bytes """ node = self.Node(parent, key, text, values, icon) @@ -7731,9 +7674,9 @@ class TreeData(object): Does the magic of converting the TreeData into a nicely formatted string version :param node: The node to begin printing the tree - :type node: (TreeData.Node) + :type node: (TreeData.Node) :param level: The indentation level for string formatting - :type level: (int) + :type level: (int) """ return '\n'.join( [str(node.key) + ' : ' + str(node.text)] + @@ -7752,7 +7695,7 @@ class ErrorElement(Element): def __init__(self, key=None, metadata=None): """ - :param key: Used with window.find_element and with return values to uniquely identify this element + :param key: Used with window.find_element and with return values to uniquely identify this element """ self.Key = key @@ -7763,13 +7706,13 @@ class ErrorElement(Element): Update method for the Error Element, an element that should not be directly used by developer :param silent_on_error: if False, then a Popup window will be shown - :type silent_on_error: (bool) - :param *args: meant to "soak up" any normal parameters passed in - :type *args: (Any) - :param **kwargs: meant to "soak up" any keyword parameters that were passed in - :type **kwargs: (Any) - :return: returns 'self' so call can be chained - :rtype: (ErrorElement) + :type silent_on_error: (bool) + :param *args: meant to "soak up" any normal parameters passed in + :type *args: (Any) + :param **kwargs: meant to "soak up" any keyword parameters that were passed in + :type **kwargs: (Any) + :return: returns 'self' so call can be chained + :rtype: (ErrorElement) """ print('** Your update is being ignored because you supplied a bad key earlier **') return self @@ -7778,8 +7721,8 @@ class ErrorElement(Element): """ One of the method names found in other Elements. Used here to return an error string in case it's called - :return: A warning text string. - :rtype: (str) + :return: A warning text string. + :rtype: (str) """ return 'This is NOT a valid Element!\nSTOP trying to do things with it or I will have to crash at some point!' @@ -7803,19 +7746,18 @@ class Window: """ NumOpenWindows = 0 _user_defined_icon = None - hidden_master_root = None # type: tk.Tk - _animated_popup_dict = {} # type: Dict - _active_windows = {} # type: Dict[Window, tk.Tk()] - _move_all_windows = False # if one window moved, they will move - _window_that_exited = None # type: Window - _root_running_mainloop = None # type: tk.Tk() # (may be the hidden root or a window's root) + hidden_master_root = None # type: tk.Tk + _animated_popup_dict = {} # type: Dict + _active_windows = {} # type: Dict[Window, tk.Tk()] + _move_all_windows = False # if one window moved, they will move + _window_that_exited = None # type: Window + _root_running_mainloop = None # type: tk.Tk() # (may be the hidden root or a window's root) _timeout_key = None - _TKAfterID = None # timer that is used to run reads with timeouts - _window_running_mainloop = None # The window that is running the mainloop + _TKAfterID = None # timer that is used to run reads with timeouts + _window_running_mainloop = None # The window that is running the mainloop _container_element_counter = 0 # used to get a number of Container Elements (Frame, Column, Tab) _read_call_from_debugger = False - _timeout_0_counter = 0 # when timeout=0 then go through each window one at a time - + _timeout_0_counter = 0 # when timeout=0 then go through each window one at a time def __init__(self, title, layout=None, default_element_size=DEFAULT_ELEMENT_SIZE, default_button_element_size=(None, None), @@ -7826,114 +7768,115 @@ class Window: alpha_channel=1, return_keyboard_events=False, use_default_focus=True, text_justification=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, resizable=False, disable_close=False, disable_minimize=False, right_click_menu=None, transparent_color=None, debugger_enabled=True, - right_click_menu_background_color=None, right_click_menu_text_color=None, right_click_menu_disabled_text_color=None, right_click_menu_selected_colors=(None, None), + right_click_menu_background_color=None, right_click_menu_text_color=None, right_click_menu_disabled_text_color=None, + right_click_menu_selected_colors=(None, None), right_click_menu_font=None, right_click_menu_tearoff=False, finalize=False, element_justification='left', ttk_theme=None, use_ttk_buttons=None, modal=False, enable_close_attempted_event=False, titlebar_background_color=None, titlebar_text_color=None, titlebar_font=None, titlebar_icon=None, use_custom_titlebar=None, metadata=None): """ - :param title: The title that will be displayed in the Titlebar and on the Taskbar - :type title: (str) - :param layout: The layout for the window. Can also be specified in the Layout method - :type layout: List[List[Elements]] - :param default_element_size: size in characters (wide) and rows (high) for all elements in this window - :type default_element_size: (int, int) - (width, height) - :param default_button_element_size: (width, height) size in characters (wide) and rows (high) for all Button elements in this window - :type default_button_element_size: (int, int) - :param auto_size_text: True if Elements in Window should be sized to exactly fir the length of text - :type auto_size_text: (bool) - :param auto_size_buttons: True if Buttons in this Window should be sized to exactly fit the text on this. - :type auto_size_buttons: (bool) - :param location: (x,y) location, in pixels, to locate the upper left corner of the window on the screen. Default is to center on screen. - :type location: (int, int) - :param size: (width, height) size in pixels for this window. Normally the window is autosized to fit contents, not set to an absolute size by the user - :type size: (int, int) - :param element_padding: Default amount of padding to put around elements in window (left/right, top/bottom) or ((left, right), (top, bottom)) - :type element_padding: (int, int) or ((int, int),(int,int)) - :param margins: (left/right, top/bottom) Amount of pixels to leave inside the window's frame around the edges before your elements are shown. - :type margins: (int, int) - :param button_color: Default button colors for all buttons in the window - :type button_color: (str, str) or str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] | None - :param progress_bar_color: (bar color, background color) Sets the default colors for all progress bars in the window - :type progress_bar_color: (str, str) - :param background_color: color of background - :type background_color: (str) - :param border_depth: Default border depth (width) for all elements in the window - :type border_depth: (int) - :param auto_close: If True, the window will automatically close itself - :type auto_close: (bool) - :param auto_close_duration: Number of seconds to wait before closing the window - :type auto_close_duration: (int) - :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO. Most portable is to use a Base64 of a GIF file. This works universally across all OS's - :type icon: (str | bytes) - :param force_toplevel: If True will cause this window to skip the normal use of a hidden master window - :type force_toplevel: (bool) - :param alpha_channel: Sets the opacity of the window. 0 = invisible 1 = completely visible. Values bewteen 0 & 1 will produce semi-transparent windows in SOME environments (The Raspberry Pi always has this value at 1 and cannot change. - :type alpha_channel: (float) - :param return_keyboard_events: if True key presses on the keyboard will be returned as Events from Read calls - :type return_keyboard_events: (bool) - :param use_default_focus: If True will use the default focus algorithm to set the focus to the "Correct" element - :type use_default_focus: (bool) - :param text_justification: Default text justification for all Text Elements in window - :type text_justification: 'left' | 'right' | 'center' - :param no_titlebar: If true, no titlebar nor frame will be shown on window. This means you cannot minimize the window and it will not show up on the taskbar - :type no_titlebar: (bool) - :param grab_anywhere: If True can use mouse to click and drag to move the window. Almost every location of the window will work except input fields on some systems - :type grab_anywhere: (bool) - :param keep_on_top: If True, window will be created on top of all other windows on screen. It can be bumped down if another window created with this parm - :type keep_on_top: (bool) - :param resizable: If True, allows the user to resize the window. Note the not all Elements will change size or location when resizing. - :type resizable: (bool) - :param disable_close: If True, the X button in the top right corner of the window will no work. Use with caution and always give a way out toyour users - :type disable_close: (bool) - :param disable_minimize: if True the user won't be able to minimize window. Good for taking over entire screen and staying that way. - :type disable_minimize: (bool) - :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. - :type right_click_menu: List[List[ List[str] | str ]] - :param transparent_color: Any portion of the window that has this color will be completely transparent. You can even click through these spots to the window under this window. - :type transparent_color: (str) - :param debugger_enabled: If True then the internal debugger will be enabled - :type debugger_enabled: (bool) - :param right_click_menu_background_color: Background color for right click menus - :type right_click_menu_background_color: (str) - :param right_click_menu_text_color: Text color for right click menus - :type right_click_menu_text_color: (str) + :param title: The title that will be displayed in the Titlebar and on the Taskbar + :type title: (str) + :param layout: The layout for the window. Can also be specified in the Layout method + :type layout: List[List[Elements]] + :param default_element_size: size in characters (wide) and rows (high) for all elements in this window + :type default_element_size: (int, int) - (width, height) + :param default_button_element_size: (width, height) size in characters (wide) and rows (high) for all Button elements in this window + :type default_button_element_size: (int, int) + :param auto_size_text: True if Elements in Window should be sized to exactly fir the length of text + :type auto_size_text: (bool) + :param auto_size_buttons: True if Buttons in this Window should be sized to exactly fit the text on this. + :type auto_size_buttons: (bool) + :param location: (x,y) location, in pixels, to locate the upper left corner of the window on the screen. Default is to center on screen. + :type location: (int, int) + :param size: (width, height) size in pixels for this window. Normally the window is autosized to fit contents, not set to an absolute size by the user + :type size: (int, int) + :param element_padding: Default amount of padding to put around elements in window (left/right, top/bottom) or ((left, right), (top, bottom)) + :type element_padding: (int, int) or ((int, int),(int,int)) + :param margins: (left/right, top/bottom) Amount of pixels to leave inside the window's frame around the edges before your elements are shown. + :type margins: (int, int) + :param button_color: Default button colors for all buttons in the window + :type button_color: (str, str) or str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] | None + :param progress_bar_color: (bar color, background color) Sets the default colors for all progress bars in the window + :type progress_bar_color: (str, str) + :param background_color: color of background + :type background_color: (str) + :param border_depth: Default border depth (width) for all elements in the window + :type border_depth: (int) + :param auto_close: If True, the window will automatically close itself + :type auto_close: (bool) + :param auto_close_duration: Number of seconds to wait before closing the window + :type auto_close_duration: (int) + :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO. Most portable is to use a Base64 of a GIF file. This works universally across all OS's + :type icon: (str | bytes) + :param force_toplevel: If True will cause this window to skip the normal use of a hidden master window + :type force_toplevel: (bool) + :param alpha_channel: Sets the opacity of the window. 0 = invisible 1 = completely visible. Values bewteen 0 & 1 will produce semi-transparent windows in SOME environments (The Raspberry Pi always has this value at 1 and cannot change. + :type alpha_channel: (float) + :param return_keyboard_events: if True key presses on the keyboard will be returned as Events from Read calls + :type return_keyboard_events: (bool) + :param use_default_focus: If True will use the default focus algorithm to set the focus to the "Correct" element + :type use_default_focus: (bool) + :param text_justification: Default text justification for all Text Elements in window + :type text_justification: 'left' | 'right' | 'center' + :param no_titlebar: If true, no titlebar nor frame will be shown on window. This means you cannot minimize the window and it will not show up on the taskbar + :type no_titlebar: (bool) + :param grab_anywhere: If True can use mouse to click and drag to move the window. Almost every location of the window will work except input fields on some systems + :type grab_anywhere: (bool) + :param keep_on_top: If True, window will be created on top of all other windows on screen. It can be bumped down if another window created with this parm + :type keep_on_top: (bool) + :param resizable: If True, allows the user to resize the window. Note the not all Elements will change size or location when resizing. + :type resizable: (bool) + :param disable_close: If True, the X button in the top right corner of the window will no work. Use with caution and always give a way out toyour users + :type disable_close: (bool) + :param disable_minimize: if True the user won't be able to minimize window. Good for taking over entire screen and staying that way. + :type disable_minimize: (bool) + :param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. + :type right_click_menu: List[List[ List[str] | str ]] + :param transparent_color: Any portion of the window that has this color will be completely transparent. You can even click through these spots to the window under this window. + :type transparent_color: (str) + :param debugger_enabled: If True then the internal debugger will be enabled + :type debugger_enabled: (bool) + :param right_click_menu_background_color: Background color for right click menus + :type right_click_menu_background_color: (str) + :param right_click_menu_text_color: Text color for right click menus + :type right_click_menu_text_color: (str) :param right_click_menu_disabled_text_color: Text color for disabled right click menu items - :type right_click_menu_disabled_text_color: (str) - :param right_click_menu_selected_colors: Text AND background colors for a selected item. Can be a Tuple OR a color string. simplified-button-color-string "foreground on background". Can be a single color if want to set only the background. + :type right_click_menu_disabled_text_color: (str) + :param right_click_menu_selected_colors: Text AND background colors for a selected item. Can be a Tuple OR a color string. simplified-button-color-string "foreground on background". Can be a single color if want to set only the background. Normally a tuple, but can be a simplified-dual-color-string "foreground on background". Can be a single color if want to set only the background. - :type right_click_menu_selected_colors: (str, str) | str | Tuple(int, int) | (None, None) + :type right_click_menu_selected_colors: (str, str) | str | Tuple(int, int) | (None, None) :type right_click_menu_disabled_text_color: (str) - :param right_click_menu_font: Font for right click menus - :type right_click_menu_font: str | Tuple[str, int] - :param right_click_menu_tearoff: If True then all right click menus can be torn off - :type right_click_menu_tearoff: bool - :param finalize: If True then the Finalize method will be called. Use this rather than chaining .Finalize for cleaner code - :type finalize: (bool) - :param element_justification: All elements in the Window itself will have this justification 'left', 'right', 'center' are valid values - :type element_justification: (str) - :param ttk_theme: Set the tkinter ttk "theme" of the window. Default = DEFAULT_TTK_THEME. Sets all ttk widgets to this theme as their default - :type ttk_theme: (str) - :param use_ttk_buttons: Affects all buttons in window. True = use ttk buttons. False = do not use ttk buttons. None = use ttk buttons only if on a Mac - :type use_ttk_buttons: (bool) - :param modal: If True then this window will be the only window a user can interact with until it is closed - :type modal: (bool) - :param enable_close_attempted_event: If True then the window will not close when "X" clicked. Instead an event WINDOW_CLOSE_ATTEMPTED_EVENT if returned from window.read - :type enable_close_attempted_event: (bool) - :param titlebar_background_color: If custom titlebar indicated by use_custom_titlebar, then use this as background color - :type titlebar_background_color: (str | None) - :param titlebar_text_color: If custom titlebar indicated by use_custom_titlebar, then use this as text color - :type titlebar_text_color: (str | None) - :param titlebar_font: If custom titlebar indicated by use_custom_titlebar, then use this as title font - :type titlebar_font: (str | Tuple[str, int] | None) - :param titlebar_icon: If custom titlebar indicated by use_custom_titlebar, then use this as the icon (file or base64 bytes) - :type titlebar_icon: (bytes | str) - :param use_custom_titlebar: If True, then a custom titlebar will be used instead of the normal titlebar - :type use_custom_titlebar: bool - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :param right_click_menu_font: Font for right click menus + :type right_click_menu_font: str | Tuple[str, int] + :param right_click_menu_tearoff: If True then all right click menus can be torn off + :type right_click_menu_tearoff: bool + :param finalize: If True then the Finalize method will be called. Use this rather than chaining .Finalize for cleaner code + :type finalize: (bool) + :param element_justification: All elements in the Window itself will have this justification 'left', 'right', 'center' are valid values + :type element_justification: (str) + :param ttk_theme: Set the tkinter ttk "theme" of the window. Default = DEFAULT_TTK_THEME. Sets all ttk widgets to this theme as their default + :type ttk_theme: (str) + :param use_ttk_buttons: Affects all buttons in window. True = use ttk buttons. False = do not use ttk buttons. None = use ttk buttons only if on a Mac + :type use_ttk_buttons: (bool) + :param modal: If True then this window will be the only window a user can interact with until it is closed + :type modal: (bool) + :param enable_close_attempted_event: If True then the window will not close when "X" clicked. Instead an event WINDOW_CLOSE_ATTEMPTED_EVENT if returned from window.read + :type enable_close_attempted_event: (bool) + :param titlebar_background_color: If custom titlebar indicated by use_custom_titlebar, then use this as background color + :type titlebar_background_color: (str | None) + :param titlebar_text_color: If custom titlebar indicated by use_custom_titlebar, then use this as text color + :type titlebar_text_color: (str | None) + :param titlebar_font: If custom titlebar indicated by use_custom_titlebar, then use this as title font + :type titlebar_font: (str | Tuple[str, int] | None) + :param titlebar_icon: If custom titlebar indicated by use_custom_titlebar, then use this as the icon (file or base64 bytes) + :type titlebar_icon: (bytes | str) + :param use_custom_titlebar: If True, then a custom titlebar will be used instead of the normal titlebar + :type use_custom_titlebar: bool + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self._metadata = None # type: Any @@ -8010,10 +7953,10 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.user_bind_dict = {} # Used when user defines a tkinter binding using bind method - convert bind string to key modifier self.user_bind_event = None # Used when user defines a tkinter binding using bind method - event data from tkinter self.modal = modal - self.thread_queue = None # type: queue.Queue - self.thread_lock = None # type: threading.Lock - self.thread_timer = None # type: tk.Misc - self.thread_strvar = None # type: tk.StringVar + self.thread_queue = None # type: queue.Queue + self.thread_lock = None # type: threading.Lock + self.thread_timer = None # type: tk.Misc + self.thread_strvar = None # type: tk.StringVar self.read_closed_window_count = 0 self.config_last_size = (None, None) self.config_last_location = (None, None) @@ -8035,14 +7978,15 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.titlebar_background_color = titlebar_background_color self.titlebar_text_color = titlebar_text_color self.titlebar_font = titlebar_font - self.titlebar_icon= titlebar_icon - self.right_click_menu_selected_colors = _simplified_dual_color_to_tuple(right_click_menu_selected_colors, (self.right_click_menu_background_color, self.right_click_menu_text_color)) + self.titlebar_icon = titlebar_icon + self.right_click_menu_selected_colors = _simplified_dual_color_to_tuple(right_click_menu_selected_colors, + (self.right_click_menu_background_color, self.right_click_menu_text_color)) self._grab_anywhere_ignore_these_list = [] self._grab_anywhere_include_these_list = [] self._has_custom_titlebar = use_custom_titlebar if self.use_custom_titlebar: - self.Margins = (0,0) + self.Margins = (0, 0) self.NoTitleBar = True if no_titlebar is True: @@ -8094,7 +8038,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Returns the size of the "screen" as determined by tkinter. This can vary depending on your operating system and the number of monitors installed on your system. For Windows, the primary monitor's size is returns. On some multi-monitored Linux systems, the monitors are combined and the total size is reported as if one screen. :return: Size of the screen in pixels as determined by tkinter - :rtype: (int, int) + :rtype: (int, int) """ root = tk.Tk() screen_width = root.winfo_screenwidth() # get window info to move to middle of screen @@ -8107,21 +8051,19 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ Metadata is available for all windows. You can set to any value. :return: the current metadata value - :rtype: (Any) + :rtype: (Any) """ return self._metadata - @metadata.setter def metadata(self, value): """ Metadata is available for all windows. You can set to any value. :param value: Anything you want it to be - :type value: (Any) + :type value: (Any) """ self._metadata = value - # ------------------------- Add ONE Row to Form ------------------------- # def add_row(self, *args): """ @@ -8141,38 +8083,40 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.add_row(*element) continue _error_popup_with_traceback('Error creating Window layout', - 'Layout has a LIST instead of an ELEMENT', - 'This means you have a badly placed ]', - 'The offensive list is:', - element, - 'This list will be stripped from your layout' - ) + 'Layout has a LIST instead of an ELEMENT', + 'This means you have a badly placed ]', + 'The offensive list is:', + element, + 'This list will be stripped from your layout' + ) continue elif callable(element) and not isinstance(element, Element): _error_popup_with_traceback('Error creating Window layout', - 'Layout has a FUNCTION instead of an ELEMENT', - 'This likely means you are missing () from your layout', - 'The offensive list is:', - element, - 'This item will be stripped from your layout') + 'Layout has a FUNCTION instead of an ELEMENT', + 'This likely means you are missing () from your layout', + 'The offensive list is:', + element, + 'This item will be stripped from your layout') continue if element.ParentContainer is not None: - warnings.warn('*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', UserWarning) + warnings.warn( + '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***', + UserWarning) _error_popup_with_traceback('Error creating Window layout', - 'The layout specified has already been used', - 'You MUST start witha "clean", unused layout every time you create a window', - 'The offensive Element = ', - element, - 'and has a key = ', element.Key, - 'This item will be stripped from your layout', - 'Hint - try printing your layout and matching the IDs "print(layout)"') + 'The layout specified has already been used', + 'You MUST start witha "clean", unused layout every time you create a window', + 'The offensive Element = ', + element, + 'and has a key = ', element.Key, + 'This item will be stripped from your layout', + 'Hint - try printing your layout and matching the IDs "print(layout)"') continue element.Position = (CurrentRowNumber, i) element.ParentContainer = self CurrentRow.append(element) # if this element is a titlebar, then automatically set the window margins to (0,0) and turn off normal titlebar if element.metadata == TITLEBAR_METADATA_MARKER: - self.Margins = (0,0) + self.Margins = (0, 0) self.NoTitleBar = True # ------------------------- Append the row to list of Rows ------------------------- # self.Rows.append(CurrentRow) @@ -8185,7 +8129,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg it as a parameter to the Window call is better. :param rows: A list of a list of elements - :type rows: List[List[Elements]] + :type rows: List[List[Elements]] """ for row in rows: try: @@ -8200,7 +8144,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg continue self.AddRow(*row) - def layout(self, rows): """ Second of two preferred ways of telling a Window what its layout is. The other way is to pass the layout as @@ -8209,9 +8152,9 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg from history and replace with sending as a parameter to Window. :param rows: Your entire layout - :type rows: List[List[Elements]] - :return: self so that you can chain method calls - :rtype: (Window) + :type rows: List[List[Elements]] + :return: self so that you can chain method calls + :rtype: (Window) """ if self.use_custom_titlebar and not self.override_custom_titlebar: if self.titlebar_icon is not None: @@ -8225,32 +8168,32 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg else: icon = None - new_rows = [[Titlebar(title=self.Title, icon=icon, text_color=self.titlebar_text_color, background_color=self.titlebar_background_color, font=self.titlebar_font)]] + rows + new_rows = [[Titlebar(title=self.Title, icon=icon, text_color=self.titlebar_text_color, background_color=self.titlebar_background_color, + font=self.titlebar_font)]] + rows else: new_rows = rows self.AddRows(new_rows) self._BuildKeyDict() if self._has_custom_titlebar_element(): - self.Margins = (0,0) + self.Margins = (0, 0) self.NoTitleBar = True self._has_custom_titlebar = True return self - - def extend_layout(self, container, rows): + def extend_layout(self, container, rows): """ Adds new rows to an existing container element inside of this window If the container is a scrollable Column, you need to also call the contents_changed() method :param container: The container Element the layout will be placed inside of - :type container: Frame | Column | Tab - :param rows: The layout to be added - :type rows: (List[List[Element]]) - :return: (Window) self so could be chained - :rtype: (Window) + :type container: Frame | Column | Tab + :param rows: The layout to be added + :type rows: (List[List[Element]]) + :return: (Window) self so could be chained + :rtype: (Window) """ - column = Column(rows, pad=(0,0)) + column = Column(rows, pad=(0, 0)) if self == container: frame = self.TKroot elif isinstance(container.Widget, TkScrollableFrame): @@ -8263,15 +8206,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.AllKeysDict = self._BuildKeyDictForWindow(self, column, self.AllKeysDict) return self - def LayoutAndRead(self, rows, non_blocking=False): """ Deprecated!! Now your layout your window's rows (layout) and then separately call Read. - :param rows: The layout of the window - :type rows: List[List[Element]] - :param non_blocking: if True the Read call will not block - :type non_blocking: (bool) + :param rows: The layout of the window + :type rows: List[List[Element]] + :param non_blocking: if True the Read call will not block + :type non_blocking: (bool) """ raise DeprecationWarning( 'LayoutAndRead is no longer supported... change your call window.Layout(layout).Read()\nor window(title, layout).Read()') @@ -8291,8 +8233,8 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg It's this method that first shows the window to the user, collects results :param non_blocking: if True, this is a non-blocking call - :type non_blocking: (bool) - :return: Tuple[Any, Dict] The event, values turple that is returned from Read calls + :type non_blocking: (bool) + :return: Tuple[Any, Dict] The event, values turple that is returned from Read calls """ self.Shown = True # Compute num rows & num cols (it'll come in handy debugging) @@ -8337,10 +8279,10 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg * bytes object * BASE64 encoded file held in a variable - :param icon: Filename or bytes object - :type icon: (str) + :param icon: Filename or bytes object + :type icon: (str) :param pngbase64: Base64 encoded image - :type pngbase64: (str) + :type pngbase64: (str) """ if type(icon) is bytes or pngbase64 is not None: wicon = tkinter.PhotoImage(data=icon if icon is not None else pngbase64) @@ -8373,14 +8315,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg pass self.WindowIcon = wicon - - def _GetElementAtLocation(self, location): """ Given a (row, col) location in a layout, return the element located at that position :param location: (int, int) Return the element located at (row, col) in layout - :return: (Element) The Element located at that position in this window + :return: (Element) The Element located at that position in this window """ (row_num, col_num) = location @@ -8392,8 +8332,8 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ Returns the default elementSize - :return: (width, height) of the default element size - :rtype: (int, int) + :return: (width, height) of the default element size + :rtype: (int, int) """ return self.DefaultElementSize @@ -8429,7 +8369,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.FormRemainedOpen = True self.TKroot.quit() # kick the users out of the mainloop - def _calendar_chooser_button_clicked(self, elem): """ @@ -8472,7 +8411,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg should_submit_window = False return should_submit_window - # @_timeit_summary def read(self, timeout=None, timeout_key=TIMEOUT_KEY, close=False): """ @@ -8480,14 +8418,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Pass in a timeout (in milliseconds) to wait for a maximum of timeout milliseconds. Will return timeout_key if no other GUI events happen first. - :param timeout: Milliseconds to wait until the Read will return IF no other GUI events happen first - :type timeout: (int) + :param timeout: Milliseconds to wait until the Read will return IF no other GUI events happen first + :type timeout: (int) :param timeout_key: The value that will be returned from the call if the timer expired - :type timeout_key: (Any) - :param close: if True the window will be closed prior to returning - :type close: (bool) - :return: (event, values) - :rtype: Tuple[(Any), Dict[Any, Any], List[Any], None] + :type timeout_key: (Any) + :param close: if True the window will be closed prior to returning + :type close: (bool) + :return: (event, values) + :rtype: Tuple[(Any), Dict[Any, Any], List[Any], None] """ # ensure called only 1 time through a single read cycle if not Window._read_call_from_debugger: @@ -8499,12 +8437,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg results = self._read(timeout=timeout, timeout_key=timeout_key) # Post processing for Calendar Chooser Button try: - if results[0] == timeout_key: # if a timeout, then not a calendar button + if results[0] == timeout_key: # if a timeout, then not a calendar button break - elem = self.find_element(results[0], silent_on_error=True) # get the element that caused the event + elem = self.find_element(results[0], silent_on_error=True) # get the element that caused the event if elem.Type == ELEM_TYPE_BUTTON: if elem.BType == BUTTON_TYPE_CALENDAR_CHOOSER: - if self._calendar_chooser_button_clicked(elem): # returns True if should break out + if self._calendar_chooser_button_clicked(elem): # returns True if should break out # results[0] = self.LastButtonClicked results = self.ReturnValues break @@ -8512,14 +8450,13 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg continue break except: - break # wasn't a calendar button for sure + break # wasn't a calendar button for sure if close: self.close() return results - # @_timeit def _read(self, timeout=None, timeout_key=TIMEOUT_KEY): """ @@ -8527,12 +8464,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Pass in a timeout (in milliseconds) to wait for a maximum of timeout milliseconds. Will return timeout_key if no other GUI events happen first. - :param timeout: Milliseconds to wait until the Read will return IF no other GUI events happen first - :type timeout: (int) + :param timeout: Milliseconds to wait until the Read will return IF no other GUI events happen first + :type timeout: (int) :param timeout_key: The value that will be returned from the call if the timer expired - :type timeout_key: (Any) - :return: (event, values) (event or timeout_key or None, Dictionary of values or List of values from all elements in the Window) - :rtype: Tuple[(Any), Dict[Any, Any], List[Any], None] + :type timeout_key: (Any) + :return: (event, values) (event or timeout_key or None, Dictionary of values or List of values from all elements in the Window) + :rtype: Tuple[(Any), Dict[Any, Any], List[Any], None] """ # if there are events in the thread event queue, then return those events before doing anything else. @@ -8559,7 +8496,8 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg if self.TKrootDestroyed: self.read_closed_window_count += 1 if self.read_closed_window_count > 100: - popup_error('You have tried 100 times to read a closed window.', 'You need to add a check for event == WIN_CLOSED', title='Trying to read a closed window') + popup_error('You have tried 100 times to read a closed window.', 'You need to add a check for event == WIN_CLOSED', + title='Trying to read a closed window') return None, None if not self.Shown: self._Show() @@ -8582,7 +8520,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg if self.AllKeysDict.get(self.LastButtonClicked, None): if self.AllKeysDict.get(self.LastButtonClicked).Type != ELEM_TYPE_BUTTON: self.LastButtonClickedWasRealtime = False # stops from generating events until something changes - else: # it is possible for the key to not be in the dicitonary because it has a modifier. If so, then clear the realtime button flag + else: # it is possible for the key to not be in the dicitonary because it has a modifier. If so, then clear the realtime button flag self.LastButtonClickedWasRealtime = False # stops from generating events until something changes try: @@ -8655,7 +8593,8 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg if self._queued_thread_event_available(): self.ReturnValues = results = _BuildResults(self, False, self) return results - if not self.XFound and self.Timeout != 0 and self.Timeout is not None and self.ReturnValues[0] is None: # Special Qt case because returning for no reason so fake timeout + if not self.XFound and self.Timeout != 0 and self.Timeout is not None and self.ReturnValues[ + 0] is None: # Special Qt case because returning for no reason so fake timeout self.ReturnValues = self.TimeoutKey, self.ReturnValues[1] # fake a timeout elif not self.XFound and self.ReturnValues[0] is None: # Return a timeout event... can happen when autoclose used on another window # print("*** Faking timeout ***") @@ -8667,7 +8606,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Should be NEVER called directly by the user. The user can call Window.Read(timeout=0) to get same effect :return: (event, values). (event or timeout_key or None, Dictionary of values or List of values from all elements in the Window) - :rtype: Tuple[(Any), Dict[Any, Any] | List[Any] | None] + :rtype: Tuple[(Any), Dict[Any, Any] | List[Any] | None] """ if self.TKrootDestroyed: try: @@ -8697,20 +8636,18 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg return None, None return _BuildResults(self, False, self) - def _start_autoclose_timer(self): duration = DEFAULT_AUTOCLOSE_TIME if self.AutoCloseDuration is None else self.AutoCloseDuration self.TKAfterID = self.TKroot.after(int(duration * 1000), self._AutoCloseAlarmCallback) - def finalize(self): """ Use this method to cause your layout to built into a real tkinter window. In reality this method is like Read(timeout=0). It doesn't block and uses your layout to create tkinter widgets to represent the elements. Lots of action! - :return: Returns 'self' so that method "Chaining" can happen (read up about it as it's very cool!) - :rtype: (Window) + :return: Returns 'self' so that method "Chaining" can happen (read up about it as it's very cool!) + :rtype: (Window) """ if self.TKrootDestroyed: @@ -8744,7 +8681,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Without this call your changes to a Window will not be visible to the user until the next Read call :return: `self` so that method calls can be easily "chained" - :rtype: (Window) + :rtype: (Window) """ if self.TKrootDestroyed: @@ -8760,15 +8697,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Fill in elements that are input fields with data based on a 'values dictionary' :param values_dict: pairs - :type values_dict: (Dict[Any, Any]) - {Element_key : value} - :return: returns self so can be chained with other methods - :rtype: (Window) + :type values_dict: (Dict[Any, Any]) - {Element_key : value} + :return: returns self so can be chained with other methods + :rtype: (Window) """ FillFormWithValues(self, values_dict) return self - def _find_closest_key(self, search_key): if not isinstance(search_key, str): search_key = str(search_key) @@ -8788,15 +8724,16 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg For now, you'll only see a message printed and the call will continue to funcation as before. - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object :param silent_on_error: If True do not display popup nor print warning of key errors - :type silent_on_error: (bool) - :return: Return value can be: the Element that matches the supplied key if found; an Error Element if silent_on_error is False; None if silent_on_error True; - :rtype: Element | Error Element | None + :type silent_on_error: (bool) + :return: Return value can be: the Element that matches the supplied key if found; an Error Element if silent_on_error is False; None if silent_on_error True; + :rtype: Element | Error Element | None """ - warnings.warn('Use of FindElement is not recommended.\nEither switch to the recommended window[key] format\nor the PEP8 compliant find_element',UserWarning) + warnings.warn('Use of FindElement is not recommended.\nEither switch to the recommended window[key] format\nor the PEP8 compliant find_element', + UserWarning) print('** Warning - FindElement should not be used to look up elements. window[key] or window.find_element are recommended. **') return self.find_element(key, silent_on_error=silent_on_error) @@ -8827,12 +8764,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Rememeber that this call will return None if no match is found which may cause your code to crash if not checked for. - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object :param silent_on_error: If True do not display popup nor print warning of key errors - :type silent_on_error: (bool) - :return: Return value can be: the Element that matches the supplied key if found; an Error Element if silent_on_error is False; None if silent_on_error True; - :rtype: Element | Error Element | None + :type silent_on_error: (bool) + :return: Return value can be: the Element that matches the supplied key if found; an Error Element if silent_on_error is False; None if silent_on_error True; + :rtype: Element | Error Element | None """ try: element = self.AllKeysDict[key] @@ -8841,7 +8778,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg closest_key = self._find_closest_key(key) if not silent_on_error: print('** Error looking up your element using the key: ', key, 'The closest matching key: ', closest_key) - _error_popup_with_traceback('Key Error', 'Problem finding your key '+ str(key), 'Closest match = ' + str(closest_key)) + _error_popup_with_traceback('Key Error', 'Problem finding your key ' + str(key), 'Closest match = ' + str(closest_key)) if not SUPPRESS_RAISE_KEY_ERRORS: raise KeyError(key) element = ErrorElement(key=key) @@ -8865,7 +8802,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ Returns the Element that currently has focus as reported by tkinter. If no element is found None is returned! :return: An Element if one has been found with focus or None if no element found - :rtype: Element | None + :rtype: Element | None """ element = _FindElementWithFocusInSubForm(self) return element @@ -8884,11 +8821,11 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Note that the calls are recursive as all pathes must be walked :param top_window: The highest level of the window - :type top_window: (Window) - :param window: The "sub-window" (container element) to be searched - :type window: Column | Frame | TabGroup | Pane | Tab - :param key_dict: The dictionary as it currently stands.... used as part of recursive call - :return: (dict) Dictionary filled with all keys in the window + :type top_window: (Window) + :param window: The "sub-window" (container element) to be searched + :type window: Column | Frame | TabGroup | Pane | Tab + :param key_dict: The dictionary as it currently stands.... used as part of recursive call + :return: (dict) Dictionary filled with all keys in the window """ for row_num, row in enumerate(window.Rows): for col_num, element in enumerate(row): @@ -8918,7 +8855,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg top_window.DictionaryKeyCounter += 1 if element.Key is not None: if element.Key in key_dict.keys(): - if element.Type != ELEM_TYPE_BUTTON: # for Buttons, let duplicate key errors be silent + if element.Type != ELEM_TYPE_BUTTON: # for Buttons, let duplicate key errors be silent warnings.warn('*** Duplicate key found in your layout {} ***'.format(element.Key), UserWarning) warnings.warn('*** Replaced new key with {} ***'.format(str(element.Key) + str(self.UniqueKeyCounter))) if not SUPPRESS_ERROR_POPUPS: @@ -8931,17 +8868,15 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg key_dict[element.Key] = element return key_dict - def element_list(self): """ Returns a list of all elements in the window - :return: List of all elements in the window and container elements in the window - :rtype: List[Element] + :return: List of all elements in the window and container elements in the window + :rtype: List[Element] """ return self._build_element_list() - def _build_element_list(self): """ Used internally only! Not user callable @@ -8957,13 +8892,13 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Note that the calls are recursive as all pathes must be walked :param top_window: The highest level of the window - :type top_window: (Window) - :param window: The "sub-window" (container element) to be searched - :type window: Column | Frame | TabGroup | Pane | Tab - :param elem_list: The element list as it currently stands.... used as part of recursive call - :type elem_list: ??? - :return: List of all elements in this sub-window - :rtype: List[Element] + :type top_window: (Window) + :param window: The "sub-window" (container element) to be searched + :type window: Column | Frame | TabGroup | Pane | Tab + :param elem_list: The element list as it currently stands.... used as part of recursive call + :type elem_list: ??? + :return: List of all elements in this sub-window + :rtype: List[Element] """ for row_num, row in enumerate(window.Rows): for col_num, element in enumerate(row): @@ -8972,15 +8907,13 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg elem_list = self._build_element_list_for_form(top_window, element, elem_list) return elem_list - - def save_to_disk(self, filename): """ Saves the values contained in each of the input areas of the form. Basically saves what would be returned from a call to Read. It takes these results and saves them to disk using pickle. Note that every element in your layout that is to be saved must have a key assigned to it. :param filename: Filename to save the values to in pickled form - :type filename: str + :type filename: str """ try: event, values = _BuildResults(self, False, self) @@ -9000,7 +8933,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Restore values from a previous call to SaveToDisk which saves the returned values dictionary in Pickle format :param filename: Pickle Filename to load - :type filename: (str) + :type filename: (str) """ try: with open(filename, 'rb') as df: @@ -9013,7 +8946,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Get the screen dimensions. NOTE - you must have a window already open for this to work (blame tkinter not me) :return: Tuple containing width and height of screen in pixels - :rtype: Tuple[None, None] | Tuple[width, height] + :rtype: Tuple[None, None] | Tuple[width, height] """ if self.TKrootDestroyed or self.TKroot is None: @@ -9026,9 +8959,9 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ Move the upper left corner of this window to the x,y coordinates provided :param x: x coordinate in pixels - :type x: (int) + :type x: (int) :param y: y coordinate in pixels - :type y: (int) + :type y: (int) """ try: self.TKroot.geometry("+%s+%s" % (x, y)) @@ -9037,7 +8970,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except: pass - def minimize(self): """ Minimize this window to the task bar @@ -9047,7 +8979,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.TKroot.iconify() self.maximized = False - def maximize(self): """ Maximize the window. This is done differently on a windows system versus a linux or mac one. For non-Windows @@ -9080,14 +9011,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.TKroot.attributes('-fullscreen', False) self.maximized = False - def _StartMove(self, event): """ Used by "Grab Anywhere" style windows. This function is bound to mouse-down. It marks the beginning of a drag. :param event: event information passed in by tkinter. Contains x,y position of mouse - :type event: (event) + :type event: (event) """ - if (isinstance(event.widget, GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list: + if (isinstance(event.widget, + GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list: # print('Found widget to ignore in grab anywhere...') return try: @@ -9102,9 +9033,10 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Used by "Grab Anywhere" style windows. This function is bound to mouse-up. It marks the ending of a drag. Sets the position of the window to this final x,y coordinates :param event: event information passed in by tkinter. Contains x,y position of mouse - :type event: (event) + :type event: (event) """ - if (isinstance(event.widget, GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list: + if (isinstance(event.widget, + GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list: # print('Found widget to ignore in grab anywhere...') return try: @@ -9113,14 +9045,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except Exception as e: print('stop move error', e, event) - def _OnMotion(self, event): """ Used by "Grab Anywhere" style windows. This function is bound to mouse motion. It actually moves the window :param event: event information passed in by tkinter. Contains x,y position of mouse - :type event: (event) + :type event: (event) """ - if (isinstance(event.widget, GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list: + if (isinstance(event.widget, + GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list: # print('Found widget to ignore in grab anywhere...') return try: @@ -9139,11 +9071,9 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except Exception as e: print('on motion error', e) - def _focus_callback(self, event): print('Focus event = {} window = {}'.format(event, self.Title)) - def _config_callback(self, event): print('Config event = {} window = {}'.format(event, self.Title)) # @@ -9163,7 +9093,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg # except Exception as e: # print('on motion error {}'.format(e), 'title = {}'.format(window.Title)) - """ def _config_callback(self, event): new_x = event.x @@ -9216,7 +9145,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg called if user has requested window level keyboard events :param event: object provided by tkinter that contains the key information - :type event: (event) + :type event: (event) """ self.LastButtonClicked = None self.FormRemainedOpen = True @@ -9234,7 +9163,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg have been enabled :param event: object sent in by tkinter that has the wheel direction - :type event: (event) + :type event: (event) """ self.LastButtonClicked = None self.FormRemainedOpen = True @@ -9243,7 +9172,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg # _BuildResults(self, False, self) _exit_mainloop(self) - def _Close(self, without_event=False): """ The internal close call that does the real work of building. This method basically sets up for closing @@ -9271,12 +9199,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg a window so that resources are properly freed up within your thread. """ try: - del Window._active_windows[self] # will only be in the list if window was explicitly finalized + del Window._active_windows[self] # will only be in the list if window was explicitly finalized except: pass try: - self.TKroot.update() # On Linux must call update if the user closed with X or else won't actually close the window + self.TKroot.update() # On Linux must call update if the user closed with X or else won't actually close the window except: pass if self.TKrootDestroyed: @@ -9300,7 +9228,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.Rows = None self.TKroot = None - # IT FINALLY WORKED! 29-Oct-2018 was the first time this damned thing got called def _OnClosingCallback(self): """ @@ -9322,7 +9249,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg _exit_mainloop(self) else: if self.close_destroys_window: - self.TKroot.destroy() # destroy this window + self.TKroot.destroy() # destroy this window self.XFound = True else: self.LastButtonClicked = WINDOW_CLOSE_ATTEMPTED_EVENT @@ -9389,7 +9316,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg Sets the Alpha Channel for a window. Values are between 0 and 1 where 0 is completely transparent :param alpha: 0 to 1. 0 is completely transparent. 1 is completely visible and solid (can't see through) - :type alpha: (float) + :type alpha: (float) """ if not self._is_window_created('tried Window.set_alpha'): return @@ -9401,7 +9328,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ A property that changes the current alpha channel value (internal value) :return: the current alpha channel setting according to self, not read directly from tkinter - :rtype: (float) + :rtype: (float) """ return self._AlphaChannel @@ -9411,7 +9338,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg The setter method for this "property". Planning on depricating so that a Set call is always used by users. This is more in line with the SDK :param alpha: 0 to 1. 0 is completely transparent. 1 is completely visible and solid (can't see through) - :type alpha: (float) + :type alpha: (float) """ if not self._is_window_created('tried Window.alpha_channel'): return @@ -9439,7 +9366,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except: pass - def send_to_back(self): """ Pushes this window to the bottom of the stack of windows. It is the opposite of BringToFront @@ -9451,7 +9377,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except: pass - def current_location(self): """ Get the current location of the window's top left corner. @@ -9460,20 +9385,19 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg off depending on if your window has a titlebar or menubar. :return: The x and y location in tuple form (x,y) - :rtype: Tuple[(int), (int)] + :rtype: Tuple[(int), (int)] """ if not self._is_window_created('tried Window.current_location'): return return int(self.TKroot.winfo_x()), int(self.TKroot.winfo_y()) - @property def size(self): """ Return the current size of the window in pixels :return: (width, height) of the window - :rtype: Tuple[(int), (int)] or Tuple[None, None] + :rtype: Tuple[(int), (int)] or Tuple[None, None] """ if not self._is_window_created('Tried to use Window.size property'): return (None, None) @@ -9481,14 +9405,13 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg win_height = self.TKroot.winfo_height() return win_width, win_height - @size.setter def size(self, size): """ Changes the size of the window, if possible :param size: (width, height) of the desired window size - :type size: (int, int) + :type size: (int, int) """ try: self.TKroot.geometry("%sx%s" % (size[0], size[1])) @@ -9496,20 +9419,18 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except: pass - def set_min_size(self, size): """ Changes the minimum size of the window. Note Window must be read or finalized first. :param size: (width, height) tuple (int, int) of the desired window size in pixels - :type size: (int, int) + :type size: (int, int) """ if not self._is_window_created('tried Window.set_min_size'): return self.TKroot.minsize(size[0], size[1]) self.TKroot.update_idletasks() - def visibility_changed(self): """ When making an element in a column or someplace that has a scrollbar, then you'll want to call this function @@ -9517,13 +9438,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ self.refresh() - def set_transparent_color(self, color): """ Set the color that will be transparent in your window. Areas with this color will be SEE THROUGH. :param color: Color string that defines the transparent color - :type color: (str) + :type color: (str) """ if not self._is_window_created('tried Window.set_transparent_color'): return @@ -9533,7 +9453,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except: print('Transparent color not supported on this platform (windows only)') - def grab_any_where_on(self): """ Turns on Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet @@ -9545,7 +9464,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.TKroot.bind("", self._StopMove) self.TKroot.bind("", self._OnMotion) - def grab_any_where_off(self): """ Turns off Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet @@ -9557,14 +9475,13 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.TKroot.unbind("") self.TKroot.unbind("") - def _user_bind_callback(self, bind_string, event): """ Used when user binds a tkinter event directly to an element :param bind_string: The event that was bound so can lookup the key modifier - :type bind_string: Mike_please_insert_type_here - :param event: Event data passed in by tkinter (not used) + :type bind_string: Mike_please_insert_type_here + :param event: Event data passed in by tkinter (not used) """ key = self.user_bind_dict.get(bind_string, '') @@ -9578,22 +9495,20 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg # self.TKroot.quit() _exit_mainloop(self) - def bind(self, bind_string, key): """ Used to add tkinter events to a Window. The tkinter specific data is in the Window's member variable user_bind_event :param bind_string: The string tkinter expected in its bind function - :type bind_string: (str) - :param key: The event that will be generated when the tkinter event occurs - :type key: str | int | tuple | object + :type bind_string: (str) + :param key: The event that will be generated when the tkinter event occurs + :type key: str | int | tuple | object """ if not self._is_window_created('tried Window.bind'): return self.TKroot.bind(bind_string, lambda evt: self._user_bind_callback(bind_string, evt)) self.user_bind_dict[bind_string] = key - def _callback_main_debugger_window_create_keystroke(self, event): """ Called when user presses the key that creates the main debugger window @@ -9602,7 +9517,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ _Debugger.debugger._build_main_debugger_window() - def _callback_popout_window_create_keystroke(self, event): """ Called when user presses the key that creates the floating debugger window @@ -9611,7 +9525,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg """ _Debugger.debugger._build_floating_window() - def enable_debugger(self): """ Enables the internal debugger. By default, the debugger IS enabled @@ -9622,7 +9535,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.TKroot.bind('', self._callback_popout_window_create_keystroke) self.DebuggerEnabled = True - def disable_debugger(self): """ Disable the internal debugger. By default the debugger is ENABLED @@ -9633,19 +9545,17 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.TKroot.unbind("") self.DebuggerEnabled = False - def set_title(self, title): """ Change the title of the window :param title: The string to set the title to - :type title: (str) + :type title: (str) """ if not self._is_window_created('tried Window.set_title'): return self.TKroot.wm_title(str(title)) - def make_modal(self): """ Makes a window into a "Modal Window" @@ -9666,7 +9576,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg except Exception as e: print('Exception trying to make modal', e) - def force_focus(self): """ Forces this window to take focus @@ -9675,27 +9584,22 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg return self.TKroot.focus_force() - - - def was_closed(self): """ Returns True if the window was closed :return: True if the window is closed - :rtype: bool + :rtype: bool """ return self.TKrootDestroyed - - def set_cursor(self, cursor): """ Sets the cursor for the window. If you do not want any mouse pointer, then use the string "none" :param cursor: The tkinter cursor name - :type cursor: (str) + :type cursor: (str) """ if not self._is_window_created('tried Window.set_cursor'): @@ -9706,13 +9610,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg print('Warning bad cursor specified ', cursor) print(e) - def ding(self, display_number=0): """ Make a "bell" sound. A capability provided by tkinter. Your window needs to be finalized prior to calling. Ring a display's bell is the tkinter description of the call. :param display_number: Passed to tkinter's bell method as parameter "displayof". - :type display_number: int + :type display_number: int """ if not self._is_window_created('tried Window.ding'): return @@ -9722,8 +9625,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg if not SUPPRESS_ERROR_POPUPS: _error_popup_with_traceback('Window.ding() - tkinter reported error from bell() call', e) - - def _window_tkvar_changed_callback(self, *args): + def _window_tkvar_changed_callback(self, *args): """ Internal callback function for when the thread @@ -9736,15 +9638,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg # print(''.join(trace_details)) # self.thread_lock.acquire() # if self.thread_timer: - # self.TKroot.after_cancel(id=self.thread_timer) - # self.thread_timer = None + # self.TKroot.after_cancel(id=self.thread_timer) + # self.thread_timer = None # self.thread_lock.release() if self._queued_thread_event_available(): self.FormRemainedOpen = True _exit_mainloop(self) - def _create_thread_queue(self): """ Creates the queue used by threads to communicate with this window @@ -9760,15 +9661,14 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg self.thread_strvar = tk.StringVar() self.thread_strvar.trace('w', self._window_tkvar_changed_callback) - def write_event_value(self, key, value): """ Adds a key & value tuple to the queue that is used by threads to communicate with the window - :param key: The key that will be returned as the event when reading the window - :type key: Any + :param key: The key that will be returned as the event when reading the window + :type key: Any :param value: The value that will be in the values dictionary - :type value: Any + :type value: Any """ if self.thread_queue is None: @@ -9776,7 +9676,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg return # self.thread_lock.acquire() # first lock the critical section self.thread_queue.put(item=(key, value)) - self.TKroot.tk.willdispatch() # brilliant bit of code provided by Giuliano who I owe a million thank yous! + self.TKroot.tk.willdispatch() # brilliant bit of code provided by Giuliano who I owe a million thank yous! self.thread_strvar.set('new item') # self.thread_queue.put(item=(key, value)) @@ -9792,14 +9692,13 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg if self.thread_queue is None: return None - try: # see if something has been posted to Queue + try: # see if something has been posted to Queue message = self.thread_queue.get_nowait() - except queue.Empty: # get_nowait() will get exception when Queue is empty + except queue.Empty: # get_nowait() will get exception when Queue is empty return None return message - def _queued_thread_event_available(self): if self.thread_queue is None: @@ -9811,20 +9710,16 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg # self.thread_lock.release() return qsize != 0 - - @property def key_dict(self): """ Returns a dictionary with all keys and their corresponding elements { key : Element } :return: Dictionary of keys and elements - :rtype: Dict[Any, Element] + :rtype: Dict[Any, Element] """ return self.AllKeysDict - - # def __enter__(self): # """ # WAS used with context managers which are no longer needed nor advised. It is here for legacy support and @@ -9840,13 +9735,12 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg window['element key'].Update :param key: The key to find - :type key: str | int | tuple | object - :rtype: Element | Input | Combo | OptionMenu | Listbox | Radio | Checkbox | Spin | Multiline | Text | StatusBar | Output | Button | ButtonMenu | ProgressBar | Image | Canvas | Graph | Frame | VerticalSeparator | HorizontalSeparator | Tab | TabGroup | Slider | Column | Pane | Menu | Table | Tree | ErrorElement | None + :type key: str | int | tuple | object + :rtype: Element | Input | Combo | OptionMenu | Listbox | Radio | Checkbox | Spin | Multiline | Text | StatusBar | Output | Button | ButtonMenu | ProgressBar | Image | Canvas | Graph | Frame | VerticalSeparator | HorizontalSeparator | Tab | TabGroup | Slider | Column | Pane | Menu | Table | Tree | ErrorElement | None """ return self.find_element(key) - def __call__(self, *args, **kwargs): """ Call window.read but without having to type it out. @@ -9854,21 +9748,22 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg window(timeout=50) == window.read(timeout=50) :return: The famous event, values that Read returns. - :rtype: Tuple[Any, Dict[Any, Any]] + :rtype: Tuple[Any, Dict[Any, Any]] """ return self.read(*args, **kwargs) def _is_window_created(self, additional_message=''): msg = str(additional_message) if self.TKroot is None: - warnings.warn('You cannot perform operations on a Window until it is read or finalized. Adding a "finalize=True" parameter to your Window creation will fix this. ' + msg, UserWarning) + warnings.warn( + 'You cannot perform operations on a Window until it is read or finalized. Adding a "finalize=True" parameter to your Window creation will fix this. ' + msg, + UserWarning) if not SUPPRESS_ERROR_POPUPS: _error_popup_with_traceback('You cannot perform operations on a Window until it is read or finalized.', - 'Adding a "finalize=True" parameter to your Window creation will likely fix this', msg) + 'Adding a "finalize=True" parameter to your Window creation will likely fix this', msg) return False return True - def _has_custom_titlebar_element(self): for elem in self.AllKeysDict.values(): if elem.Key in (TITLEBAR_MAXIMIZE_KEY, TITLEBAR_CLOSE_KEY, TITLEBAR_IMAGE_KEY): @@ -9877,8 +9772,6 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg return True return False - - AddRow = add_row AddRows = add_rows AlphaChannel = alpha_channel @@ -9924,7 +9817,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg # WAS used with context managers which are no longer needed nor advised. It is here for legacy support and # am afraid of removing right now # :param *a: (?) Not sure what's passed in. - # :return: Always returns False which was needed for context manager to work + # :return: Always returns False which was needed for context manager to work # """ # self.__del__() # return False @@ -9941,6 +9834,7 @@ Normally a tuple, but can be a simplified-dual-color-string "foreground on backg FlexForm = Window + def _exit_mainloop(exiting_window): if exiting_window == Window._window_running_mainloop or Window._root_running_mainloop == Window.hidden_master_root: Window._window_that_exited = exiting_window @@ -9976,12 +9870,12 @@ def read_all_windows(timeout=None, timeout_key=TIMEOUT_KEY): If no windows are open, then the value (None, WIN_CLOSED, None) will be returned Since WIN_CLOSED is None, it means (None, None, None) is what's returned when no windows remain opened - :param timeout: Time in milliseconds to delay before a returning a timeout event - :type timeout: (int) + :param timeout: Time in milliseconds to delay before a returning a timeout event + :type timeout: (int) :param timeout_key: Key to return when a timeout happens. Defaults to the standard TIMEOUT_KEY - :type timeout_key: (Any) - :return: A tuple with the (Window, event, values dictionary/list) - :rtype: Tuple[Window, Any, (Dict or List)] + :type timeout_key: (Any) + :return: A tuple with the (Window, event, values dictionary/list) + :rtype: Tuple[Window, Any, (Dict or List)] """ if len(Window._active_windows) == 0: @@ -10004,11 +9898,10 @@ def read_all_windows(timeout=None, timeout_key=TIMEOUT_KEY): event = timeout_key if values is None: event = None - Window._timeout_0_counter = (Window._timeout_0_counter +1 ) % len(Window._active_windows) + Window._timeout_0_counter = (Window._timeout_0_counter + 1) % len(Window._active_windows) return window, event, values - Window._timeout_0_counter = 0 # reset value if not reading with timeout 0 so ready next time needed - + Window._timeout_0_counter = 0 # reset value if not reading with timeout 0 so ready next time needed # setup timeout timer if timeout != None: @@ -10052,8 +9945,6 @@ def read_all_windows(timeout=None, timeout_key=TIMEOUT_KEY): return window, event, values - - ###### ## ## ###### ######## ######## ## ## ## ## ## ## ## ## ## ## ### ### ## #### ## ## ## #### #### @@ -10080,7 +9971,7 @@ def read_all_windows(timeout=None, timeout_key=TIMEOUT_KEY): # ------------------------------------------------------------------- # fade in/out info and default window alpha -SYSTEM_TRAY_WIN_MARGINS = 160, 60 # from right edge of screen, from bottom of screen +SYSTEM_TRAY_WIN_MARGINS = 160, 60 # from right edge of screen, from bottom of screen SYSTEM_TRAY_MESSAGE_MAX_LINE_LENGTH = 50 # colors SYSTEM_TRAY_MESSAGE_WIN_COLOR = "#282828" @@ -10093,8 +9984,6 @@ EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED = '__DOUBLE_CLICKED__' EVENT_SYSTEM_TRAY_ICON_ACTIVATED = '__ACTIVATED__' EVENT_SYSTEM_TRAY_MESSAGE_CLICKED = '__MESSAGE_CLICKED__' - - # Base64 Images to use as icons in the window _tray_icon_error = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADlAAAA5QGP5Zs8AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAIpQTFRF////20lt30Bg30pg4FJc409g4FBe4E9f4U9f4U9g4U9f4E9g31Bf4E9f4E9f4E9f4E9f4E9f4FFh4Vdm4lhn42Bv5GNx5W575nJ/6HqH6HyI6YCM6YGM6YGN6oaR8Kev9MPI9cbM9snO9s3R+Nfb+dzg+d/i++vt/O7v/fb3/vj5//z8//7+////KofnuQAAABF0Uk5TAAcIGBktSYSXmMHI2uPy8/XVqDFbAAAA8UlEQVQ4y4VT15LCMBBTQkgPYem9d9D//x4P2I7vILN68kj2WtsAhyDO8rKuyzyLA3wjSnvi0Eujf3KY9OUP+kno651CvlB0Gr1byQ9UXff+py5SmRhhIS0oPj4SaUUCAJHxP9+tLb/ezU0uEYDUsCc+l5/T8smTIVMgsPXZkvepiMj0Tm5txQLENu7gSF7HIuMreRxYNkbmHI0u5Hk4PJOXkSMz5I3nyY08HMjbpOFylF5WswdJPmYeVaL28968yNfGZ2r9gvqFalJNUy2UWmq1Wa7di/3Kxl3tF1671YHRR04dWn3s9cXRV09f3vb1fwPD7z9j1WgeRgAAAABJRU5ErkJggg==' _tray_icon_success = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAEKAAABCgEWpLzLAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAHJQTFRF////ZsxmbbZJYL9gZrtVar9VZsJcbMRYaMZVasFYaL9XbMFbasRZaMFZacRXa8NYasFaasJaasFZasJaasNZasNYasJYasJZasJZasJZasJZasJZasJYasJZasJZasJZasJZasJaasJZasJZasJZasJZ2IAizQAAACV0Uk5TAAUHCA8YGRobHSwtPEJJUVtghJeYrbDByNjZ2tvj6vLz9fb3/CyrN0oAAADnSURBVDjLjZPbWoUgFIQnbNPBIgNKiwwo5v1fsQvMvUXI5oqPf4DFOgCrhLKjC8GNVgnsJY3nKm9kgTsduVHU3SU/TdxpOp15P7OiuV/PVzk5L3d0ExuachyaTWkAkLFtiBKAqZHPh/yuAYSv8R7XE0l6AVXnwBNJUsE2+GMOzWL8k3OEW7a/q5wOIS9e7t5qnGExvF5Bvlc4w/LEM4Abt+d0S5BpAHD7seMcf7+ZHfclp10TlYZc2y2nOqc6OwruxUWx0rDjNJtyp6HkUW4bJn0VWdf/a7nDpj1u++PBOR694+Ftj/8PKNdnDLn/V8YAAAAASUVORK5CYII=' @@ -10104,7 +9993,6 @@ _tray_icon_stop = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c _tray_icon_exclamation = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAN0zM900NN01Nd02Nt03N944ON45Od46Ot47O98/P99BQd9CQt9DQ+FPT+JSUuJTU+JUVOJVVeJWVuNbW+ReXuVjY+Zra+dxceh4eOl7e+l8fOl+ful/f+qBgeqCguqDg+qFheuJieuLi+yPj+yQkO2Wlu+cnO+hofGqqvGtrfre3vrf3/ri4vvn5/75+f76+v/+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQ8SQkAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABJElEQVQ4T4WS63KCMBBGsyBai62X0otY0aq90ZZa3v/dtpvsJwTijOfXt7tnILOJYY9tNonjNCtQOlqhuKKG0RrNVjgkmIHBHgMId+h7zHSiwg2a9FNVVYScupETmjkd67o+CWpYwft+R6CpCgeUlq5AOyf45+8JsRUKFI6eQLkI3n5CIREBUekLxGaLpATCymRISiAszARJCYSxiZGUQKDLQoqgnPnFhUPOTWeRoZD3FvVZlmVHkE2OEM9iV71GVoZDBGUpAg9QWN5/jx+Ilsi9hz0q4VHOWD+hEF70yc1QEr1a4Q0F0S3eJDfLuv8T4QEFXduZE1rj+et7g6hzCDxF08N+X4DAu+6lUSTnc5wE5tx73ckSTV8QVoux3N88Rykw/wP3i+vwPKk17AAAAABJRU5ErkJggg==' _tray_icon_none = None - SYSTEM_TRAY_MESSAGE_ICON_INFORMATION = _tray_icon_success SYSTEM_TRAY_MESSAGE_ICON_WARNING = _tray_icon_exclamation SYSTEM_TRAY_MESSAGE_ICON_CRITICAL = _tray_icon_stop @@ -10124,18 +10012,18 @@ class SystemTray: def __init__(self, menu=None, filename=None, data=None, data_base64=None, tooltip=None, metadata=None): """ SystemTray - create an icon in the system tray - :param menu: Menu definition. Example - ['UNUSED', ['My', 'Simple', '---', 'Menu', 'Exit']] - :type menu: List[List[List[str] or str]] - :param filename: filename for icon - :type filename: (str) - :param data: in-ram image for icon (same as data_base64 parm) - :type data: (bytes) + :param menu: Menu definition. Example - ['UNUSED', ['My', 'Simple', '---', 'Menu', 'Exit']] + :type menu: List[List[List[str] or str]] + :param filename: filename for icon + :type filename: (str) + :param data: in-ram image for icon (same as data_base64 parm) + :type data: (bytes) :param data_base64: base-64 data for icon - :type data_base64: (bytes) - :param tooltip: tooltip string - :type tooltip: (str) - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) + :type data_base64: (bytes) + :param tooltip: tooltip string + :type tooltip: (str) + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) """ self._metadata = None self.Menu = menu @@ -10158,7 +10046,8 @@ class SystemTray: layout = [ [image_elem], ] - self.window = Window('Window Title', layout, element_padding=(0, 0), margins=(0, 0), grab_anywhere=True, no_titlebar=True, transparent_color='red', keep_on_top=True, right_click_menu=menu, location=(screen_size[0] - 100, screen_size[1] - 100), finalize=True) + self.window = Window('Window Title', layout, element_padding=(0, 0), margins=(0, 0), grab_anywhere=True, no_titlebar=True, transparent_color='red', + keep_on_top=True, right_click_menu=menu, location=(screen_size[0] - 100, screen_size[1] - 100), finalize=True) self.window['-IMAGE-'].bind('', '+DOUBLE_CLICK') @@ -10167,22 +10056,19 @@ class SystemTray: """ Metadata is an SystemTray property that you can use at any time to hold any value :return: the current metadata value - :rtype: (Any) + :rtype: (Any) """ return self._metadata - @metadata.setter def metadata(self, value): """ Metadata is an SystemTray property that you can use at any time to hold any value :param value: Anything you want it to be - :type value: (Any) + :type value: (Any) """ self._metadata = value - - def read(self, timeout=None): """ Reads the context menu @@ -10201,38 +10087,36 @@ class SystemTray: return event - def hide(self): """ Hides the icon """ self.window.hide() - def un_hide(self): """ Restores a previously hidden icon """ self.window.un_hide() - - def show_message(self, title, message, filename=None, data=None, data_base64=None, messageicon=None, time=(SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION, SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS)): + def show_message(self, title, message, filename=None, data=None, data_base64=None, messageicon=None, + time=(SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION, SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS)): """ Shows a balloon above icon in system tray - :param title: Title shown in balloon - :type title: str - :param message: Message to be displayed - :type message: str - :param filename: Optional icon filename - :type filename: str - :param data: Optional in-ram icon - :type data: b'' + :param title: Title shown in balloon + :type title: str + :param message: Message to be displayed + :type message: str + :param filename: Optional icon filename + :type filename: str + :param data: Optional in-ram icon + :type data: b'' :param data_base64: Optional base64 icon - :type data_base64: b'' - :param time: Amount of time to display message in milliseconds. If tuple, first item is fade in/out duration - :type time: int | (int, int) - :return: The event that happened during the display such as user clicked on message - :rtype: Any + :type data_base64: b'' + :param time: Amount of time to display message in milliseconds. If tuple, first item is fade in/out duration + :type time: int | (int, int) + :return: The event that happened during the display such as user clicked on message + :rtype: Any """ if isinstance(time, tuple): @@ -10253,20 +10137,19 @@ class SystemTray: """ self.window.close() - - def update(self, menu=None, tooltip=None,filename=None, data=None, data_base64=None,): + def update(self, menu=None, tooltip=None, filename=None, data=None, data_base64=None, ): """ Updates the menu, tooltip or icon - :param menu: menu defintion - :type menu: ??? - :param tooltip: string representing tooltip - :type tooltip: ??? - :param filename: icon filename - :type filename: ??? - :param data: icon raw image - :type data: ??? + :param menu: menu defintion + :type menu: ??? + :param tooltip: string representing tooltip + :type tooltip: ??? + :param filename: icon filename + :type filename: ??? + :param data: icon raw image + :type data: ??? :param data_base64: icon base 64 image - :type data_base64: ??? + :type data_base64: ??? """ # Menu if menu is not None: @@ -10284,29 +10167,28 @@ class SystemTray: if tooltip: self.window['-IMAGE-'].set_tooltip(tooltip) - @classmethod def notify(cls, title, message, icon=_tray_icon_success, display_duration_in_ms=SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS, fade_in_duration=SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION, alpha=0.9, location=None): """ Displays a "notification window", usually in the bottom right corner of your display. Has an icon, a title, and a message The window will slowly fade in and out if desired. Clicking on the window will cause it to move through the end the current "phase". For example, if the window was fading in and it was clicked, then it would immediately stop fading in and instead be fully visible. It's a way for the user to quickly dismiss the window. - :param title: Text to be shown at the top of the window in a larger font - :type title: (str) - :param message: Text message that makes up the majority of the window - :type message: (str) - :param icon: A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window - :type icon: bytes | str + :param title: Text to be shown at the top of the window in a larger font + :type title: (str) + :param message: Text message that makes up the majority of the window + :type message: (str) + :param icon: A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window + :type icon: bytes | str :param display_duration_in_ms: Number of milliseconds to show the window - :type display_duration_in_ms: (int) - :param fade_in_duration: Number of milliseconds to fade window in and out - :type fade_in_duration: (int) - :param alpha: Alpha channel. 0 - invisible 1 - fully visible - :type alpha: (float) - :param location: Location on the screen to display the window - :type location: (int, int) - :return: (int) reason for returning - :rtype: (int) + :type display_duration_in_ms: (int) + :param fade_in_duration: Number of milliseconds to fade window in and out + :type fade_in_duration: (int) + :param alpha: Alpha channel. 0 - invisible 1 - fully visible + :type alpha: (float) + :param location: Location on the screen to display the window + :type location: (int, int) + :return: (int) reason for returning + :rtype: (int) """ messages = message.split('\n') @@ -10330,13 +10212,16 @@ class SystemTray: window = Window(title, layout, background_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR, no_titlebar=True, location=win_location, keep_on_top=True, alpha_channel=0, margins=(0, 0), element_padding=(0, 0), grab_anywhere=True, finalize=True) - window["-GRAPH-"].draw_rectangle((win_width, win_height), (-win_width, -win_height), fill_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR, line_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR) + window["-GRAPH-"].draw_rectangle((win_width, win_height), (-win_width, -win_height), fill_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR, + line_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR) if type(icon) is bytes: window["-GRAPH-"].draw_image(data=icon, location=(20, 20)) elif icon is not None: window["-GRAPH-"].draw_image(filename=icon, location=(20, 20)) - window["-GRAPH-"].draw_text(title, location=(64, 20), color=SYSTEM_TRAY_MESSAGE_TEXT_COLOR, font=("Helvetica", 12, "bold"), text_location=TEXT_LOCATION_TOP_LEFT) - window["-GRAPH-"].draw_text(message, location=(64, 44), color=SYSTEM_TRAY_MESSAGE_TEXT_COLOR, font=("Helvetica", 9), text_location=TEXT_LOCATION_TOP_LEFT) + window["-GRAPH-"].draw_text(title, location=(64, 20), color=SYSTEM_TRAY_MESSAGE_TEXT_COLOR, font=("Helvetica", 12, "bold"), + text_location=TEXT_LOCATION_TOP_LEFT) + window["-GRAPH-"].draw_text(message, location=(64, 44), color=SYSTEM_TRAY_MESSAGE_TEXT_COLOR, font=("Helvetica", 9), + text_location=TEXT_LOCATION_TOP_LEFT) window["-GRAPH-"].set_cursor('hand2') if fade_in_duration: @@ -10371,11 +10256,6 @@ class SystemTray: Update = update - - - - - # ################################################################################ # ################################################################################ # END OF ELEMENT DEFINITIONS @@ -10383,10 +10263,6 @@ class SystemTray: # ################################################################################ - - - - # =========================================================================== # # Button Lazy Functions so the caller doesn't have to define a bunch of stuff # # =========================================================================== # @@ -10397,11 +10273,11 @@ def Sizer(h_pixels=0, v_pixels=0): "Pushes" out the size of whatever it is placed inside of. This includes Columns, Frames, Tabs and Windows :param h_pixels: number of horizontal pixels - :type h_pixels: (int) + :type h_pixels: (int) :param v_pixels: number of vertical pixels - :type v_pixels: (int) - :return: (Column) A column element that has a pad setting set according to parameters - :rtype: (Column) + :type v_pixels: (int) + :return: (Column) A column element that has a pad setting set according to parameters + :rtype: (Column) """ return Column([[]], pad=((h_pixels, 0), (v_pixels, 0))) @@ -10412,23 +10288,23 @@ def pin(elem, vertical_alignment=None, shrink=True, expand_x=None, expand_y=None Pin's an element provided into a layout so that when it's made invisible and visible again, it will be in the correct place. Otherwise it will be placed at the end of its containing window/column. - :param elem: the element to put into the layout - :type elem: Element + :param elem: the element to put into the layout + :type elem: Element :param vertical_alignment: Aligns elements vertically. 'top', 'center', 'bottom'. Can be shortened to 't', 'c', 'b' - :type vertical_alignment: str | None - :param shrink: If True, then the space will shrink down to a single pixel when hidden. False leaves the area large and blank - :type shrink: bool - :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_x: (bool) - :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_y: (bool) - :return: A column element containing the provided element - :rtype: Column + :type vertical_alignment: str | None + :param shrink: If True, then the space will shrink down to a single pixel when hidden. False leaves the area large and blank + :type shrink: bool + :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_x: (bool) + :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_y: (bool) + :return: A column element containing the provided element + :rtype: Column """ if shrink: - return Column([[elem, Canvas(size=(0,0), pad=(0,0))]], pad=(0,0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y) + return Column([[elem, Canvas(size=(0, 0), pad=(0, 0))]], pad=(0, 0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y) else: - return Column([[elem]], pad=(0,0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y) + return Column([[elem]], pad=(0, 0), vertical_alignment=vertical_alignment, expand_x=expand_x, expand_y=expand_y) def vtop(elem_or_row, expand_x=None, expand_y=None): @@ -10436,19 +10312,19 @@ def vtop(elem_or_row, expand_x=None, expand_y=None): Align an element or a row of elements to the top of the row that contains it :param elem_or_row: the element or row of elements - :type elem_or_row: Element | List[Element] | Tuple[Element] - :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_x: (bool) - :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_y: (bool) - :return: A column element containing the provided element aligned to the top or list of elements (a row) - :rtype: Column | List[Column] + :type elem_or_row: Element | List[Element] | Tuple[Element] + :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_x: (bool) + :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_y: (bool) + :return: A column element containing the provided element aligned to the top or list of elements (a row) + :rtype: Column | List[Column] """ if isinstance(elem_or_row, list) or isinstance(elem_or_row, tuple): - return [Column([[e]], pad=(0,0), vertical_alignment='top', expand_x=expand_x, expand_y=expand_y) for e in elem_or_row] + return [Column([[e]], pad=(0, 0), vertical_alignment='top', expand_x=expand_x, expand_y=expand_y) for e in elem_or_row] - return Column([[elem_or_row]], pad=(0,0), vertical_alignment='top', expand_x=expand_x, expand_y=expand_y) + return Column([[elem_or_row]], pad=(0, 0), vertical_alignment='top', expand_x=expand_x, expand_y=expand_y) def vcenter(elem_or_row, expand_x=None, expand_y=None): @@ -10456,20 +10332,19 @@ def vcenter(elem_or_row, expand_x=None, expand_y=None): Align an element or a row of elements to the center of the row that contains it :param elem_or_row: the element or row of elements - :type elem_or_row: Element | List[Element] | Tuple[Element] - :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_x: (bool) - :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_y: (bool) - :return: A column element containing the provided element aligned to the center or list of elements (a row) - :rtype: Column | List[Column] + :type elem_or_row: Element | List[Element] | Tuple[Element] + :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_x: (bool) + :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_y: (bool) + :return: A column element containing the provided element aligned to the center or list of elements (a row) + :rtype: Column | List[Column] """ if isinstance(elem_or_row, list) or isinstance(elem_or_row, tuple): - return [Column([[e]], pad=(0,0), vertical_alignment='center') for e in elem_or_row] + return [Column([[e]], pad=(0, 0), vertical_alignment='center') for e in elem_or_row] - - return Column([[elem_or_row]], pad=(0,0), vertical_alignment='center') + return Column([[elem_or_row]], pad=(0, 0), vertical_alignment='center') def vbottom(elem_or_row, expand_x=None, expand_y=None): @@ -10477,26 +10352,22 @@ def vbottom(elem_or_row, expand_x=None, expand_y=None): Align an element or a row of elements to the bottom of the row that contains it :param elem_or_row: the element or row of elements - :type elem_or_row: Element | List[Element] | Tuple[Element] - :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_x: (bool) - :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature - :type expand_y: (bool) - :return: A column element containing the provided element aligned to the bottom or list of elements (a row) - :rtype: Column | List[Column] + :type elem_or_row: Element | List[Element] | Tuple[Element] + :param expand_x: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_x: (bool) + :param expand_y: If True/False the value will be passed to the Column Elements used to make this feature + :type expand_y: (bool) + :return: A column element containing the provided element aligned to the bottom or list of elements (a row) + :rtype: Column | List[Column] """ if isinstance(elem_or_row, list) or isinstance(elem_or_row, tuple): - return [Column([[e]], pad=(0,0), vertical_alignment='bottom') for e in elem_or_row] + return [Column([[e]], pad=(0, 0), vertical_alignment='bottom') for e in elem_or_row] + + return Column([[elem_or_row]], pad=(0, 0), vertical_alignment='bottom') - return Column([[elem_or_row]], pad=(0,0), vertical_alignment='bottom') - - - - - -def Titlebar(title='',icon=None, text_color=None, background_color=None, font=None, key=None, k=None): +def Titlebar(title='', icon=None, text_color=None, background_color=None, font=None, key=None, k=None): """ A custom titlebar that replaces the OS provided titlebar, thus giving you control the is not possible using the OS provided titlebar such as the color. @@ -10514,22 +10385,22 @@ def Titlebar(title='',icon=None, text_color=None, background_color=None, font=No The Titlebar is a COLUMN element. You can thus call the update method for the column and perform operations such as making the column visible/invisible - :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO - :type icon: str or bytes or None - :param title: The "title" to show in the titlebar - :type title: str - :param text_color: Text color for titlebar - :type text_color: str | None + :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO + :type icon: str or bytes or None + :param title: The "title" to show in the titlebar + :type title: str + :param text_color: Text color for titlebar + :type text_color: str | None :param background_color: Background color for titlebar - :type background_color: str | None - :param font: Font to be used for the text and the symbols - :type font: str | None - :param key: Identifies an Element. Should be UNIQUE to this window. - :type key: str | int | tuple | object | None - :param k: Exactly the same as key. Choose one of them to use - :type k: str | int | tuple | object | None - :return: A single Column element that has eveything in 1 element - :rtype: Column + :type background_color: str | None + :param font: Font to be used for the text and the symbols + :type font: str | None + :param key: Identifies an Element. Should be UNIQUE to this window. + :type key: str | int | tuple | object | None + :param k: Exactly the same as key. Choose one of them to use + :type k: str | int | tuple | object | None + :return: A single Column element that has eveything in 1 element + :rtype: Column """ bc = background_color or CUSTOM_TITLEBAR_BACKGROUND_COLOR or theme_button_color()[1] tc = text_color or CUSTOM_TITLEBAR_TEXT_COLOR or theme_button_color()[0] @@ -10552,48 +10423,49 @@ def Titlebar(title='',icon=None, text_color=None, background_color=None, font=No icon_and_text_portion += [T(title, text_color=tc, background_color=bc, font=font, grab=True)] - return Column([[Column([icon_and_text_portion], pad=(0, 0), background_color=bc), Column([[T(SYMBOL_TITLEBAR_MINIMIZE, text_color=tc, background_color=bc, enable_events=True, font=font, key=TITLEBAR_MINIMIZE_KEY), - Text(SYMBOL_TITLEBAR_MAXIMIZE, text_color=tc, background_color=bc, enable_events=True, font=font,key=TITLEBAR_MAXIMIZE_KEY), - Text(SYMBOL_TITLEBAR_CLOSE, text_color=tc, background_color=bc, font=font, enable_events=True, key=TITLEBAR_CLOSE_KEY),]], - element_justification='r', expand_x=True, grab=True, pad=(0, 0), background_color=bc)]],expand_x=True, grab=True, background_color=bc, pad=(0,0),metadata=TITLEBAR_METADATA_MARKER, key=key) + Text(SYMBOL_TITLEBAR_MAXIMIZE, text_color=tc, background_color=bc, enable_events=True, font=font, key=TITLEBAR_MAXIMIZE_KEY), + Text(SYMBOL_TITLEBAR_CLOSE, text_color=tc, background_color=bc, font=font, enable_events=True, key=TITLEBAR_CLOSE_KEY), ]], + element_justification='r', expand_x=True, grab=True, pad=(0, 0), background_color=bc)]], expand_x=True, grab=True, + background_color=bc, pad=(0, 0), metadata=TITLEBAR_METADATA_MARKER, key=key) # Not ready for prime time -def MenubarCustom(menu_definition, disabled_text_color=None, bar_font=None, font=None, tearoff=False, pad=None, background_color=None, text_color=None, bar_background_color=None, bar_text_color=None, key=None, k=None): +def MenubarCustom(menu_definition, disabled_text_color=None, bar_font=None, font=None, tearoff=False, pad=None, background_color=None, text_color=None, + bar_background_color=None, bar_text_color=None, key=None, k=None): """ A custom Menubar that replaces the OS provided Menubar Why? Two reasons - 1. they look great (see custom titlebar) 2. if you have a custom titlebar, then you have to use a custom menubar if you want a menubar - :param menu_definition: The Menu definition specified using lists (docs explain the format) - :type menu_definition: List[List[Tuple[str, List[str]]] - :param disabled_text_color: color to use for text when item is disabled. Can be in #RRGGBB format or a color name "black" - :type disabled_text_color: (str) - :param bar_font: specifies the font family, size to be used for the chars in the bar itself - :type bar_font: str | Tuple[str, int] - :param font: specifies the font family, size to be used for the menu items - :type font: str | Tuple[str, int] - :param tearoff: if True, then can tear the menu off from the window ans use as a floating window. Very cool effect - :type tearoff: (bool) - :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param background_color: color to use for background of the menus that are displayed after making a section. Can be in #RRGGBB format or a color name "black". Defaults to the color of the bar text - :type background_color: (str) - :param text_color: color to use for the text of the many items in the displayed menus. Can be in #RRGGBB format or a color name "black". Defaults to the bar background - :type text_color: (str) + :param menu_definition: The Menu definition specified using lists (docs explain the format) + :type menu_definition: List[List[Tuple[str, List[str]]] + :param disabled_text_color: color to use for text when item is disabled. Can be in #RRGGBB format or a color name "black" + :type disabled_text_color: (str) + :param bar_font: specifies the font family, size to be used for the chars in the bar itself + :type bar_font: str | Tuple[str, int] + :param font: specifies the font family, size to be used for the menu items + :type font: str | Tuple[str, int] + :param tearoff: if True, then can tear the menu off from the window ans use as a floating window. Very cool effect + :type tearoff: (bool) + :param pad: Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom)) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param background_color: color to use for background of the menus that are displayed after making a section. Can be in #RRGGBB format or a color name "black". Defaults to the color of the bar text + :type background_color: (str) + :param text_color: color to use for the text of the many items in the displayed menus. Can be in #RRGGBB format or a color name "black". Defaults to the bar background + :type text_color: (str) :param bar_background_color: color to use for the menubar. Can be in #RRGGBB format or a color name "black". Defaults to theme's button text color - :type bar_background_color: (str) - :param bar_text_color: color to use for the menu items text when item is disabled. Can be in #RRGGBB format or a color name "black". Defaults to theme's button background color - :type bar_text_color: (str) - :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 - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :returns: A Column element that has a series of ButtonMenu elements - :rtype: Column + :type bar_background_color: (str) + :param bar_text_color: color to use for the menu items text when item is disabled. Can be in #RRGGBB format or a color name "black". Defaults to theme's button background color + :type bar_text_color: (str) + :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 + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :returns: A Column element that has a series of ButtonMenu elements + :rtype: Column """ bar_bg = bar_background_color if bar_background_color is not None else theme_button_color()[0] @@ -10612,53 +10484,52 @@ def MenubarCustom(menu_definition, disabled_text_color=None, bar_font=None, font else: disabled = False - - button_menu = ButtonMenu(text, menu, border_width=0, button_color=(bar_text, bar_bg), key=text, pad=(0,0), disabled=disabled, font=bar_font, item_font=font, disabled_text_color=disabled_text_color, text_color=menu_text, background_color=menu_bg, tearoff=tearoff) + button_menu = ButtonMenu(text, menu, border_width=0, button_color=(bar_text, bar_bg), key=text, pad=(0, 0), disabled=disabled, font=bar_font, + item_font=font, disabled_text_color=disabled_text_color, text_color=menu_text, background_color=menu_bg, tearoff=tearoff) button_menu.part_of_custom_menubar = True button_menu.custom_menubar_key = key if key is not None else k row += [button_menu] return Column([row], pad=pad, background_color=bar_bg, expand_x=True, key=key if key is not None else k) - # ------------------------- FOLDER BROWSE Element lazy function ------------------------- # def FolderBrowse(button_text='Browse', target=(ThisRow, -1), initial_folder=None, tooltip=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, disabled=False, change_submits=False, enable_events=False, font=None, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Browse') - :type button_text: (str) - :param target: target for the button (Default value = (ThisRow, -1)) - :type target: key or (row,col) - :param initial_folder: starting path for folders and files - :type initial_folder: (str) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Browse') + :type button_text: (str) + :param target: target for the button (Default value = (ThisRow, -1)) + :type target: key or (row,col) + :param initial_folder: starting path for folders and files + :type initial_folder: (str) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param change_submits: If True, pressing Enter key submits window (Default = False) - :type enable_events: (bool) - :param enable_events: Turns on the element specific events.(Default = False) - :type enable_events: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param pad: Amount of padding to put around element - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: The Button created - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param change_submits: If True, pressing Enter key submits window (Default = False) + :type enable_events: (bool) + :param enable_events: Turns on the element specific events.(Default = False) + :type enable_events: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param pad: Amount of padding to put around element + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: The Button created + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_BROWSE_FOLDER, target=target, @@ -10674,40 +10545,40 @@ def FileBrowse(button_text='Browse', target=(ThisRow, -1), file_types=(("ALL Fil pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Browse') - :type button_text: (str) - :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) - :param file_types: filter file types (Default value = (("ALL Files", "*.*"))) - :type file_types: Tuple[(str, str), ...] - :param initial_folder: starting path for folders and files - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Browse') + :type button_text: (str) + :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) + :param file_types: filter file types (Default value = (("ALL Files", "*.*"))) + :type file_types: Tuple[(str, str), ...] + :param initial_folder: starting path for folders and files + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param change_submits: If True, pressing Enter key submits window (Default = False) - :type change_submits: (bool) - :param enable_events: Turns on the element specific events.(Default = False) - :type enable_events: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param change_submits: If True, pressing Enter key submits window (Default = False) + :type change_submits: (bool) + :param enable_events: Turns on the element specific events.(Default = False) + :type enable_events: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_BROWSE_FILE, target=target, file_types=file_types, initial_folder=initial_folder, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, @@ -10723,48 +10594,48 @@ def FilesBrowse(button_text='Browse', target=(ThisRow, -1), file_types=(("ALL Fi """ Allows browsing of multiple files. File list is returned as a single list with the delimiter defined using the files_delimiter parameter. - :param button_text: text in the button (Default value = 'Browse') - :type button_text: (str) - :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) - :param file_types: (Default value = (("ALL Files", "*.*"))) - :type file_types: Tuple[(str, str), ...] - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param initial_folder: starting path for folders and files - :type initial_folder: (str) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Browse') + :type button_text: (str) + :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) + :param file_types: (Default value = (("ALL Files", "*.*"))) + :type file_types: Tuple[(str, str), ...] + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param initial_folder: starting path for folders and files + :type initial_folder: (str) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param change_submits: If True, pressing Enter key submits window (Default = False) - :type change_submits: (bool) - :param enable_events: Turns on the element specific events.(Default = False) - :type enable_events: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param files_delimiter: String to place between files when multiple files are selected. Normally a ; - :type files_delimiter: str - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param change_submits: If True, pressing Enter key submits window (Default = False) + :type change_submits: (bool) + :param enable_events: Turns on the element specific events.(Default = False) + :type enable_events: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param files_delimiter: String to place between files when multiple files are selected. Normally a ; + :type files_delimiter: str + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ button = Button(button_text=button_text, button_type=BUTTON_TYPE_BROWSE_FILES, target=target, file_types=file_types, - initial_folder=initial_folder, change_submits=change_submits, enable_events=enable_events, - tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, - disabled=disabled, button_color=button_color, font=font, pad=pad, key=key, k=k, metadata=metadata) + initial_folder=initial_folder, change_submits=change_submits, enable_events=enable_events, + tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, + disabled=disabled, button_color=button_color, font=font, pad=pad, key=key, k=k, metadata=metadata) button._files_delimiter = files_delimiter return button @@ -10776,43 +10647,43 @@ def FileSaveAs(button_text='Save As...', target=(ThisRow, -1), file_types=(("ALL pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Save As...') - :type button_text: (str) - :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) - :param file_types: (Default value = (("ALL Files", "*.*"))) - :type file_types: Tuple[(str, str), ...] + :param button_text: text in the button (Default value = 'Save As...') + :type button_text: (str) + :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) + :param file_types: (Default value = (("ALL Files", "*.*"))) + :type file_types: Tuple[(str, str), ...] :param default_extension: If no extension entered by user, add this to filename (only used in saveas dialogs) - :type default_extension: (str) - :param initial_folder: starting path for folders and files - :type initial_folder: (str) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) - :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param change_submits: If True, pressing Enter key submits window (Default = False) - :type change_submits: (bool) - :param enable_events: Turns on the element specific events.(Default = False) - :type enable_events: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type default_extension: (str) + :param initial_folder: starting path for folders and files + :type initial_folder: (str) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) + :param auto_size_button: True if button size is determined by button text + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param change_submits: If True, pressing Enter key submits window (Default = False) + :type change_submits: (bool) + :param enable_events: Turns on the element specific events.(Default = False) + :type enable_events: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_SAVEAS_FILE, target=target, file_types=file_types, initial_folder=initial_folder, default_extension=default_extension, tooltip=tooltip, size=size, s=s, disabled=disabled, @@ -10821,52 +10692,52 @@ def FileSaveAs(button_text='Save As...', target=(ThisRow, -1), file_types=(("ALL # ------------------------- SAVE AS Element lazy function ------------------------- # -def SaveAs(button_text='Save As...', target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), initial_folder=None,default_extension='', +def SaveAs(button_text='Save As...', target=(ThisRow, -1), file_types=(("ALL Files", "*.*"),), initial_folder=None, default_extension='', disabled=False, tooltip=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, change_submits=False, enable_events=False, font=None, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Save As...') - :type button_text: (str) - :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) - :param file_types: (Default value = (("ALL Files", "*.*"))) - :type file_types: Tuple[(str, str), ...] + :param button_text: text in the button (Default value = 'Save As...') + :type button_text: (str) + :param target: key or (row,col) target for the button (Default value = (ThisRow, -1)) + :param file_types: (Default value = (("ALL Files", "*.*"))) + :type file_types: Tuple[(str, str), ...] :param default_extension: If no extension entered by user, add this to filename (only used in saveas dialogs) - :type default_extension: (str) - :param initial_folder: starting path for folders and files - :type initial_folder: (str) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) - :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param change_submits: If True, pressing Enter key submits window (Default = False) - :type change_submits: (bool) - :param enable_events: Turns on the element specific events.(Default = False) - :type enable_events: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type default_extension: (str) + :param initial_folder: starting path for folders and files + :type initial_folder: (str) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) + :param auto_size_button: True if button size is determined by button text + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param change_submits: If True, pressing Enter key submits window (Default = False) + :type change_submits: (bool) + :param enable_events: Turns on the element specific events.(Default = False) + :type enable_events: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_SAVEAS_FILE, target=target, file_types=file_types, - initial_folder=initial_folder, default_extension=default_extension, tooltip=tooltip, size=size, s=s, disabled=disabled, + initial_folder=initial_folder, default_extension=default_extension, tooltip=tooltip, size=size, s=s, disabled=disabled, auto_size_button=auto_size_button, button_color=button_color, change_submits=change_submits, enable_events=enable_events, font=font, pad=pad, key=key, k=k, metadata=metadata) @@ -10876,36 +10747,36 @@ def Save(button_text='Save', size=(None, None), s=(None, None), auto_size_button disabled=False, tooltip=None, font=None, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Save') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Save') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -10917,36 +10788,36 @@ def Submit(button_text='Submit', size=(None, None), s=(None, None), auto_size_bu bind_return_key=True, tooltip=None, font=None, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Submit') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Submit') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -10959,36 +10830,36 @@ def Open(button_text='Open', size=(None, None), s=(None, None), auto_size_button bind_return_key=True, tooltip=None, font=None, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Open') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Open') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11000,36 +10871,36 @@ def OK(button_text='OK', size=(None, None), s=(None, None), auto_size_button=Non bind_return_key=True, tooltip=None, font=None, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'OK') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'OK') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11041,36 +10912,36 @@ def Ok(button_text='Ok', size=(None, None), s=(None, None), auto_size_button=Non bind_return_key=True, tooltip=None, font=None, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Ok') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Ok') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11082,35 +10953,35 @@ def Cancel(button_text='Cancel', size=(None, None), s=(None, None), auto_size_bu tooltip=None, font=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Cancel') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Cancel') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11122,35 +10993,35 @@ def Quit(button_text='Quit', size=(None, None), s=(None, None), auto_size_button font=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Quit') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Quit') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11162,35 +11033,35 @@ def Exit(button_text='Exit', size=(None, None), s=(None, None), auto_size_button font=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Exit') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Exit') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11202,35 +11073,35 @@ def Yes(button_text='Yes', size=(None, None), s=(None, None), auto_size_button=N font=None, bind_return_key=True, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Yes') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Yes') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11242,35 +11113,35 @@ def No(button_text='No', size=(None, None), s=(None, None), auto_size_button=Non font=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'No') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'No') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11282,35 +11153,35 @@ def Help(button_text='Help', size=(None, None), s=(None, None), auto_size_button tooltip=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = 'Help') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = 'Help') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=button_color, font=font, disabled=disabled, @@ -11322,35 +11193,35 @@ def Debug(button_text='', size=(None, None), s=(None, None), auto_size_button=No tooltip=None, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button (Default value = '') - :type button_text: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button (Default value = '') + :type button_text: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_SHOW_DEBUGGER, tooltip=tooltip, size=size, s=s, auto_size_button=auto_size_button, button_color=theme_button_color(), font=font, disabled=disabled, @@ -11364,44 +11235,44 @@ def SimpleButton(button_text, image_filename=None, image_data=None, image_size=( font=None, bind_return_key=False, disabled=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button - :type button_text: (str) - :param image_filename: image filename if there is a button image - :type image_filename: image filename if there is a button image - :param image_data: in-RAM image to be displayed on button - :type image_data: in-RAM image to be displayed on button - :param image_size: image size (O.K.) - :type image_size: (Default = (None)) - :param image_subsample:amount to reduce the size of the image - :type image_subsample: amount to reduce the size of the image - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button + :type button_text: (str) + :param image_filename: image filename if there is a button image + :type image_filename: image filename if there is a button image + :param image_data: in-RAM image to be displayed on button + :type image_data: in-RAM image to be displayed on button + :param image_size: image size (O.K.) + :type image_size: (Default = (None)) + :param image_subsample: amount to reduce the size of the image + :type image_subsample: amount to reduce the size of the image + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_CLOSES_WIN, image_filename=image_filename, image_data=image_data, image_size=image_size, image_subsample=image_subsample, @@ -11416,44 +11287,44 @@ def CloseButton(button_text, image_filename=None, image_data=None, image_size=(N bind_return_key=False, disabled=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button - :type button_text: (str) - :param image_filename: image filename if there is a button image - :type image_filename: image filename if there is a button image - :param image_data: in-RAM image to be displayed on button - :type image_data: in-RAM image to be displayed on button - :param image_size: image size (O.K.) - :type image_size: (Default = (None)) - :param image_subsample:amount to reduce the size of the image - :type image_subsample: amount to reduce the size of the image - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button + :type button_text: (str) + :param image_filename: image filename if there is a button image + :type image_filename: image filename if there is a button image + :param image_data: in-RAM image to be displayed on button + :type image_data: in-RAM image to be displayed on button + :param image_size: image size (O.K.) + :type image_size: (Default = (None)) + :param image_subsample: amount to reduce the size of the image + :type image_subsample: amount to reduce the size of the image + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_CLOSES_WIN, image_filename=image_filename, image_data=image_data, image_size=image_size, image_subsample=image_subsample, @@ -11470,46 +11341,46 @@ def ReadButton(button_text, image_filename=None, image_data=None, image_size=(No border_width=None, tooltip=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, font=None, bind_return_key=False, disabled=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button - :type button_text: (str) - :param image_filename: image filename if there is a button image - :type image_filename: image filename if there is a button image - :param image_data: in-RAM image to be displayed on button - :type image_data: in-RAM image to be displayed on button - :param image_size: image size (O.K.) - :type image_size: (Default = (None)) - :param image_subsample:amount to reduce the size of the image - :type image_subsample: amount to reduce the size of the image - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button + :type button_text: (str) + :param image_filename: image filename if there is a button image + :type image_filename: image filename if there is a button image + :param image_data: in-RAM image to be displayed on button + :type image_data: in-RAM image to be displayed on button + :param image_size: image size (O.K.) + :type image_size: (Default = (None)) + :param image_subsample: amount to reduce the size of the image + :type image_subsample: amount to reduce the size of the image + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param focus: if focus should be set to this - :type focus: idk_yetReally - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param border_width: width of border around element - :type border_width: (int) - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: Button created - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param focus: if focus should be set to this + :type focus: idk_yetReally + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param border_width: width of border around element + :type border_width: (int) + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: Button created + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_READ_FORM, image_filename=image_filename, @@ -11529,46 +11400,46 @@ def RealtimeButton(button_text, image_filename=None, image_data=None, image_size font=None, disabled=False, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button - :type button_text: (str) - :param image_filename: image filename if there is a button image - :type image_filename: image filename if there is a button image - :param image_data: in-RAM image to be displayed on button - :type image_data: in-RAM image to be displayed on button - :param image_size: image size (O.K.) - :type image_size: (Default = (None)) - :param image_subsample:amount to reduce the size of the image - :type image_subsample: amount to reduce the size of the image - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button + :type button_text: (str) + :param image_filename: image filename if there is a button image + :type image_filename: image filename if there is a button image + :param image_data: in-RAM image to be displayed on button + :type image_data: in-RAM image to be displayed on button + :param image_size: image size (O.K.) + :type image_size: (Default = (None)) + :param image_subsample: amount to reduce the size of the image + :type image_subsample: amount to reduce the size of the image + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :type focus: (bool) - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param border_width: width of border around element - :type border_width: (int) - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: Button created - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :type focus: (bool) + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param border_width: width of border around element + :type border_width: (int) + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: Button created + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_REALTIME, image_filename=image_filename, image_data=image_data, image_size=image_size, image_subsample=image_subsample, @@ -11583,46 +11454,46 @@ def DummyButton(button_text, image_filename=None, image_data=None, image_size=(N disabled=False, bind_return_key=False, focus=False, pad=None, key=None, k=None, metadata=None): """ - :param button_text: text in the button - :type button_text: (str) - :param image_filename: image filename if there is a button image - :type image_filename: image filename if there is a button image - :param image_data: in-RAM image to be displayed on button - :type image_data: in-RAM image to be displayed on button - :param image_size: image size (O.K.) - :type image_size: (Default = (None)) - :param image_subsample:amount to reduce the size of the image - :type image_subsample: amount to reduce the size of the image - :param border_width: width of border around element - :type border_width: (int) - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button + :type button_text: (str) + :param image_filename: image filename if there is a button image + :type image_filename: image filename if there is a button image + :param image_data: in-RAM image to be displayed on button + :type image_data: in-RAM image to be displayed on button + :param image_size: image size (O.K.) + :type image_size: (Default = (None)) + :param image_subsample: amount to reduce the size of the image + :type image_subsample: amount to reduce the size of the image + :param border_width: width of border around element + :type border_width: (int) + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: if focus should be set to this - :type focus: (bool) - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: if focus should be set to this + :type focus: (bool) + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_CLOSES_WIN_ONLY, image_filename=image_filename, image_data=image_data, image_size=image_size, image_subsample=image_subsample, @@ -11636,71 +11507,72 @@ def CalendarButton(button_text, target=(ThisRow, -1), close_when_date_chosen=Tru image_filename=None, image_data=None, image_size=(None, None), image_subsample=None, tooltip=None, border_width=None, size=(None, None), s=(None, None), auto_size_button=None, button_color=None, disabled=False, font=None, bind_return_key=False, focus=False, pad=None, enable_events=None, - key=None, k=None, locale=None, format='%Y-%m-%d %H:%M:%S', begin_at_sunday_plus=0, month_names=None, day_abbreviations=None, title='Choose Date', + key=None, k=None, locale=None, format='%Y-%m-%d %H:%M:%S', begin_at_sunday_plus=0, month_names=None, day_abbreviations=None, + title='Choose Date', no_titlebar=True, location=(None, None), metadata=None): """ Button that will show a calendar chooser window. Fills in the target element with result - :param button_text: text in the button - :type button_text: (str) - :param target: Key or "coordinate" (see docs) of target element - :type target: (int, int) | Any + :param button_text: text in the button + :type button_text: (str) + :param target: Key or "coordinate" (see docs) of target element + :type target: (int, int) | Any :param close_when_date_chosen: (Default = True) - :type close_when_date_chosen: bool - :param default_date_m_d_y: Beginning date to show - :type default_date_m_d_y: (int, int or None, int) - :param image_filename: image filename if there is a button image - :type image_filename: image filename if there is a button image - :param image_data: in-RAM image to be displayed on button - :type image_data: in-RAM image to be displayed on button - :param image_size: image size (O.K.) - :type image_size: (Default = (None)) - :param image_subsample: amount to reduce the size of the image - :type image_subsample: amount to reduce the size of the image - :param tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param border_width: width of border around element - :type border_width: width of border around element - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) - :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: bool - :param focus: if focus should be set to this - :type focus: bool - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param locale: defines the locale used to get day names - :type locale: str - :param format: formats result using this strftime format - :type format: str - :param month_names: optional list of month names to use (should be 12 items) - :type month_names: List[str] - :param day_abbreviations: optional list of abbreviations to display as the day of week - :type day_abbreviations: List[str] - :param title: Title shown on the date chooser window - :type title: (str) - :param no_titlebar: if True no titlebar will be shown on the date chooser window - :type no_titlebar: bool - :param location: Location on the screen (x,y) to show the calendar popup window - :type location: (int, int) - :param metadata: Anything you want to store along with this button - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type close_when_date_chosen: bool + :param default_date_m_d_y: Beginning date to show + :type default_date_m_d_y: (int, int or None, int) + :param image_filename: image filename if there is a button image + :type image_filename: image filename if there is a button image + :param image_data: in-RAM image to be displayed on button + :type image_data: in-RAM image to be displayed on button + :param image_size: image size (O.K.) + :type image_size: (Default = (None)) + :param image_subsample: amount to reduce the size of the image + :type image_subsample: amount to reduce the size of the image + :param tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param border_width: width of border around element + :type border_width: width of border around element + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) + :param auto_size_button: True if button size is determined by button text + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: bool + :param focus: if focus should be set to this + :type focus: bool + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param locale: defines the locale used to get day names + :type locale: str + :param format: formats result using this strftime format + :type format: str + :param month_names: optional list of month names to use (should be 12 items) + :type month_names: List[str] + :param day_abbreviations: optional list of abbreviations to display as the day of week + :type day_abbreviations: List[str] + :param title: Title shown on the date chooser window + :type title: (str) + :param no_titlebar: if True no titlebar will be shown on the date chooser window + :type no_titlebar: bool + :param location: Location on the screen (x,y) to show the calendar popup window + :type location: (int, int) + :param metadata: Anything you want to store along with this button + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ button = Button(button_text=button_text, button_type=BUTTON_TYPE_CALENDAR_CHOOSER, target=target, image_filename=image_filename, image_data=image_data, image_size=image_size, @@ -11728,49 +11600,49 @@ def ColorChooserButton(button_text, target=(ThisRow, -1), image_filename=None, i key=None, k=None, metadata=None): """ - :param button_text: text in the button - :type button_text: (str) - :param target: key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button - :type target: str | (int, int) - :type image_filename: (str) - :param image_filename: image filename if there is a button image. GIFs and PNGs only. - :type image_filename: (str) - :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data - :type image_data: bytes | str - :param image_size: Size of the image in pixels (width, height) - :type image_size: (int, int) - :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 tooltip: text, that will appear when mouse hovers over the element - :type tooltip: (str) - :param border_width: width of border around element - :type border_width: (int) - :param size: (w,h) w=characters-wide, h=rows-high - :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 - :type s: (int, int) | (None, None) + :param button_text: text in the button + :type button_text: (str) + :param target: key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button + :type target: str | (int, int) + :type image_filename: (str) + :param image_filename: image filename if there is a button image. GIFs and PNGs only. + :type image_filename: (str) + :param image_data: Raw or Base64 representation of the image to put on button. Choose either filename or data + :type image_data: bytes | str + :param image_size: Size of the image in pixels (width, height) + :type image_size: (int, int) + :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 tooltip: text, that will appear when mouse hovers over the element + :type tooltip: (str) + :param border_width: width of border around element + :type border_width: (int) + :param size: (w,h) w=characters-wide, h=rows-high + :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 + :type s: (int, int) | (None, None) :param auto_size_button: True if button size is determined by button text - :type auto_size_button: (bool) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param disabled: set disable state for element (Default = False) - :type disabled: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event - :type bind_return_key: (bool) - :param focus: Determines if initial focus should go to this element. - :type focus: (bool) - :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) - :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) - :param key: key for uniquely identify this element (for window.find_element) - :type key: str | int | tuple | object - :param k: Same as the Key. You can use either k or key. Which ever is set will be used. - :type k: str | int | tuple | object - :param metadata: User metadata that can be set to ANYTHING - :type metadata: (Any) - :return: returns a button - :rtype: (Button) + :type auto_size_button: (bool) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param disabled: set disable state for element (Default = False) + :type disabled: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event + :type bind_return_key: (bool) + :param focus: Determines if initial focus should go to this element. + :type focus: (bool) + :param pad: Amount of padding to put around element in pixels (left/right, top/bottom) + :type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) + :param key: key for uniquely identify this element (for window.find_element) + :type key: str | int | tuple | object + :param k: Same as the Key. You can use either k or key. Which ever is set will be used. + :type k: str | int | tuple | object + :param metadata: User metadata that can be set to ANYTHING + :type metadata: (Any) + :return: returns a button + :rtype: (Button) """ return Button(button_text=button_text, button_type=BUTTON_TYPE_COLOR_CHOOSER, target=target, image_filename=image_filename, image_data=image_data, image_size=image_size, @@ -11779,8 +11651,6 @@ def ColorChooserButton(button_text, target=(ThisRow, -1), image_filename=None, i bind_return_key=bind_return_key, focus=focus, pad=pad, key=key, k=k, metadata=metadata) - - ##################################### ----- BUTTON Functions ------ ################################################## def button_color_to_tuple(color_tuple_or_string, default=(None, None)): @@ -11792,20 +11662,21 @@ def button_color_to_tuple(color_tuple_or_string, default=(None, None)): :param color_tuple_or_string: Button color - tuple or a simplied color string with word "on" between color :type color_tuple_or_string: str | (str, str) - :param default: The 2 colors to use if there is a problem. Otherwise defaults to the theme's button color - :type default: (str, str) - :return: (str | (str, str) - :rtype: str | (str, str) + :param default: The 2 colors to use if there is a problem. Otherwise defaults to the theme's button color + :type default: (str, str) + :return: (str | (str, str) + :rtype: str | (str, str) """ if default == (None, None): color_tuple = _simplified_dual_color_to_tuple(color_tuple_or_string, default=theme_button_color()) elif color_tuple_or_string == COLOR_SYSTEM_DEFAULT: - color_tuple = (COLOR_SYSTEM_DEFAULT,COLOR_SYSTEM_DEFAULT) + color_tuple = (COLOR_SYSTEM_DEFAULT, COLOR_SYSTEM_DEFAULT) else: color_tuple = _simplified_dual_color_to_tuple(color_tuple_or_string, default=default) return color_tuple + def _simplified_dual_color_to_tuple(color_tuple_or_string, default=(None, None)): """ Convert a color tuple or color string into 2 components and returns them as a tuple @@ -11814,10 +11685,10 @@ def _simplified_dual_color_to_tuple(color_tuple_or_string, default=(None, None)) :param color_tuple_or_string: Button color - tuple or a simplied color string with word "on" between color :type color_tuple_or_string: str | (str, str} | (None, None) - :param default: The 2 colors to use if there is a problem. Otherwise defaults to the theme's button color - :type default: (str, str) - :return: (str | (str, str) - :rtype: str | (str, str) + :param default: The 2 colors to use if there is a problem. Otherwise defaults to the theme's button color + :type default: (str, str) + :return: (str | (str, str) + :rtype: str | (str, str) """ if color_tuple_or_string is None or color_tuple_or_string == (None, None): color_tuple_or_string = default @@ -11840,7 +11711,7 @@ def _simplified_dual_color_to_tuple(color_tuple_or_string, default=(None, None)) elif len(split_colors) == 1: split_colors = color_tuple_or_string.split('on') if len(split_colors) == 1: - text_color, background_color = default[0], split_colors[0].strip() + text_color, background_color = default[0], split_colors[0].strip() else: split_colors = split_colors[0].strip(), split_colors[1].strip() text_color = split_colors[0] or default[0] @@ -11869,8 +11740,6 @@ def _simplified_dual_color_to_tuple(color_tuple_or_string, default=(None, None)) return (text_color, background_color) - - ##################################### ----- RESULTS ------ ################################################## def AddToReturnDictionary(form, element, value): @@ -12056,7 +11925,7 @@ def _BuildResultsForSubform(form, initialize_only, top_level_form): except: value = 0 elif element.Type == ELEM_TYPE_INPUT_MULTILINE: - if element.WriteOnly: # if marked as "write only" when created, then don't include with the values being returned + if element.WriteOnly: # if marked as "write only" when created, then don't include with the values being returned continue try: value = element.TKText.get(1.0, tk.END) @@ -12084,7 +11953,7 @@ def _BuildResultsForSubform(form, initialize_only, top_level_form): value = element.MenuItemChosen element.MenuItemChosen = None elif element.Type == ELEM_TYPE_BUTTONMENU: - element = element # type: ButtonMenu + element = element # type: ButtonMenu value = element.MenuItemChosen if element.part_of_custom_menubar: if element.MenuItemChosen is not None: @@ -12106,7 +11975,9 @@ def _BuildResultsForSubform(form, initialize_only, top_level_form): value = None # if an input type element, update the results - if element.Type not in (ELEM_TYPE_BUTTON, ELEM_TYPE_TEXT, ELEM_TYPE_IMAGE, ELEM_TYPE_OUTPUT, ELEM_TYPE_PROGRESS_BAR, ELEM_TYPE_COLUMN, ELEM_TYPE_FRAME, ELEM_TYPE_SEPARATOR, ELEM_TYPE_TAB): + if element.Type not in ( + ELEM_TYPE_BUTTON, ELEM_TYPE_TEXT, ELEM_TYPE_IMAGE, ELEM_TYPE_OUTPUT, ELEM_TYPE_PROGRESS_BAR, ELEM_TYPE_COLUMN, ELEM_TYPE_FRAME, ELEM_TYPE_SEPARATOR, + ELEM_TYPE_TAB): if not (element.Type == ELEM_TYPE_BUTTONMENU and element.part_of_custom_menubar): AddToReturnList(form, value) AddToReturnDictionary(top_level_form, element, value) @@ -12146,7 +12017,6 @@ def _BuildResultsForSubform(form, initialize_only, top_level_form): else: form.ReturnValues = event, form.ReturnValuesDictionary - return form.ReturnValues @@ -12154,12 +12024,12 @@ def fill_form_with_values(window, values_dict): """ Fills a window with values provided in a values dictionary { element_key : new_value } - :param window: The window object to fill - :type window: (Window) + :param window: The window object to fill + :type window: (Window) :param values_dict: A dictionary with element keys as key and value is values parm for Update call - :type values_dict: (Dict[Any, Any]) - :return: None - :rtype: None + :type values_dict: (Dict[Any, Any]) + :return: None + :rtype: None """ for element_key in values_dict: @@ -12174,9 +12044,9 @@ def _FindElementWithFocusInSubForm(form): Searches through a "sub-form" (can be a window or container) for the current element with focus :param form: a Window, Column, Frame, or TabGroup (container elements) - :type form: container elements - :return: Element - :rtype: Element | None + :type form: container elements + :return: Element + :rtype: Element | None """ for row_num, row in enumerate(form.Rows): for col_num, element in enumerate(row): @@ -12226,15 +12096,15 @@ def _FindElementWithFocusInSubForm(form): def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False, right_click_menu=False): """ Only to be used internally. Not user callable - :param top_menu: ??? - :type top_menu: ??? + :param top_menu: ??? + :type top_menu: ??? :param sub_menu_info: ??? - :param element: ??? - :type element: idk_yetReally - :param is_sub_menu: (Default = False) - :type is_sub_menu: (bool) - :param skip: (Default = False) - :type skip: (bool) + :param element: ??? + :type element: idk_yetReally + :param is_sub_menu: (Default = False) + :type is_sub_menu: (bool) + :param skip: (Default = False) + :type skip: (bool) """ return_val = None @@ -12253,7 +12123,7 @@ def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False, item_without_key = sub_menu_info if item_without_key[0] == MENU_DISABLED_CHARACTER: - top_menu.add_command(label=item_without_key[len(MENU_DISABLED_CHARACTER):], underline=pos-1, + top_menu.add_command(label=item_without_key[len(MENU_DISABLED_CHARACTER):], underline=pos - 1, command=lambda: element._MenuItemChosenCallback(sub_menu_info)) top_menu.entryconfig(item_without_key[len(MENU_DISABLED_CHARACTER):], state='disabled') else: @@ -12307,6 +12177,7 @@ def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False, i += 1 return return_val + # 888 888 d8b 888 # 888 888 Y8P 888 # 888 888 888 @@ -12328,9 +12199,11 @@ def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False, """ + # Chr0nic || This is probably *very* bad practice. But it works. Simple, but it works... class VarHolder(object): canvas_holder = None + def __init__(self): self.canvas_holder = None @@ -12354,7 +12227,6 @@ def _fixed_map(style, style_name, option, highlight_colors=(None, None)): new_map = custom_map + default_map return new_map - new_map = [elm for elm in style.map(style_name, query_opt=option) if elm[:2] != ('!disabled', '!selected')] if option == 'background': @@ -12363,6 +12235,7 @@ def _fixed_map(style, style_name, option, highlight_colors=(None, None)): new_map.append(('selected', highlight_colors[0] if highlight_colors[0] is not None else ALTERNATE_TABLE_AND_TREE_SELECTED_ROW_COLORS[0])) return new_map + def _add_right_click_menu(element, toplevel_form): if element.RightClickMenu == MENU_RIGHT_CLICK_DISABLED: return @@ -12392,12 +12265,12 @@ def _add_right_click_menu(element, toplevel_form): def PackFormIntoFrame(form, containing_frame, toplevel_form): """ - :param form: a window class - :type form: (Window) + :param form: a window class + :type form: (Window) :param containing_frame: ??? - :type containing_frame: ??? - :param toplevel_form: ??? - :type toplevel_form: (Window) + :type containing_frame: ??? + :param toplevel_form: ??? + :type toplevel_form: (Window) """ @@ -12473,7 +12346,6 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # '\nValid choices include: {}'.format(style.theme_names())) return False - def _add_right_click_menu(element): if element.RightClickMenu == MENU_RIGHT_CLICK_DISABLED: return @@ -12546,7 +12418,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # Set foreground color text_color = element.TextColor elementpad = element.Pad if element.Pad is not None else toplevel_form.ElementPadding - element.pad_used = elementpad # store the value used back into the element + element.pad_used = elementpad # store the value used back into the element # Determine Element size element_size = element.Size if (element_size == (None, None) and element_type not in ( @@ -12622,7 +12494,6 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # side = tk.LEFT # row_justify = element.Justification - element.Widget = element.TKColFrame expand = True @@ -12639,10 +12510,10 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): row_should_expand = True else: fill = tk.NONE - expand=False + expand = False if element.VerticalAlignment is not None: - anchor = tk.CENTER # Default to center if a bad choice is made + anchor = tk.CENTER # Default to center if a bad choice is made if element.VerticalAlignment.lower().startswith('t'): anchor = tk.N @@ -12792,7 +12663,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): tkbutton.bind('', element.ButtonReleaseCallBack) tkbutton.bind('', element.ButtonPressCallBack) if bc != (None, None) and COLOR_SYSTEM_DEFAULT not in bc: - tkbutton.config(foreground=bc[0], background=bc[1]) + tkbutton.config(foreground=bc[0], background=bc[1]) else: if bc[0] != COLOR_SYSTEM_DEFAULT: tkbutton.config(foreground=bc[0]) @@ -12921,10 +12792,9 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): tkbutton.bind('', element.ButtonReleaseCallBack) tkbutton.bind('', element.ButtonPressCallBack) - style_name = str(element.Key) + 'custombutton.TButton' button_style = ttk.Style() - if _valid_theme(button_style,toplevel_form.TtkTheme): + if _valid_theme(button_style, toplevel_form.TtkTheme): button_style.theme_use(toplevel_form.TtkTheme) button_style.configure(style_name, font=font) @@ -12942,8 +12812,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): button_style.configure(style_name, borderwidth=bd) button_style.configure(style_name, justify=tk.CENTER) - - if element.MouseOverColors[1] not in (COLOR_SYSTEM_DEFAULT, None) : + if element.MouseOverColors[1] not in (COLOR_SYSTEM_DEFAULT, None): button_style.map(style_name, background=[('active', element.MouseOverColors[1])]) if element.MouseOverColors[0] not in (COLOR_SYSTEM_DEFAULT, None): button_style.map(style_name, foreground=[('active', element.MouseOverColors[0])]) @@ -12954,7 +12823,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): button_style.map(style_name, background=[('disabled', element.DisabledButtonColor[1])]) if height > 1: - button_style.configure(style_name, padding=height * _char_width_in_pixels(font)) # should this be height instead? + button_style.configure(style_name, padding=height * _char_width_in_pixels(font)) # should this be height instead? wraplen = tkbutton.winfo_reqwidth() # width of widget in Pixels if width != 0: button_style.configure(style_name, wraplength=wraplen) # set wrap to width of widget @@ -13152,7 +13021,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): element.TKStringVar = tk.StringVar() style_name = 'TCombobox' s = ttk.Style() - if _valid_theme(s,toplevel_form.TtkTheme): + if _valid_theme(s, toplevel_form.TtkTheme): s.theme_use(toplevel_form.TtkTheme) # s.theme_use('default') @@ -13338,7 +13207,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): if element.no_scrollbar: element.TKText = element.Widget = tk.Text(tk_row_frame, width=width, height=height, wrap='word', bd=bd, font=font, relief=RELIEF_SUNKEN) else: - element.TKText = element.Widget = tk.scrolledtext.ScrolledText(tk_row_frame, width=width, height=height, wrap='word', bd=bd, font=font, relief=RELIEF_SUNKEN) + element.TKText = element.Widget = tk.scrolledtext.ScrolledText(tk_row_frame, width=width, height=height, wrap='word', bd=bd, font=font, + relief=RELIEF_SUNKEN) if element.DefaultText: element.TKText.insert(1.0, element.DefaultText) # set the default text element.TKText.config(highlightthickness=0) @@ -13374,7 +13244,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): row_should_expand = True else: fill = tk.NONE - expand=False + expand = False element.TKText.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1], fill=fill, expand=expand) if element.visible is False: @@ -13405,7 +13275,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # row_should_expand = True # ------------------------- CHECKBOX pleacement element ------------------------- # elif element_type == ELEM_TYPE_INPUT_CHECKBOX: - element = element # type: Checkbox + element = element # type: Checkbox width = 0 if auto_size_text else element_size[0] default_value = element.InitialState element.TKIntVar = tk.IntVar() @@ -13425,7 +13295,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): element.TKCheckbutton.configure(state='disable') if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT: element.TKCheckbutton.configure(background=element.BackgroundColor) - element.TKCheckbutton.configure(selectcolor=element.CheckboxBackgroundColor) # The background of the checkbox + element.TKCheckbutton.configure(selectcolor=element.CheckboxBackgroundColor) # The background of the checkbox element.TKCheckbutton.configure(activebackground=element.BackgroundColor) if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT: element.TKCheckbutton.configure(fg=text_color) @@ -13554,7 +13424,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # ------------------------- OUTPUT placement element ------------------------- # elif element_type == ELEM_TYPE_OUTPUT: - element = element # type: Output + element = element # type: Output width, height = element_size element._TKOut = element.Widget = TKOutput(tk_row_frame, width=width, height=height, bd=border_depth, background_color=element.BackgroundColor, @@ -13580,7 +13450,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): photo = None # print('*ERROR laying out form.... Image Element has no image specified*') except Exception as e: - photo=None + photo = None _error_popup_with_traceback('Your Window has an Image Element with a 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), @@ -13665,9 +13535,10 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): elif element_type == ELEM_TYPE_MENUBAR: element = element # type: MenuBar menu_def = element.MenuDefinition - element.TKMenu = element.Widget = tk.Menu(toplevel_form.TKroot, tearoff=element.Tearoff, tearoffcommand=element._tearoff_menu_callback) # create the menubar + element.TKMenu = element.Widget = tk.Menu(toplevel_form.TKroot, tearoff=element.Tearoff, + tearoffcommand=element._tearoff_menu_callback) # create the menubar menubar = element.TKMenu - if font is not None: # if a font is used, make sure it's saved in the element + if font is not None: # if a font is used, make sure it's saved in the element element.Font = font for menu_entry in menu_def: baritem = tk.Menu(menubar, tearoff=element.Tearoff, tearoffcommand=element._tearoff_menu_callback) @@ -13686,7 +13557,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): 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-1) + underline=pos - 1) menubar.entryconfig(menu_entry[0][len(MENU_DISABLED_CHARACTER):], state='disabled') else: menubar.add_cascade(label=menu_entry[0], menu=baritem, underline=pos) @@ -13702,7 +13573,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): PackFormIntoFrame(element, labeled_frame, toplevel_form) if element.VerticalAlignment is not None: - anchor = tk.CENTER # Default to center if a bad choice is made + anchor = tk.CENTER # Default to center if a bad choice is made if element.VerticalAlignment.lower().startswith('t'): anchor = tk.N if element.VerticalAlignment.lower().startswith('c'): @@ -13910,13 +13781,14 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): treeview = element.TKTreeview if element.DisplayRowNumbers: treeview.heading(element.RowHeaderText, text=element.RowHeaderText) # make a dummy heading - treeview.column(element.RowHeaderText, width=_string_width_in_pixels(font, element.RowHeaderText)+10, minwidth=10, anchor=anchor, stretch=0) + treeview.column(element.RowHeaderText, width=_string_width_in_pixels(font, element.RowHeaderText) + 10, minwidth=10, anchor=anchor, + stretch=0) 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)) * _char_width_in_pixels(font) + width = max(column_widths[i], len(heading)) * _char_width_in_pixels(font) else: try: width = element.ColumnWidths[i] * _char_width_in_pixels(font) @@ -13956,13 +13828,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): else: table_style.configure(style_name, rowheight=_char_height_in_pixels(font)) if element.HeaderTextColor is not None and element.HeaderTextColor != COLOR_SYSTEM_DEFAULT: - table_style.configure(style_name+'.Heading', foreground=element.HeaderTextColor) + table_style.configure(style_name + '.Heading', foreground=element.HeaderTextColor) if element.HeaderBackgroundColor is not None and element.HeaderBackgroundColor != COLOR_SYSTEM_DEFAULT: - table_style.configure(style_name+'.Heading', background=element.HeaderBackgroundColor) + table_style.configure(style_name + '.Heading', background=element.HeaderBackgroundColor) if element.HeaderFont is not None: - table_style.configure(style_name+'.Heading', font=element.HeaderFont) + table_style.configure(style_name + '.Heading', font=element.HeaderFont) else: - table_style.configure(style_name+'.Heading', font=font) + table_style.configure(style_name + '.Heading', font=font) table_style.configure(style_name, font=font) treeview.configure(style=style_name) # scrollable_frame.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1], expand=True, fill='both') @@ -14033,7 +13905,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): width = element.ColumnWidths[i] except: width = element.DefaultColumnWidth - treeview.column(heading, width=width * _char_width_in_pixels(font)+ 10, anchor=anchor) + treeview.column(heading, width=width * _char_width_in_pixels(font) + 10, anchor=anchor) + def add_treeview_data(node): """ @@ -14083,13 +13956,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): if element.SelectedRowColors[0] is not None: tree_style.map(style_name, foreground=_fixed_map(tree_style, style_name, 'foreground', element.SelectedRowColors)) if element.HeaderTextColor is not None and element.HeaderTextColor != COLOR_SYSTEM_DEFAULT: - tree_style.configure(style_name+'.Heading', foreground=element.HeaderTextColor) + tree_style.configure(style_name + '.Heading', foreground=element.HeaderTextColor) if element.HeaderBackgroundColor is not None and element.HeaderBackgroundColor != COLOR_SYSTEM_DEFAULT: - tree_style.configure(style_name+'.Heading', background=element.HeaderBackgroundColor) + tree_style.configure(style_name + '.Heading', background=element.HeaderBackgroundColor) if element.HeaderFont is not None: - tree_style.configure(style_name+'.Heading', font=element.HeaderFont) + tree_style.configure(style_name + '.Heading', font=element.HeaderFont) else: - tree_style.configure(style_name+'.Heading', font=font) + tree_style.configure(style_name + '.Heading', font=font) tree_style.configure(style_name, font=font) if element.RowHeight: tree_style.configure(style_name, rowheight=element.RowHeight) @@ -14238,7 +14111,6 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): # AddMenuItem(top_menu, menu[1], form) # tk_row_frame.bind('', form._RightClickMenuCallback) - tk_row_frame.pack(side=tk.TOP, anchor=anchor, padx=0, pady=0, expand=row_should_expand, fill=row_fill_direction) if form.BackgroundColor is not None and form.BackgroundColor != COLOR_SYSTEM_DEFAULT: @@ -14248,7 +14120,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form): def _no_titlebar_setup(window): - # for the Raspberry Pi. Need to set the attributes here, prior to the building of the window + # for the Raspberry Pi. Need to set the attributes here, prior to the building of the window try: if window.NoTitleBar: if running_linux(): @@ -14278,8 +14150,6 @@ def _convert_window_to_tk(window): window.TKroot.configure(padx=window.Margins[0], pady=window.Margins[1]) - - # ....................................... DONE creating and laying out window ..........................# if window._Size != (None, None): master.geometry("%sx%s" % (window._Size[0], window._Size[1])) @@ -14305,7 +14175,7 @@ def _convert_window_to_tk(window): window.config_last_location = (int(x), (int(y))) window.TKroot.x = int(x) window.TKroot.y = int(y) - window.starting_window_position = (int(x), (int(y))) + window.starting_window_position = (int(x), (int(y))) master.update_idletasks() # don't forget _no_titlebar_setup(window) @@ -14321,7 +14191,7 @@ def StartupTK(window): "porting layer" that will change depending on the GUI framework PySimpleGUI is running on top of. :param window: you window object - :type window: (Window) + :type window: (Window) """ window = window # type: Window @@ -14371,7 +14241,6 @@ def StartupTK(window): # so going ahead and doing it for all platforms, in addition to doing it after the window is packed _no_titlebar_setup(window) - if not window.Resizable: root.resizable(False, False) @@ -14388,7 +14257,6 @@ def StartupTK(window): # root.bind('', MyFlexForm.DestroyedCallback()) _convert_window_to_tk(window) - # Make moveable window if (window.GrabAnywhere is not False and not ( window.NonBlocking and window.GrabAnywhere is not True)): @@ -14461,8 +14329,6 @@ def StartupTK(window): return - - def _set_icon_for_tkinter_window(root, icon=None, pngbase64=None): """ At the moment, this function is only used by the get_filename or folder with the no_window option set. @@ -14473,12 +14339,12 @@ def _set_icon_for_tkinter_window(root, icon=None, pngbase64=None): * bytes object * BASE64 encoded file held in a variable - :param root: The window being modified - :type root: (tk.Tk or tk.TopLevel) - :param icon: Filename or bytes object - :type icon: (str) + :param root: The window being modified + :type root: (tk.Tk or tk.TopLevel) + :param icon: Filename or bytes object + :type icon: (str) :param pngbase64: Base64 encoded image - :type pngbase64: (str) + :type pngbase64: (str) """ if type(icon) is bytes or pngbase64 is not None: @@ -14565,35 +14431,36 @@ class QuickMeter(object): active_meters = {} exit_reasons = {} - def __init__(self, title, current_value, max_value, key, *args, orientation='v', bar_color=(None, None), button_color=(None, None), size=DEFAULT_PROGRESS_BAR_SIZE, border_width=None, grab_anywhere=False, no_titlebar=False, keep_on_top=False): + def __init__(self, title, current_value, max_value, key, *args, orientation='v', bar_color=(None, None), button_color=(None, None), + size=DEFAULT_PROGRESS_BAR_SIZE, border_width=None, grab_anywhere=False, no_titlebar=False, keep_on_top=False): """ - :param title: text to display in element - :type title: (str) + :param title: text to display in element + :type title: (str) :param current_value: current value - :type current_value: (int) - :param max_value: max value of QuickMeter - :type max_value: (int) - :param key: Used with window.find_element and with return values to uniquely identify this element - :type key: str | int | tuple | object - :param *args: stuff to output - :type *args: (Any) - :param orientation: 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') - :type orientation: (str) - :param bar_color: color of a bar line - :type bar_color: (str, str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param size: (w,h) w=characters-wide, h=rows-high (Default value = DEFAULT_PROGRESS_BAR_SIZE) - :type size: (int, int) + :type current_value: (int) + :param max_value: max value of QuickMeter + :type max_value: (int) + :param key: Used with window.find_element and with return values to uniquely identify this element + :type key: str | int | tuple | object + :param *args: stuff to output + :type *args: (Any) + :param orientation: 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') + :type orientation: (str) + :param bar_color: color of a bar line + :type bar_color: (str, str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param size: (w,h) w=characters-wide, h=rows-high (Default value = DEFAULT_PROGRESS_BAR_SIZE) + :type size: (int, int) :param border_width: width of border around element - :type border_width: (int) + :type border_width: (int) :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param no_titlebar: If True: window will be created without a titlebar - :type no_titlebar: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) + :type grab_anywhere: (bool) + :param no_titlebar: If True: window will be created without a titlebar + :type no_titlebar: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) """ self.start_time = datetime.datetime.utcnow() self.key = key @@ -14632,7 +14499,8 @@ class QuickMeter(object): col2 += [[T('', size=(30, 10), key='_STATS_')], [Cancel(button_color=self.button_color), Stretch()]] layout = [Column(col), Column(col2)] - self.window = Window(self.title, grab_anywhere=self.grab_anywhere, border_depth=self.border_width, no_titlebar=self.no_titlebar, disable_close=True, keep_on_top=self.keep_on_top) + self.window = Window(self.title, grab_anywhere=self.grab_anywhere, border_depth=self.border_width, no_titlebar=self.no_titlebar, disable_close=True, + keep_on_top=self.keep_on_top) self.window.Layout([layout]).Finalize() return self.window @@ -14683,39 +14551,41 @@ class QuickMeter(object): return self.stat_messages -def one_line_progress_meter(title, current_value, max_value, *args, key='OK for 1 meter', orientation='v', bar_color=(None, None), button_color=None, size=DEFAULT_PROGRESS_BAR_SIZE, border_width=None, grab_anywhere=False, no_titlebar=False, keep_on_top=False): +def one_line_progress_meter(title, current_value, max_value, *args, key='OK for 1 meter', orientation='v', bar_color=(None, None), button_color=None, + size=DEFAULT_PROGRESS_BAR_SIZE, border_width=None, grab_anywhere=False, no_titlebar=False, keep_on_top=False): """ - :param title: text to display in eleemnt - :type title: (str) + :param title: text to display in eleemnt + :type title: (str) :param current_value: current value - :type current_value: (int) - :param max_value: max value of QuickMeter - :type max_value: (int) - :param *args: stuff to output - :type *args: (Any) - :param key: Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters - :type key: str | int | tuple | object - :param orientation: 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') - :type orientation: (str) - :param bar_color: color of a bar line - :type bar_color: Tuple(str, str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param size: (w,h) w=characters-wide, h=rows-high (Default value = DEFAULT_PROGRESS_BAR_SIZE) - :type size: (int, int) - :param border_width: width of border around element - :type border_width: (int) + :type current_value: (int) + :param max_value: max value of QuickMeter + :type max_value: (int) + :param *args: stuff to output + :type *args: (Any) + :param key: Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters + :type key: str | int | tuple | object + :param orientation: 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') + :type orientation: (str) + :param bar_color: color of a bar line + :type bar_color: Tuple(str, str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param size: (w,h) w=characters-wide, h=rows-high (Default value = DEFAULT_PROGRESS_BAR_SIZE) + :type size: (int, int) + :param border_width: width of border around element + :type border_width: (int) :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param no_titlebar: If True: no titlebar will be shown on the window - :type no_titlebar: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :return: True if updated successfully. False if user closed the meter with the X or Cancel button - :rtype: (bool) + :type grab_anywhere: (bool) + :param no_titlebar: If True: no titlebar will be shown on the window + :type no_titlebar: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :return: True if updated successfully. False if user closed the meter with the X or Cancel button + :rtype: (bool) """ if key not in QuickMeter.active_meters: - meter = QuickMeter(title, current_value, max_value, key, *args, orientation=orientation, bar_color=bar_color, button_color=button_color, size=size, border_width=border_width, grab_anywhere=grab_anywhere, no_titlebar=no_titlebar, keep_on_top=keep_on_top) + meter = QuickMeter(title, current_value, max_value, key, *args, orientation=orientation, bar_color=bar_color, button_color=button_color, size=size, + border_width=border_width, grab_anywhere=grab_anywhere, no_titlebar=no_titlebar, keep_on_top=keep_on_top) QuickMeter.active_meters[key] = meter else: meter = QuickMeter.active_meters[key] @@ -14730,9 +14600,9 @@ def one_line_progress_meter_cancel(key='OK for 1 meter'): Cancels and closes a previously created One Line Progress Meter window :param key: Key used when meter was created - :type key: (Any) - :return: None - :rtype: None + :type key: (Any) + :return: None + :rtype: None """ try: meter = QuickMeter.active_meters[key] @@ -14746,9 +14616,9 @@ def one_line_progress_meter_cancel(key='OK for 1 meter'): def get_complimentary_hex(color): """ :param color: color string, like "#RRGGBB" - :type color: (str) - :return: color string, like "#RRGGBB" - :rtype: (str) + :type color: (str) + :return: color string, like "#RRGGBB" + :rtype: (str) """ # strip the # from the beginning @@ -14772,28 +14642,28 @@ class _DebugWin(): grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=True, resizable=True): """ - :param size: (w,h) w=characters-wide, h=rows-high - :type size: (int, int) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] + :param size: (w,h) w=characters-wide, h=rows-high + :type size: (int, int) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) + :type no_titlebar: (bool) :param no_button: show button - :type no_button: (bool) + :type no_button: (bool) :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) + :type grab_anywhere: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) + :param location: Location of upper left corner of the window + :type location: (int, int) :param do_not_reroute_stdout: bool value - :type do_not_reroute_stdout: (bool) - :param resizable: if True, makes the window resizble - :type resizable: (bool) - :rtype: (None) + :type do_not_reroute_stdout: (bool) + :param resizable: if True, makes the window resizble + :type resizable: (bool) + :rtype: (None) """ # Show a form that's a running counter self.size = size @@ -14807,20 +14677,20 @@ class _DebugWin(): self.resizable = resizable win_size = size if size != (None, None) else DEFAULT_DEBUG_WINDOW_SIZE - self.output_element = Multiline(size=win_size, autoscroll=True, auto_refresh=True, reroute_stdout=False if do_not_reroute_stdout else True, expand_x=True, expand_y=True, key='-MULTILINE-') + self.output_element = Multiline(size=win_size, autoscroll=True, auto_refresh=True, reroute_stdout=False if do_not_reroute_stdout else True, + expand_x=True, expand_y=True, key='-MULTILINE-') if no_button: self.layout = [[self.output_element]] else: - self.layout = [ [self.output_element], - [DummyButton('Quit'), Stretch()]] + self.layout = [[self.output_element], + [DummyButton('Quit'), Stretch()]] if no_titlebar and resizable: self.layout[-1] += [Sizegrip()] self.window = Window('Debug Window', self.layout, 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, finalize=False, resizable=resizable) + font=font or ('Courier New', 10), grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, finalize=False, resizable=resizable) return - def Print(self, *args, end=None, sep=None, text_color=None, background_color=None, erase_all=False, font=None): sepchar = sep if sep is not None else ' ' endchar = end if end is not None else '\n' @@ -14835,7 +14705,7 @@ class _DebugWin(): self.Close() self.__init__(size=self.size, location=self.location, font=self.font, no_titlebar=self.no_titlebar, no_button=self.no_button, grab_anywhere=self.grab_anywhere, keep_on_top=self.keep_on_top, - do_not_reroute_stdout=self.do_not_reroute_stdout, resizable=self.resizable) + do_not_reroute_stdout=self.do_not_reroute_stdout, resizable=self.resizable) event, values = self.window.read(timeout=0) if erase_all: self.window['-MULTILINE-'].update('') @@ -14851,20 +14721,21 @@ class _DebugWin(): outstring += sep_str outstring += end_str - self.output_element.Update(outstring, append=True, text_color_for_value=text_color, background_color_for_value=background_color, font_for_value=font) + self.output_element.Update(outstring, append=True, text_color_for_value=text_color, background_color_for_value=background_color, + font_for_value=font) else: print(*args, sep=sepchar, end=endchar) def Close(self): - if self.window.XFound: # increment the number of open windows to get around a bug with debug windows + if self.window.XFound: # increment the number of open windows to get around a bug with debug windows Window._IncrementOpenCount() self.window.close() self.window = None - def easy_print(*args, size=(None, None), end=None, sep=None, location=(None, None), font=None, no_titlebar=False, - no_button=False, grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=True, text_color=None, background_color=None, colors=None, c=None, erase_all=False, resizable=True): + no_button=False, grab_anywhere=False, keep_on_top=False, do_not_reroute_stdout=True, text_color=None, background_color=None, colors=None, c=None, + erase_all=False, resizable=True): """ Works like a "print" statement but with windowing options. Routes output to the "Debug Window" @@ -14875,42 +14746,42 @@ def easy_print(*args, size=(None, None), end=None, sep=None, location=(None, Non c - (str, str) - Colors tuple has format (foreground, backgrouned) c - str - can also be a string of the format "foreground on background" ("white on red") - :param *args: stuff to output - :type *args: (Any) - :param size: (w,h) w=characters-wide, h=rows-high - :type size: (int, int) - :param end: end character - :type end: (str) - :param sep: separator character - :type sep: (str) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param no_button: don't show button - :type no_button: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) + :param *args: stuff to output + :type *args: (Any) + :param size: (w,h) w=characters-wide, h=rows-high + :type size: (int, int) + :param end: end character + :type end: (str) + :param sep: separator character + :type sep: (str) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param no_button: don't show button + :type no_button: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) :param do_not_reroute_stdout: do not reroute stdout - :type do_not_reroute_stdout: (bool) - :param colors: Either a tuple or a string that has both the text and background colors - :type colors: (str) or (str, str) - :param c: Either a tuple or a string that has both the text and background colors - :type c: (str) or (str, str) - :param resizable: if True, the user can resize the debug window. Default is True - :type resizable: (bool) - :param erase_all: If True when erase the output before printing - :type erase_all: (bool) + :type do_not_reroute_stdout: (bool) + :param colors: Either a tuple or a string that has both the text and background colors + :type colors: (str) or (str, str) + :param c: Either a tuple or a string that has both the text and background colors + :type c: (str) or (str, str) + :param resizable: if True, the user can resize the debug window. Default is True + :type resizable: (bool) + :param erase_all: If True when erase the output before printing + :type erase_all: (bool) :return: :rtype: """ @@ -14919,10 +14790,8 @@ def easy_print(*args, size=(None, None), end=None, sep=None, location=(None, Non no_button=no_button, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, do_not_reroute_stdout=do_not_reroute_stdout, resizable=resizable) txt_color, bg_color = _parse_colors_parm(c or colors) - _DebugWin.debug_window.Print(*args, end=end, sep=sep, text_color=text_color or txt_color, background_color=background_color or bg_color, erase_all=erase_all, font=font) - - - + _DebugWin.debug_window.Print(*args, end=end, sep=sep, text_color=text_color or txt_color, background_color=background_color or bg_color, + erase_all=erase_all, font=font) def easy_print_close(): @@ -14937,8 +14806,6 @@ def easy_print_close(): _DebugWin.debug_window = None - - # d8b 888 # Y8P 888 # 888 @@ -14955,15 +14822,16 @@ def easy_print_close(): CPRINT_DESTINATION_WINDOW = None CPRINT_DESTINATION_MULTILINE_ELMENT_KEY = None + def cprint_set_output_destination(window, multiline_key): """ Sets up the color print (cprint) output destination - :param window: The window that the cprint call will route the output to - :type window: (Window) + :param window: The window that the cprint call will route the output to + :type window: (Window) :param multiline_key: Key for the Multiline Element where output will be sent - :type multiline_key: (Any) - :return: None - :rtype: None + :type multiline_key: (Any) + :return: None + :rtype: None """ global CPRINT_DESTINATION_WINDOW, CPRINT_DESTINATION_MULTILINE_ELMENT_KEY @@ -14972,8 +14840,8 @@ def cprint_set_output_destination(window, multiline_key): CPRINT_DESTINATION_MULTILINE_ELMENT_KEY = multiline_key - -def cprint(*args, end=None, sep=' ', text_color=None, font=None, t=None, background_color=None, b=None, colors=None, c=None, window=None, key=None, justification=None, autoscroll=True): +def cprint(*args, end=None, sep=' ', text_color=None, font=None, t=None, background_color=None, b=None, colors=None, c=None, window=None, key=None, + justification=None, autoscroll=True): """ Color print to a multiline element in a window of your choice. Must have EITHER called cprint_set_output_destination prior to making this call so that the @@ -15002,34 +14870,34 @@ def cprint(*args, end=None, sep=' ', text_color=None, font=None, t=None, backgro cprint('This will print white text on red background', text_color='white', background_color='red') cprint('This will print white text on red background', t='white', b='red') - :param *args: stuff to output - :type *args: (Any) - :param text_color: Color of the text - :type text_color: (str) - :param font: specifies the font family, size, etc for the value being updated - :type font: str | (str, int) | (str, int, str) + :param *args: stuff to output + :type *args: (Any) + :param text_color: Color of the text + :type text_color: (str) + :param font: specifies the font family, size, etc for the value being updated + :type font: str | (str, int) | (str, int, str) :param background_color: The background color of the line - :type background_color: (str) - :param colors: Either a tuple or a string that has both the text and background colors "text on background" or just the text color - :type colors: (str) or (str, str) - :param t: Color of the text - :type t: (str) - :param b: The background color of the line - :type b: (str) - :param c: Either a tuple or a string. Same as the color parm - :type c: (str) or (str, str) - :param end: end character - :type end: (str) - :param sep: separator character - :type sep: (str) - :param key: key of multiline to output to (if you want to override the one previously set) - :type key: (Any) - :param window: Window containing the multiline to output to (if you want to override the one previously set) - :param justification: text justification. left, right, center. Can use single characters l, r, c. Sets only for this value, not entire element - :type justification: (str) - :type window: (Window) - :param autoscroll: If True the contents of the element will automatically scroll as more data added to the end - :type autoscroll: (bool) + :type background_color: (str) + :param colors: Either a tuple or a string that has both the text and background colors "text on background" or just the text color + :type colors: (str) or (str, str) + :param t: Color of the text + :type t: (str) + :param b: The background color of the line + :type b: (str) + :param c: Either a tuple or a string. Same as the color parm + :type c: (str) or (str, str) + :param end: end character + :type end: (str) + :param sep: separator character + :type sep: (str) + :param key: key of multiline to output to (if you want to override the one previously set) + :type key: (Any) + :param window: Window containing the multiline to output to (if you want to override the one previously set) + :param justification: text justification. left, right, center. Can use single characters l, r, c. Sets only for this value, not entire element + :type justification: (str) + :type window: (Window) + :param autoscroll: If True the contents of the element will automatically scroll as more data added to the end + :type autoscroll: (bool) """ destination_key = CPRINT_DESTINATION_MULTILINE_ELMENT_KEY if key is None else key @@ -15050,22 +14918,24 @@ def cprint(*args, end=None, sep=' ', text_color=None, font=None, t=None, backgro kw_text_color = dual_color[0] kw_background_color = dual_color[1] elif isinstance(dual_color, str): - if ' on ' in dual_color: # if has "on" in the string, then have both text and background + if ' on ' in dual_color: # if has "on" in the string, then have both text and background kw_text_color = dual_color.split(' on ')[0] kw_background_color = dual_color.split(' on ')[1] - else: # if no "on" then assume the color string is just the text color + else: # if no "on" then assume the color string is just the text color kw_text_color = dual_color except Exception as e: print('* cprint warning * you messed up with color formatting', e) - mline = destination_window.find_element(destination_key, silent_on_error=True) # type: Multiline + mline = destination_window.find_element(destination_key, silent_on_error=True) # type: Multiline try: # mline = destination_window[destination_key] # type: Multiline if end is None: - mline.print(*args, text_color=kw_text_color, background_color=kw_background_color, end='', sep=sep, justification=justification, font=font, autoscroll=autoscroll) + mline.print(*args, text_color=kw_text_color, background_color=kw_background_color, end='', sep=sep, justification=justification, font=font, + autoscroll=autoscroll) mline.print('', justification=justification, autoscroll=autoscroll) else: - mline.print(*args,text_color=kw_text_color, background_color=kw_background_color, end=end, sep=sep, justification=justification, font=font, autoscroll=autoscroll) + mline.print(*args, text_color=kw_text_color, background_color=kw_background_color, end=end, sep=sep, justification=justification, font=font, + autoscroll=autoscroll) except Exception as e: print('** cprint error trying to print to the multiline. Printing to console instead **', e) print(*args, end=end, sep=sep) @@ -15080,21 +14950,21 @@ def _print_to_element(multiline_element, *args, end=None, sep=None, text_color=N Print like Python normally prints except route the output to a multiline element and also add colors if desired :param multiline_element: The multiline element to be output to - :type multiline_element: (Multiline) - :param args: The arguments to print - :type args: List[Any] - :param end: The end char to use just like print uses - :type end: (str) - :param sep: The separation character like print uses - :type sep: (str) - :param text_color: color of the text - :type text_color: (str) - :param background_color: The background color of the line - :type background_color: (str) - :param autoscroll: If True (the default), the element will scroll to bottom after updating - :type autoscroll: (bool) - :param font: specifies the font family, size, etc for the value being updated - :type font: str | (str, int) + :type multiline_element: (Multiline) + :param args: The arguments to print + :type args: List[Any] + :param end: The end char to use just like print uses + :type end: (str) + :param sep: The separation character like print uses + :type sep: (str) + :param text_color: color of the text + :type text_color: (str) + :param background_color: The background color of the line + :type background_color: (str) + :param autoscroll: If True (the default), the element will scroll to bottom after updating + :type autoscroll: (bool) + :param font: specifies the font family, size, etc for the value being updated + :type font: str | (str, int) """ end_str = str(end) if end is not None else '\n' sep_str = str(sep) if sep is not None else ' ' @@ -15103,13 +14973,14 @@ def _print_to_element(multiline_element, *args, end=None, sep=None, text_color=N num_args = len(args) for i, arg in enumerate(args): outstring += str(arg) - if i != num_args-1: + if i != num_args - 1: outstring += sep_str outstring += end_str - multiline_element.update(outstring, append=True, text_color_for_value=text_color, background_color_for_value=background_color, autoscroll=autoscroll, justification=justification, font_for_value=font) + multiline_element.update(outstring, append=True, text_color_for_value=text_color, background_color_for_value=background_color, autoscroll=autoscroll, + justification=justification, font_for_value=font) - try: # if the element is set to autorefresh, then refresh the parent window + try: # if the element is set to autorefresh, then refresh the parent window if multiline_element.AutoRefresh: multiline_element.ParentForm.refresh() except: @@ -15123,9 +14994,9 @@ def _parse_colors_parm(colors): This function parses the parameter into the component colors :param colors: Either a tuple or a string that has both the text and background colors - :type colors: (str) or (str, str) - :return: tuple with the individual text and background colors - :rtype: (str, str) + :type colors: (str) or (str, str) + :return: tuple with the individual text and background colors + :rtype: (str, str) """ if colors is None: return None, None @@ -15136,10 +15007,10 @@ def _parse_colors_parm(colors): kw_text_color = dual_color[0] kw_background_color = dual_color[1] elif isinstance(dual_color, str): - if ' on ' in dual_color: # if has "on" in the string, then have both text and background + if ' on ' in dual_color: # if has "on" in the string, then have both text and background kw_text_color = dual_color.split(' on ')[0] kw_background_color = dual_color.split(' on ')[1] - else: # if no "on" then assume the color string is just the text color + else: # if no "on" then assume the color string is just the text color kw_text_color = dual_color except Exception as e: print('* warning * you messed up with color formatting', e) @@ -15156,9 +15027,9 @@ def set_global_icon(icon): window is created. :param icon: Either a Base64 byte string or a filename - :type icon: bytes | str - :return: None - :rtype: None + :type icon: bytes | str + :return: None + :rtype: None """ Window._user_defined_icon = icon @@ -15168,117 +15039,120 @@ def set_global_icon(icon): # Sets the icon to be used by default # # ===================================================# def set_options(icon=None, button_color=None, element_size=(None, None), button_element_size=(None, None), - margins=(None, None), - element_padding=(None, None), auto_size_text=None, auto_size_buttons=None, font=None, border_width=None, - slider_border_width=None, slider_relief=None, slider_orientation=None, - autoclose_time=None, message_box_line_width=None, - progress_meter_border_depth=None, progress_meter_style=None, - progress_meter_relief=None, progress_meter_color=None, progress_meter_size=None, - text_justification=None, background_color=None, element_background_color=None, - text_element_background_color=None, input_elements_background_color=None, input_text_color=None, - scrollbar_color=None, text_color=None, element_text_color=None, debug_win_size=(None, None), - window_location=(None, None), error_button_color=(None, None), tooltip_time=None, tooltip_font=None, use_ttk_buttons=None, ttk_theme=None, suppress_error_popups=None, suppress_raise_key_errors=None, suppress_key_guessing=None, enable_treeview_869_patch=None, enable_mac_notitlebar_patch=None, use_custom_titlebar=None, titlebar_background_color=None, titlebar_text_color=None, titlebar_font=None, titlebar_icon=None, user_settings_path=None, pysimplegui_settings_path=None, pysimplegui_settings_filename=None): + margins=(None, None), + element_padding=(None, None), auto_size_text=None, auto_size_buttons=None, font=None, border_width=None, + slider_border_width=None, slider_relief=None, slider_orientation=None, + autoclose_time=None, message_box_line_width=None, + progress_meter_border_depth=None, progress_meter_style=None, + progress_meter_relief=None, progress_meter_color=None, progress_meter_size=None, + text_justification=None, background_color=None, element_background_color=None, + text_element_background_color=None, input_elements_background_color=None, input_text_color=None, + scrollbar_color=None, text_color=None, element_text_color=None, debug_win_size=(None, None), + window_location=(None, None), error_button_color=(None, None), tooltip_time=None, tooltip_font=None, use_ttk_buttons=None, ttk_theme=None, + suppress_error_popups=None, suppress_raise_key_errors=None, suppress_key_guessing=None, enable_treeview_869_patch=None, + enable_mac_notitlebar_patch=None, use_custom_titlebar=None, titlebar_background_color=None, titlebar_text_color=None, titlebar_font=None, + titlebar_icon=None, user_settings_path=None, pysimplegui_settings_path=None, pysimplegui_settings_filename=None): """ - :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO. Most portable is to use a Base64 of a GIF file. This works universally across all OS's - :type icon: bytes | str - :param button_color: Color of the button (text, background) - :type button_color: (str, str) or str - :param element_size: element size (width, height) in characters - :type element_size: (int, int) - :param button_element_size: Size of button - :type button_element_size: (int, int) - :param margins: (left/right, top/bottom) tkinter margins around outsize. Amount of pixels to leave inside the window's frame around the edges before your elements are shown. - :type margins: (int, int) - :param element_padding: Default amount of padding to put around elements in window (left/right, top/bottom) or ((left, right), (top, bottom)) - :type element_padding: (int, int) or ((int, int),(int,int)) - :param auto_size_text: True if the Widget should be shrunk to exactly fit the number of chars to show - :type auto_size_text: bool - :param auto_size_buttons: True if Buttons in this Window should be sized to exactly fit the text on this. - :type auto_size_buttons: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param border_width: width of border around element - :type border_width: (int) - :param slider_border_width: Width of the border around sliders - :type slider_border_width: (int) - :param slider_relief: Type of relief to use for sliders - :type slider_relief: (str) - :param slider_orientation: ??? - :type slider_orientation: ??? - :param autoclose_time: ??? - :type autoclose_time: ??? - :param message_box_line_width: ??? - :type message_box_line_width: ??? - :param progress_meter_border_depth: ??? - :type progress_meter_border_depth: ??? - :param progress_meter_style: You can no longer set a progress bar style. All ttk styles must be the same for the window - :type progress_meter_style: ??? + :param icon: Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO. Most portable is to use a Base64 of a GIF file. This works universally across all OS's + :type icon: bytes | str + :param button_color: Color of the button (text, background) + :type button_color: (str, str) or str + :param element_size: element size (width, height) in characters + :type element_size: (int, int) + :param button_element_size: Size of button + :type button_element_size: (int, int) + :param margins: (left/right, top/bottom) tkinter margins around outsize. Amount of pixels to leave inside the window's frame around the edges before your elements are shown. + :type margins: (int, int) + :param element_padding: Default amount of padding to put around elements in window (left/right, top/bottom) or ((left, right), (top, bottom)) + :type element_padding: (int, int) or ((int, int),(int,int)) + :param auto_size_text: True if the Widget should be shrunk to exactly fit the number of chars to show + :type auto_size_text: bool + :param auto_size_buttons: True if Buttons in this Window should be sized to exactly fit the text on this. + :type auto_size_buttons: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param border_width: width of border around element + :type border_width: (int) + :param slider_border_width: Width of the border around sliders + :type slider_border_width: (int) + :param slider_relief: Type of relief to use for sliders + :type slider_relief: (str) + :param slider_orientation: ??? + :type slider_orientation: ??? + :param autoclose_time: ??? + :type autoclose_time: ??? + :param message_box_line_width: ??? + :type message_box_line_width: ??? + :param progress_meter_border_depth: ??? + :type progress_meter_border_depth: ??? + :param progress_meter_style: You can no longer set a progress bar style. All ttk styles must be the same for the window + :type progress_meter_style: ??? :param progress_meter_relief: - :type progress_meter_relief: ??? - :param progress_meter_color: ??? - :type progress_meter_color: ??? - :param progress_meter_size: ??? - :type progress_meter_size: ??? - :param text_justification: Default text justification for all Text Elements in window - :type text_justification: 'left' | 'right' | 'center' - :param background_color: color of background - :type background_color: (str) - :param element_background_color: element background color - :type element_background_color: (str) - :param text_element_background_color: text element background color - :type text_element_background_color: (str) + :type progress_meter_relief: ??? + :param progress_meter_color: ??? + :type progress_meter_color: ??? + :param progress_meter_size: ??? + :type progress_meter_size: ??? + :param text_justification: Default text justification for all Text Elements in window + :type text_justification: 'left' | 'right' | 'center' + :param background_color: color of background + :type background_color: (str) + :param element_background_color: element background color + :type element_background_color: (str) + :param text_element_background_color: text element background color + :type text_element_background_color: (str) :param input_elements_background_color: Default color to use for the background of input elements - :type input_elements_background_color: (str) - :param input_text_color: Default color to use for the text for Input elements - :type input_text_color: (str) - :param scrollbar_color: Default color to use for the slider trough - :type scrollbar_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param element_text_color: Default color to use for Text elements - :type element_text_color: (str) - :param debug_win_size: window size - :type debug_win_size: (int, int) - :param window_location: Default location to place windows. Not setting will center windows on the display - :type window_location: (int, int) | None - :param error_button_color: (Default = (None)) - :type error_button_color: ??? - :param tooltip_time: time in milliseconds to wait before showing a tooltip. Default is 400ms - :type tooltip_time: (int) - :param tooltip_font: font to use for all tooltips - :type tooltip_font: str or Tuple[str, int] or Tuple[str, int, str] - :param use_ttk_buttons: if True will cause all buttons to be ttk buttons - :type use_ttk_buttons: (bool) - :param ttk_theme: Theme to use with ttk widgets. Choices (on Windows) include - 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' - :type ttk_theme: (str) - :param suppress_error_popups: If True then error popups will not be shown if generated internally to PySimpleGUI - :type suppress_error_popups: (bool) - :param suppress_raise_key_errors: If True then key errors won't be raised (you'll still get popup error) - :type suppress_raise_key_errors: (bool) - :param suppress_key_guessing: If True then key errors won't try and find closest matches for you - :type suppress_key_guessing: (bool) - :param enable_treeview_869_patch: If True, then will use the treeview color patch for tk 8.6.9 - :type enable_treeview_869_patch: (bool) - :param enable_mac_notitlebar_patch: If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 - :type enable_mac_notitlebar_patch: (bool) - :param use_custom_titlebar: If True then a custom titlebar is used instead of the normal system titlebar - :type use_custom_titlebar: (bool) - :param titlebar_background_color: If custom titlebar indicated by use_custom_titlebar, then use this as background color - :type titlebar_background_color: str | None - :param titlebar_text_color: If custom titlebar indicated by use_custom_titlebar, then use this as text color - :type titlebar_text_color: str | None - :param titlebar_font: If custom titlebar indicated by use_custom_titlebar, then use this as title font - :type titlebar_font: str | Tuple[str, int] | None - :param titlebar_icon: If custom titlebar indicated by use_custom_titlebar, then use this as the icon (file or base64 bytes) - :type titlebar_icon: bytes | str - :param user_settings_path: default path for user_settings API calls. Expanded with os.path.expanduser so can contain ~ to represent user - :type user_settings_path: (str) - :param pysimplegui_settings_path: default path for the global PySimpleGUI user_settings - :type pysimplegui_settings_path: (str) - :param pysimplegui_settings_filename: default filename for the global PySimpleGUI user_settings - :type pysimplegui_settings_filename: (str) - :return: None - :rtype: None + :type input_elements_background_color: (str) + :param input_text_color: Default color to use for the text for Input elements + :type input_text_color: (str) + :param scrollbar_color: Default color to use for the slider trough + :type scrollbar_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param element_text_color: Default color to use for Text elements + :type element_text_color: (str) + :param debug_win_size: window size + :type debug_win_size: (int, int) + :param window_location: Default location to place windows. Not setting will center windows on the display + :type window_location: (int, int) | None + :param error_button_color: (Default = (None)) + :type error_button_color: ??? + :param tooltip_time: time in milliseconds to wait before showing a tooltip. Default is 400ms + :type tooltip_time: (int) + :param tooltip_font: font to use for all tooltips + :type tooltip_font: str or Tuple[str, int] or Tuple[str, int, str] + :param use_ttk_buttons: if True will cause all buttons to be ttk buttons + :type use_ttk_buttons: (bool) + :param ttk_theme: Theme to use with ttk widgets. Choices (on Windows) include - 'default', 'winnative', 'clam', 'alt', 'classic', 'vista', 'xpnative' + :type ttk_theme: (str) + :param suppress_error_popups: If True then error popups will not be shown if generated internally to PySimpleGUI + :type suppress_error_popups: (bool) + :param suppress_raise_key_errors: If True then key errors won't be raised (you'll still get popup error) + :type suppress_raise_key_errors: (bool) + :param suppress_key_guessing: If True then key errors won't try and find closest matches for you + :type suppress_key_guessing: (bool) + :param enable_treeview_869_patch: If True, then will use the treeview color patch for tk 8.6.9 + :type enable_treeview_869_patch: (bool) + :param enable_mac_notitlebar_patch: If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 + :type enable_mac_notitlebar_patch: (bool) + :param use_custom_titlebar: If True then a custom titlebar is used instead of the normal system titlebar + :type use_custom_titlebar: (bool) + :param titlebar_background_color: If custom titlebar indicated by use_custom_titlebar, then use this as background color + :type titlebar_background_color: str | None + :param titlebar_text_color: If custom titlebar indicated by use_custom_titlebar, then use this as text color + :type titlebar_text_color: str | None + :param titlebar_font: If custom titlebar indicated by use_custom_titlebar, then use this as title font + :type titlebar_font: str | Tuple[str, int] | None + :param titlebar_icon: If custom titlebar indicated by use_custom_titlebar, then use this as the icon (file or base64 bytes) + :type titlebar_icon: bytes | str + :param user_settings_path: default path for user_settings API calls. Expanded with os.path.expanduser so can contain ~ to represent user + :type user_settings_path: (str) + :param pysimplegui_settings_path: default path for the global PySimpleGUI user_settings + :type pysimplegui_settings_path: (str) + :param pysimplegui_settings_filename: default filename for the global PySimpleGUI user_settings + :type pysimplegui_settings_filename: (str) + :return: None + :rtype: None """ global DEFAULT_ELEMENT_SIZE @@ -15510,168 +15384,417 @@ def set_options(icon=None, button_color=None, element_size=(None, None), button_ # of the elements. # ############################################################## LOOK_AND_FEEL_TABLE = { - "SystemDefault": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "SystemDefaultForReal": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": COLOR_SYSTEM_DEFAULT,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "SystemDefault1": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": COLOR_SYSTEM_DEFAULT,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "Material1": {"BACKGROUND": "#E3F2FD","TEXT": "#000000","INPUT": "#86A8FF","TEXT_INPUT": "#000000","SCROLL": "#86A8FF","BUTTON": ("#FFFFFF", "#5079D3"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 0,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#FF0266","ACCENT2": "#FF5C93","ACCENT3": "#C5003C",}, - "Material2": {"BACKGROUND": "#FAFAFA","TEXT": "#000000","INPUT": "#004EA1","TEXT_INPUT": "#FFFFFF","SCROLL": "#5EA7FF","BUTTON": ("#FFFFFF", "#0079D3"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 0,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#FF0266","ACCENT2": "#FF5C93","ACCENT3": "#C5003C",}, - "Reddit": {"BACKGROUND": "#ffffff","TEXT": "#1a1a1b","INPUT": "#dae0e6","TEXT_INPUT": "#222222","SCROLL": "#a5a4a4","BUTTON": ("#FFFFFF", "#0079d3"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#ff5414","ACCENT2": "#33a8ff","ACCENT3": "#dbf0ff",}, - "Topanga": {"BACKGROUND": "#282923","TEXT": "#E7DB74","INPUT": "#393a32","TEXT_INPUT": "#E7C855","SCROLL": "#E7C855","BUTTON": ("#E7C855", "#284B5A"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#c15226","ACCENT2": "#7a4d5f","ACCENT3": "#889743",}, - "GreenTan": {"BACKGROUND": "#9FB8AD","TEXT": '#000000',"INPUT": "#F7F3EC","TEXT_INPUT": "#000000","SCROLL": "#F7F3EC","BUTTON": ("#FFFFFF", "#475841"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Dark": {"BACKGROUND": "#404040","TEXT": "#FFFFFF","INPUT": "#4D4D4D","TEXT_INPUT": "#FFFFFF","SCROLL": "#707070","BUTTON": ("#FFFFFF", "#004F00"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightGreen": {"BACKGROUND": "#B7CECE","TEXT": "#000000","INPUT": "#FDFFF7","TEXT_INPUT": "#000000","SCROLL": "#FDFFF7","BUTTON": ("#FFFFFF", "#658268"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"ACCENT1": "#76506d","ACCENT2": "#5148f1","ACCENT3": "#0a1c84","PROGRESS_DEPTH": 0,}, - "Dark2": {"BACKGROUND": "#404040","TEXT": "#FFFFFF","INPUT": "#FFFFFF","TEXT_INPUT": "#000000","SCROLL": "#707070","BUTTON": ("#FFFFFF", "#004F00"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Black": {"BACKGROUND": "#000000","TEXT": "#FFFFFF","INPUT": "#4D4D4D","TEXT_INPUT": "#FFFFFF","SCROLL": "#707070","BUTTON": ("#000000", "#FFFFFF"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Tan": {"BACKGROUND": "#fdf6e3","TEXT": "#268bd1","INPUT": "#eee8d5","TEXT_INPUT": "#6c71c3","SCROLL": "#eee8d5","BUTTON": ("#FFFFFF", "#063542"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "TanBlue": {"BACKGROUND": "#e5dece","TEXT": "#063289","INPUT": "#f9f8f4","TEXT_INPUT": "#242834","SCROLL": "#eee8d5","BUTTON": ("#FFFFFF", "#063289"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkTanBlue": {"BACKGROUND": "#242834","TEXT": "#dfe6f8","INPUT": "#97755c","TEXT_INPUT": "#FFFFFF","SCROLL": "#a9afbb","BUTTON": ("#FFFFFF", "#063289"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkAmber": {"BACKGROUND": "#2c2825","TEXT": "#fdcb52","INPUT": "#705e52","TEXT_INPUT": "#fdcb52","SCROLL": "#705e52","BUTTON": ("#000000", "#fdcb52"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBlue": {"BACKGROUND": "#1a2835","TEXT": "#d1ecff","INPUT": "#335267","TEXT_INPUT": "#acc2d0","SCROLL": "#1b6497","BUTTON": ("#000000", "#fafaf8"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Reds": {"BACKGROUND": "#280001","TEXT": "#FFFFFF","INPUT": "#d8d584","TEXT_INPUT": "#000000","SCROLL": "#763e00","BUTTON": ("#000000", "#daad28"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Green": {"BACKGROUND": "#82a459","TEXT": "#000000","INPUT": "#d8d584","TEXT_INPUT": "#000000","SCROLL": "#e3ecf3","BUTTON": ("#FFFFFF", "#517239"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "BluePurple": {"BACKGROUND": "#A5CADD","TEXT": "#6E266E","INPUT": "#E0F5FF","TEXT_INPUT": "#000000","SCROLL": "#E0F5FF","BUTTON": ("#FFFFFF", "#303952"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Purple": {"BACKGROUND": "#B0AAC2","TEXT": "#000000","INPUT": "#F2EFE8","SCROLL": "#F2EFE8","TEXT_INPUT": "#000000","BUTTON": ("#000000", "#C2D4D8"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "BlueMono": {"BACKGROUND": "#AAB6D3","TEXT": "#000000","INPUT": "#F1F4FC","SCROLL": "#F1F4FC","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#7186C7"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "GreenMono": {"BACKGROUND": "#A8C1B4","TEXT": "#000000","INPUT": "#DDE0DE","SCROLL": "#E3E3E3","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#6D9F85"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "BrownBlue": {"BACKGROUND": "#64778d","TEXT": "#FFFFFF","INPUT": "#f0f3f7","SCROLL": "#A6B2BE","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#283b5b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "BrightColors": {"BACKGROUND": "#b4ffb4","TEXT": "#000000","INPUT": "#ffff64","SCROLL": "#ffb482","TEXT_INPUT": "#000000","BUTTON": ("#000000", "#ffa0dc"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "NeutralBlue": {"BACKGROUND": "#92aa9d","TEXT": "#000000","INPUT": "#fcfff6","SCROLL": "#fcfff6","TEXT_INPUT": "#000000","BUTTON": ("#000000", "#d0dbbd"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Kayak": {"BACKGROUND": "#a7ad7f","TEXT": "#000000","INPUT": "#e6d3a8","SCROLL": "#e6d3a8","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#5d907d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "SandyBeach": {"BACKGROUND": "#efeccb","TEXT": "#012f2f","INPUT": "#e6d3a8","SCROLL": "#e6d3a8","TEXT_INPUT": "#012f2f","BUTTON": ("#FFFFFF", "#046380"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "TealMono": {"BACKGROUND": "#a8cfdd","TEXT": "#000000","INPUT": "#dfedf2","SCROLL": "#dfedf2","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#183440"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "Default": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "Default1": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": COLOR_SYSTEM_DEFAULT,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "DefaultNoMoreNagging": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "GrayGrayGray": {"BACKGROUND": COLOR_SYSTEM_DEFAULT,"TEXT": COLOR_SYSTEM_DEFAULT,"INPUT": COLOR_SYSTEM_DEFAULT,"TEXT_INPUT": COLOR_SYSTEM_DEFAULT,"SCROLL": COLOR_SYSTEM_DEFAULT,"BUTTON": COLOR_SYSTEM_DEFAULT,"PROGRESS": COLOR_SYSTEM_DEFAULT,"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "LightBlue": {"BACKGROUND": "#E3F2FD","TEXT": "#000000","INPUT": "#86A8FF","TEXT_INPUT": "#000000","SCROLL": "#86A8FF","BUTTON": ("#FFFFFF", "#5079D3"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 0,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#FF0266","ACCENT2": "#FF5C93","ACCENT3": "#C5003C",}, - "LightGrey": {"BACKGROUND": "#FAFAFA","TEXT": "#000000","INPUT": "#004EA1","TEXT_INPUT": "#FFFFFF","SCROLL": "#5EA7FF","BUTTON": ("#FFFFFF", "#0079D3"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 0,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#FF0266","ACCENT2": "#FF5C93","ACCENT3": "#C5003C",}, - "LightGrey1": {"BACKGROUND": "#ffffff","TEXT": "#1a1a1b","INPUT": "#dae0e6","TEXT_INPUT": "#222222","SCROLL": "#a5a4a4","BUTTON": ("#FFFFFF", "#0079d3"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#ff5414","ACCENT2": "#33a8ff","ACCENT3": "#dbf0ff",}, - "DarkBrown": {"BACKGROUND": "#282923","TEXT": "#E7DB74","INPUT": "#393a32","TEXT_INPUT": "#E7C855","SCROLL": "#E7C855","BUTTON": ("#E7C855", "#284B5A"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"ACCENT1": "#c15226","ACCENT2": "#7a4d5f","ACCENT3": "#889743",}, - "LightGreen1": {"BACKGROUND": "#9FB8AD","TEXT": "#000000","INPUT": "#F7F3EC","TEXT_INPUT": "#000000","SCROLL": "#F7F3EC","BUTTON": ("#FFFFFF", "#475841"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey": {"BACKGROUND": "#404040","TEXT": "#FFFFFF","INPUT": "#4D4D4D","TEXT_INPUT": "#FFFFFF","SCROLL": "#707070","BUTTON": ("#FFFFFF", "#004F00"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightGreen2": {"BACKGROUND": "#B7CECE","TEXT": "#000000","INPUT": "#FDFFF7","TEXT_INPUT": "#000000","SCROLL": "#FDFFF7","BUTTON": ("#FFFFFF", "#658268"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"ACCENT1": "#76506d","ACCENT2": "#5148f1","ACCENT3": "#0a1c84","PROGRESS_DEPTH": 0,}, - "DarkGrey1": {"BACKGROUND": "#404040","TEXT": "#FFFFFF","INPUT": "#FFFFFF","TEXT_INPUT": "#000000","SCROLL": "#707070","BUTTON": ("#FFFFFF", "#004F00"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBlack": {"BACKGROUND": "#000000","TEXT": "#FFFFFF","INPUT": "#4D4D4D","TEXT_INPUT": "#FFFFFF","SCROLL": "#707070","BUTTON": ("#000000", "#FFFFFF"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBrown": {"BACKGROUND": "#fdf6e3","TEXT": "#268bd1","INPUT": "#eee8d5","TEXT_INPUT": "#6c71c3","SCROLL": "#eee8d5","BUTTON": ("#FFFFFF", "#063542"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBrown1": {"BACKGROUND": "#e5dece","TEXT": "#063289","INPUT": "#f9f8f4","TEXT_INPUT": "#242834","SCROLL": "#eee8d5","BUTTON": ("#FFFFFF", "#063289"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBlue1": {"BACKGROUND": "#242834","TEXT": "#dfe6f8","INPUT": "#97755c","TEXT_INPUT": "#FFFFFF","SCROLL": "#a9afbb","BUTTON": ("#FFFFFF", "#063289"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBrown1": {"BACKGROUND": "#2c2825","TEXT": "#fdcb52","INPUT": "#705e52","TEXT_INPUT": "#fdcb52","SCROLL": "#705e52","BUTTON": ("#000000", "#fdcb52"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBlue2": {"BACKGROUND": "#1a2835","TEXT": "#d1ecff","INPUT": "#335267","TEXT_INPUT": "#acc2d0","SCROLL": "#1b6497","BUTTON": ("#000000", "#fafaf8"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBrown2": {"BACKGROUND": "#280001","TEXT": "#FFFFFF","INPUT": "#d8d584","TEXT_INPUT": "#000000","SCROLL": "#763e00","BUTTON": ("#000000", "#daad28"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGreen": {"BACKGROUND": "#82a459","TEXT": "#000000","INPUT": "#d8d584","TEXT_INPUT": "#000000","SCROLL": "#e3ecf3","BUTTON": ("#FFFFFF", "#517239"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBlue1": {"BACKGROUND": "#A5CADD","TEXT": "#6E266E","INPUT": "#E0F5FF","TEXT_INPUT": "#000000","SCROLL": "#E0F5FF","BUTTON": ("#FFFFFF", "#303952"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightPurple": {"BACKGROUND": "#B0AAC2","TEXT": "#000000","INPUT": "#F2EFE8","SCROLL": "#F2EFE8","TEXT_INPUT": "#000000","BUTTON": ("#000000", "#C2D4D8"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBlue2": {"BACKGROUND": "#AAB6D3","TEXT": "#000000","INPUT": "#F1F4FC","SCROLL": "#F1F4FC","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#7186C7"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightGreen3": {"BACKGROUND": "#A8C1B4","TEXT": "#000000","INPUT": "#DDE0DE","SCROLL": "#E3E3E3","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#6D9F85"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBlue3": {"BACKGROUND": "#64778d","TEXT": "#FFFFFF","INPUT": "#f0f3f7","SCROLL": "#A6B2BE","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#283b5b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightGreen4": {"BACKGROUND": "#b4ffb4","TEXT": "#000000","INPUT": "#ffff64","SCROLL": "#ffb482","TEXT_INPUT": "#000000","BUTTON": ("#000000", "#ffa0dc"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightGreen5": {"BACKGROUND": "#92aa9d","TEXT": "#000000","INPUT": "#fcfff6","SCROLL": "#fcfff6","TEXT_INPUT": "#000000","BUTTON": ("#000000", "#d0dbbd"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBrown2": {"BACKGROUND": "#a7ad7f","TEXT": "#000000","INPUT": "#e6d3a8","SCROLL": "#e6d3a8","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#5d907d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBrown3": {"BACKGROUND": "#efeccb","TEXT": "#012f2f","INPUT": "#e6d3a8","SCROLL": "#e6d3a8","TEXT_INPUT": "#012f2f","BUTTON": ("#FFFFFF", "#046380"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBlue3": {"BACKGROUND": "#a8cfdd","TEXT": "#000000","INPUT": "#dfedf2","SCROLL": "#dfedf2","TEXT_INPUT": "#000000","BUTTON": ("#FFFFFF", "#183440"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "LightBrown4": {"BACKGROUND": "#d7c79e","TEXT": "#a35638","INPUT": "#9dab86","TEXT_INPUT": "#000000","SCROLL": "#a35638","BUTTON": ("#FFFFFF", "#a35638"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#a35638", "#9dab86", "#e08f62", "#d7c79e"],}, - "DarkTeal": {"BACKGROUND": "#003f5c","TEXT": "#fb5b5a","INPUT": "#bc4873","TEXT_INPUT": "#FFFFFF","SCROLL": "#bc4873","BUTTON": ("#FFFFFF", "#fb5b5a"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#003f5c", "#472b62", "#bc4873", "#fb5b5a"],}, - "DarkPurple": {"BACKGROUND": "#472b62","TEXT": "#fb5b5a","INPUT": "#bc4873","TEXT_INPUT": "#FFFFFF","SCROLL": "#bc4873","BUTTON": ("#FFFFFF", "#472b62"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#003f5c", "#472b62", "#bc4873", "#fb5b5a"],}, - "LightGreen6": {"BACKGROUND": "#eafbea","TEXT": "#1f6650","INPUT": "#6f9a8d","TEXT_INPUT": "#FFFFFF","SCROLL": "#1f6650","BUTTON": ("#FFFFFF", "#1f6650"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#1f6650", "#6f9a8d", "#ea5e5e", "#eafbea"],}, - "DarkGrey2": {"BACKGROUND": "#2b2b28","TEXT": "#f8f8f8","INPUT": "#f1d6ab","TEXT_INPUT": "#000000","SCROLL": "#f1d6ab","BUTTON": ("#2b2b28", "#e3b04b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#2b2b28", "#e3b04b", "#f1d6ab", "#f8f8f8"],}, - "LightBrown6": {"BACKGROUND": "#f9b282","TEXT": "#8f4426","INPUT": "#de6b35","TEXT_INPUT": "#FFFFFF","SCROLL": "#8f4426","BUTTON": ("#FFFFFF", "#8f4426"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#8f4426", "#de6b35", "#64ccda", "#f9b282"],}, - "DarkTeal1": {"BACKGROUND": "#396362","TEXT": "#ffe7d1","INPUT": "#f6c89f","TEXT_INPUT": "#000000","SCROLL": "#f6c89f","BUTTON": ("#ffe7d1", "#4b8e8d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#396362", "#4b8e8d", "#f6c89f", "#ffe7d1"],}, - "LightBrown7": {"BACKGROUND": "#f6c89f","TEXT": "#396362","INPUT": "#4b8e8d","TEXT_INPUT": "#FFFFFF","SCROLL": "#396362","BUTTON": ("#FFFFFF", "#396362"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#396362", "#4b8e8d", "#f6c89f", "#ffe7d1"],}, - "DarkPurple1": {"BACKGROUND": "#0c093c","TEXT": "#fad6d6","INPUT": "#eea5f6","TEXT_INPUT": "#000000","SCROLL": "#eea5f6","BUTTON": ("#FFFFFF", "#df42d1"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#0c093c", "#df42d1", "#eea5f6", "#fad6d6"],}, - "DarkGrey3": {"BACKGROUND": "#211717","TEXT": "#dfddc7","INPUT": "#f58b54","TEXT_INPUT": "#000000","SCROLL": "#f58b54","BUTTON": ("#dfddc7", "#a34a28"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#211717", "#a34a28", "#f58b54", "#dfddc7"],}, - "LightBrown8": {"BACKGROUND": "#dfddc7","TEXT": "#211717","INPUT": "#a34a28","TEXT_INPUT": "#dfddc7","SCROLL": "#211717","BUTTON": ("#dfddc7", "#a34a28"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#211717", "#a34a28", "#f58b54", "#dfddc7"],}, - "DarkBlue4": {"BACKGROUND": "#494ca2","TEXT": "#e3e7f1","INPUT": "#c6cbef","TEXT_INPUT": "#000000","SCROLL": "#c6cbef","BUTTON": ("#FFFFFF", "#8186d5"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#494ca2", "#8186d5", "#c6cbef", "#e3e7f1"],}, - "LightBlue4": {"BACKGROUND": "#5c94bd","TEXT": "#470938","INPUT": "#1a3e59","TEXT_INPUT": "#FFFFFF","SCROLL": "#470938","BUTTON": ("#FFFFFF", "#470938"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#470938", "#1a3e59", "#5c94bd", "#f2d6eb"],}, - "DarkTeal2": {"BACKGROUND": "#394a6d","TEXT": "#c0ffb3","INPUT": "#52de97","TEXT_INPUT": "#000000","SCROLL": "#52de97","BUTTON": ("#c0ffb3", "#394a6d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#394a6d", "#3c9d9b", "#52de97", "#c0ffb3"],}, - "DarkTeal3": {"BACKGROUND": "#3c9d9b","TEXT": "#c0ffb3","INPUT": "#52de97","TEXT_INPUT": "#000000","SCROLL": "#52de97","BUTTON": ("#c0ffb3", "#394a6d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#394a6d", "#3c9d9b", "#52de97", "#c0ffb3"],}, - "DarkPurple5": {"BACKGROUND": "#730068","TEXT": "#f6f078","INPUT": "#01d28e","TEXT_INPUT": "#000000","SCROLL": "#01d28e","BUTTON": ("#f6f078", "#730068"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#730068", "#434982", "#01d28e", "#f6f078"],}, - "DarkPurple2": {"BACKGROUND": "#202060","TEXT": "#b030b0","INPUT": "#602080","TEXT_INPUT": "#FFFFFF","SCROLL": "#602080","BUTTON": ("#FFFFFF", "#202040"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#202040", "#202060", "#602080", "#b030b0"],}, - "DarkBlue5": {"BACKGROUND": "#000272","TEXT": "#ff6363","INPUT": "#a32f80","TEXT_INPUT": "#FFFFFF","SCROLL": "#a32f80","BUTTON": ("#FFFFFF", "#341677"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#000272", "#341677", "#a32f80", "#ff6363"],}, - "LightGrey2": {"BACKGROUND": "#f6f6f6","TEXT": "#420000","INPUT": "#d4d7dd","TEXT_INPUT": "#420000","SCROLL": "#420000","BUTTON": ("#420000", "#d4d7dd"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#420000", "#d4d7dd", "#eae9e9", "#f6f6f6"],}, - "LightGrey3": {"BACKGROUND": "#eae9e9","TEXT": "#420000","INPUT": "#d4d7dd","TEXT_INPUT": "#420000","SCROLL": "#420000","BUTTON": ("#420000", "#d4d7dd"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#420000", "#d4d7dd", "#eae9e9", "#f6f6f6"],}, - "DarkBlue6": {"BACKGROUND": "#01024e","TEXT": "#ff6464","INPUT": "#8b4367","TEXT_INPUT": "#FFFFFF","SCROLL": "#8b4367","BUTTON": ("#FFFFFF", "#543864"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#01024e", "#543864", "#8b4367", "#ff6464"],}, - "DarkBlue7": {"BACKGROUND": "#241663","TEXT": "#eae7af","INPUT": "#a72693","TEXT_INPUT": "#eae7af","SCROLL": "#a72693","BUTTON": ("#eae7af", "#160f30"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#160f30", "#241663", "#a72693", "#eae7af"],}, - "LightBrown9": {"BACKGROUND": "#f6d365","TEXT": "#3a1f5d","INPUT": "#c83660","TEXT_INPUT": "#f6d365","SCROLL": "#3a1f5d","BUTTON": ("#f6d365", "#c83660"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3a1f5d", "#c83660", "#e15249", "#f6d365"],}, - "DarkPurple3": {"BACKGROUND": "#6e2142","TEXT": "#ffd692","INPUT": "#e16363","TEXT_INPUT": "#ffd692","SCROLL": "#e16363","BUTTON": ("#ffd692", "#943855"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#6e2142", "#943855", "#e16363", "#ffd692"],}, - "LightBrown10": {"BACKGROUND": "#ffd692","TEXT": "#6e2142","INPUT": "#943855","TEXT_INPUT": "#FFFFFF","SCROLL": "#6e2142","BUTTON": ("#FFFFFF", "#6e2142"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#6e2142", "#943855", "#e16363", "#ffd692"],}, - "DarkPurple4": {"BACKGROUND": "#200f21","TEXT": "#f638dc","INPUT": "#5a3d5c","TEXT_INPUT": "#FFFFFF","SCROLL": "#5a3d5c","BUTTON": ("#FFFFFF", "#382039"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#200f21", "#382039", "#5a3d5c", "#f638dc"],}, - "LightBlue5": {"BACKGROUND": "#b2fcff","TEXT": "#3e64ff","INPUT": "#5edfff","TEXT_INPUT": "#000000","SCROLL": "#3e64ff","BUTTON": ("#FFFFFF", "#3e64ff"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3e64ff", "#5edfff", "#b2fcff", "#ecfcff"],}, - "DarkTeal4": {"BACKGROUND": "#464159","TEXT": "#c7f0db","INPUT": "#8bbabb","TEXT_INPUT": "#000000","SCROLL": "#8bbabb","BUTTON": ("#FFFFFF", "#6c7b95"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#464159", "#6c7b95", "#8bbabb", "#c7f0db"],}, - "LightTeal": {"BACKGROUND": "#c7f0db","TEXT": "#464159","INPUT": "#6c7b95","TEXT_INPUT": "#FFFFFF","SCROLL": "#464159","BUTTON": ("#FFFFFF", "#464159"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#464159", "#6c7b95", "#8bbabb", "#c7f0db"],}, - "DarkTeal5": {"BACKGROUND": "#8bbabb","TEXT": "#464159","INPUT": "#6c7b95","TEXT_INPUT": "#FFFFFF","SCROLL": "#464159","BUTTON": ("#c7f0db", "#6c7b95"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#464159", "#6c7b95", "#8bbabb", "#c7f0db"],}, - "LightGrey4": {"BACKGROUND": "#faf5ef","TEXT": "#672f2f","INPUT": "#99b19c","TEXT_INPUT": "#672f2f","SCROLL": "#672f2f","BUTTON": ("#672f2f", "#99b19c"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#672f2f", "#99b19c", "#d7d1c9", "#faf5ef"],}, - "LightGreen7": {"BACKGROUND": "#99b19c","TEXT": "#faf5ef","INPUT": "#d7d1c9","TEXT_INPUT": "#000000","SCROLL": "#d7d1c9","BUTTON": ("#FFFFFF", "#99b19c"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#672f2f", "#99b19c", "#d7d1c9", "#faf5ef"],}, - "LightGrey5": {"BACKGROUND": "#d7d1c9","TEXT": "#672f2f","INPUT": "#99b19c","TEXT_INPUT": "#672f2f","SCROLL": "#672f2f","BUTTON": ("#FFFFFF", "#672f2f"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#672f2f", "#99b19c", "#d7d1c9", "#faf5ef"],}, - "DarkBrown3": {"BACKGROUND": "#a0855b","TEXT": "#f9f6f2","INPUT": "#f1d6ab","TEXT_INPUT": "#000000","SCROLL": "#f1d6ab","BUTTON": ("#FFFFFF", "#38470b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#38470b", "#a0855b", "#f1d6ab", "#f9f6f2"],}, - "LightBrown11": {"BACKGROUND": "#f1d6ab","TEXT": "#38470b","INPUT": "#a0855b","TEXT_INPUT": "#FFFFFF","SCROLL": "#38470b","BUTTON": ("#f9f6f2", "#a0855b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#38470b", "#a0855b", "#f1d6ab", "#f9f6f2"],}, - "DarkRed": {"BACKGROUND": "#83142c","TEXT": "#f9d276","INPUT": "#ad1d45","TEXT_INPUT": "#FFFFFF","SCROLL": "#ad1d45","BUTTON": ("#f9d276", "#ad1d45"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#44000d", "#83142c", "#ad1d45", "#f9d276"],}, - "DarkTeal6": {"BACKGROUND": "#204969","TEXT": "#fff7f7","INPUT": "#dadada","TEXT_INPUT": "#000000","SCROLL": "#dadada","BUTTON": ("#000000", "#fff7f7"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#204969", "#08ffc8", "#dadada", "#fff7f7"],}, - "DarkBrown4": {"BACKGROUND": "#252525","TEXT": "#ff0000","INPUT": "#af0404","TEXT_INPUT": "#FFFFFF","SCROLL": "#af0404","BUTTON": ("#FFFFFF", "#252525"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#252525", "#414141", "#af0404", "#ff0000"],}, - "LightYellow": {"BACKGROUND": "#f4ff61","TEXT": "#27aa80","INPUT": "#32ff6a","TEXT_INPUT": "#000000","SCROLL": "#27aa80","BUTTON": ("#f4ff61", "#27aa80"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#27aa80", "#32ff6a", "#a8ff3e", "#f4ff61"],}, - "DarkGreen1": {"BACKGROUND": "#2b580c","TEXT": "#fdef96","INPUT": "#f7b71d","TEXT_INPUT": "#000000","SCROLL": "#f7b71d","BUTTON": ("#fdef96", "#2b580c"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#2b580c", "#afa939", "#f7b71d", "#fdef96"],}, - "LightGreen8": {"BACKGROUND": "#c8dad3","TEXT": "#63707e","INPUT": "#93b5b3","TEXT_INPUT": "#000000","SCROLL": "#63707e","BUTTON": ("#FFFFFF", "#63707e"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#63707e", "#93b5b3", "#c8dad3", "#f2f6f5"],}, - "DarkTeal7": {"BACKGROUND": "#248ea9","TEXT": "#fafdcb","INPUT": "#aee7e8","TEXT_INPUT": "#000000","SCROLL": "#aee7e8","BUTTON": ("#000000", "#fafdcb"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#248ea9", "#28c3d4", "#aee7e8", "#fafdcb"],}, - "DarkBlue8": {"BACKGROUND": "#454d66","TEXT": "#d9d872","INPUT": "#58b368","TEXT_INPUT": "#000000","SCROLL": "#58b368","BUTTON": ("#000000", "#009975"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#009975", "#454d66", "#58b368", "#d9d872"],}, - "DarkBlue9": {"BACKGROUND": "#263859","TEXT": "#ff6768","INPUT": "#6b778d","TEXT_INPUT": "#FFFFFF","SCROLL": "#6b778d","BUTTON": ("#ff6768", "#263859"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#17223b", "#263859", "#6b778d", "#ff6768"],}, - "DarkBlue10": {"BACKGROUND": "#0028ff","TEXT": "#f1f4df","INPUT": "#10eaf0","TEXT_INPUT": "#000000","SCROLL": "#10eaf0","BUTTON": ("#f1f4df", "#24009c"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#24009c", "#0028ff", "#10eaf0", "#f1f4df"],}, - "DarkBlue11": {"BACKGROUND": "#6384b3","TEXT": "#e6f0b6","INPUT": "#b8e9c0","TEXT_INPUT": "#000000","SCROLL": "#b8e9c0","BUTTON": ("#e6f0b6", "#684949"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#684949", "#6384b3", "#b8e9c0", "#e6f0b6"],}, - "DarkTeal8": {"BACKGROUND": "#71a0a5","TEXT": "#212121","INPUT": "#665c84","TEXT_INPUT": "#FFFFFF","SCROLL": "#212121","BUTTON": ("#fab95b", "#665c84"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#212121", "#665c84", "#71a0a5", "#fab95b"],}, - "DarkRed1": {"BACKGROUND": "#c10000","TEXT": "#eeeeee","INPUT": "#dedede","TEXT_INPUT": "#000000","SCROLL": "#dedede","BUTTON": ("#c10000", "#eeeeee"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#c10000", "#ff4949", "#dedede", "#eeeeee"],}, - "LightBrown5": {"BACKGROUND": "#fff591","TEXT": "#e41749","INPUT": "#f5587b","TEXT_INPUT": "#000000","SCROLL": "#e41749","BUTTON": ("#fff591", "#e41749"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#e41749", "#f5587b", "#ff8a5c", "#fff591"],}, - "LightGreen9": {"BACKGROUND": "#f1edb3","TEXT": "#3b503d","INPUT": "#4a746e","TEXT_INPUT": "#f1edb3","SCROLL": "#3b503d","BUTTON": ("#f1edb3", "#3b503d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3b503d", "#4a746e", "#c8cf94", "#f1edb3"],"DESCRIPTION": ["Green", "Turquoise", "Yellow"],}, - "DarkGreen2": {"BACKGROUND": "#3b503d","TEXT": "#f1edb3","INPUT": "#c8cf94","TEXT_INPUT": "#000000","SCROLL": "#c8cf94","BUTTON": ("#f1edb3", "#3b503d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3b503d", "#4a746e", "#c8cf94", "#f1edb3"],"DESCRIPTION": ["Green", "Turquoise", "Yellow"],}, - "LightGray1": {"BACKGROUND": "#f2f2f2","TEXT": "#222831","INPUT": "#393e46","TEXT_INPUT": "#FFFFFF","SCROLL": "#222831","BUTTON": ("#f2f2f2", "#222831"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#222831", "#393e46", "#f96d00", "#f2f2f2"],"DESCRIPTION": ["#000000", "Grey", "Orange", "Grey", "Autumn"],}, - "DarkGrey4": {"BACKGROUND": "#52524e","TEXT": "#e9e9e5","INPUT": "#d4d6c8","TEXT_INPUT": "#000000","SCROLL": "#d4d6c8","BUTTON": ("#FFFFFF", "#9a9b94"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#52524e", "#9a9b94", "#d4d6c8", "#e9e9e5"],"DESCRIPTION": ["Grey", "Pastel", "Winter"],}, - "DarkBlue12": {"BACKGROUND": "#324e7b","TEXT": "#f8f8f8","INPUT": "#86a6df","TEXT_INPUT": "#000000","SCROLL": "#86a6df","BUTTON": ("#FFFFFF", "#5068a9"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#324e7b", "#5068a9", "#86a6df", "#f8f8f8"],"DESCRIPTION": ["Blue", "Grey", "Cold", "Winter"],}, - "DarkPurple6": {"BACKGROUND": "#070739","TEXT": "#e1e099","INPUT": "#c327ab","TEXT_INPUT": "#e1e099","SCROLL": "#c327ab","BUTTON": ("#e1e099", "#521477"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#070739", "#521477", "#c327ab", "#e1e099"],"DESCRIPTION": ["#000000", "Purple", "Yellow", "Dark"],}, - "DarkPurple7": {"BACKGROUND": "#191930","TEXT": "#B1B7C5","INPUT": "#232B5C","TEXT_INPUT": "#D0E3E7","SCROLL": "#B1B7C5","BUTTON": ("#272D38", "#B1B7C5"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBlue13": {"BACKGROUND": "#203562","TEXT": "#e3e8f8","INPUT": "#c0c5cd","TEXT_INPUT": "#000000","SCROLL": "#c0c5cd","BUTTON": ("#FFFFFF", "#3e588f"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#203562", "#3e588f", "#c0c5cd", "#e3e8f8"],"DESCRIPTION": ["Blue", "Grey", "Wedding", "Cold"],}, - "DarkBrown5": {"BACKGROUND": "#3c1b1f","TEXT": "#f6e1b5","INPUT": "#e2bf81","TEXT_INPUT": "#000000","SCROLL": "#e2bf81","BUTTON": ("#3c1b1f", "#f6e1b5"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3c1b1f", "#b21e4b", "#e2bf81", "#f6e1b5"],"DESCRIPTION": ["Brown", "Red", "Yellow", "Warm"],}, - "DarkGreen3": {"BACKGROUND": "#062121","TEXT": "#eeeeee","INPUT": "#e4dcad","TEXT_INPUT": "#000000","SCROLL": "#e4dcad","BUTTON": ("#eeeeee", "#181810"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#062121", "#181810", "#e4dcad", "#eeeeee"],"DESCRIPTION": ["#000000", "#000000", "Brown", "Grey"],}, - "DarkBlack1": {"BACKGROUND": "#181810","TEXT": "#eeeeee","INPUT": "#e4dcad","TEXT_INPUT": "#000000","SCROLL": "#e4dcad","BUTTON": ("#FFFFFF", "#062121"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#062121", "#181810", "#e4dcad", "#eeeeee"],"DESCRIPTION": ["#000000", "#000000", "Brown", "Grey"],}, - "DarkGrey5": {"BACKGROUND": "#343434","TEXT": "#f3f3f3","INPUT": "#e9dcbe","TEXT_INPUT": "#000000","SCROLL": "#e9dcbe","BUTTON": ("#FFFFFF", "#8e8b82"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#343434", "#8e8b82", "#e9dcbe", "#f3f3f3"],"DESCRIPTION": ["Grey", "Brown"],}, - "LightBrown12": {"BACKGROUND": "#8e8b82","TEXT": "#f3f3f3","INPUT": "#e9dcbe","TEXT_INPUT": "#000000","SCROLL": "#e9dcbe","BUTTON": ("#f3f3f3", "#8e8b82"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#343434", "#8e8b82", "#e9dcbe", "#f3f3f3"],"DESCRIPTION": ["Grey", "Brown"],}, - "DarkTeal9": {"BACKGROUND": "#13445a","TEXT": "#fef4e8","INPUT": "#446878","TEXT_INPUT": "#FFFFFF","SCROLL": "#446878","BUTTON": ("#fef4e8", "#446878"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#13445a", "#970747", "#446878", "#fef4e8"],"DESCRIPTION": ["Red", "Grey", "Blue", "Wedding", "Retro"],}, - "DarkBlue14": {"BACKGROUND": "#21273d","TEXT": "#f1f6f8","INPUT": "#b9d4f1","TEXT_INPUT": "#000000","SCROLL": "#b9d4f1","BUTTON": ("#FFFFFF", "#6a759b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#21273d", "#6a759b", "#b9d4f1", "#f1f6f8"],"DESCRIPTION": ["Blue", "#000000", "Grey", "Cold", "Winter"],}, - "LightBlue6": {"BACKGROUND": "#f1f6f8","TEXT": "#21273d","INPUT": "#6a759b","TEXT_INPUT": "#FFFFFF","SCROLL": "#21273d","BUTTON": ("#f1f6f8", "#6a759b"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#21273d", "#6a759b", "#b9d4f1", "#f1f6f8"],"DESCRIPTION": ["Blue", "#000000", "Grey", "Cold", "Winter"],}, - "DarkGreen4": {"BACKGROUND": "#044343","TEXT": "#e4e4e4","INPUT": "#045757","TEXT_INPUT": "#e4e4e4","SCROLL": "#045757","BUTTON": ("#e4e4e4", "#045757"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#222222", "#044343", "#045757", "#e4e4e4"],"DESCRIPTION": ["#000000", "Turquoise", "Grey", "Dark"],}, - "DarkGreen5": {"BACKGROUND": "#1b4b36","TEXT": "#e0e7f1","INPUT": "#aebd77","TEXT_INPUT": "#000000","SCROLL": "#aebd77","BUTTON": ("#FFFFFF", "#538f6a"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#1b4b36", "#538f6a", "#aebd77", "#e0e7f1"],"DESCRIPTION": ["Green", "Grey"],}, - "DarkTeal10": {"BACKGROUND": "#0d3446","TEXT": "#d8dfe2","INPUT": "#71adb5","TEXT_INPUT": "#000000","SCROLL": "#71adb5","BUTTON": ("#FFFFFF", "#176d81"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#0d3446", "#176d81", "#71adb5", "#d8dfe2"],"DESCRIPTION": ["Grey", "Turquoise", "Winter", "Cold"],}, - "DarkGrey6": {"BACKGROUND": "#3e3e3e","TEXT": "#ededed","INPUT": "#68868c","TEXT_INPUT": "#ededed","SCROLL": "#68868c","BUTTON": ("#FFFFFF", "#405559"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3e3e3e", "#405559", "#68868c", "#ededed"],"DESCRIPTION": ["Grey", "Turquoise", "Winter"],}, - "DarkTeal11": {"BACKGROUND": "#405559","TEXT": "#ededed","INPUT": "#68868c","TEXT_INPUT": "#ededed","SCROLL": "#68868c","BUTTON": ("#ededed", "#68868c"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#3e3e3e", "#405559", "#68868c", "#ededed"],"DESCRIPTION": ["Grey", "Turquoise", "Winter"],}, - "LightBlue7": {"BACKGROUND": "#9ed0e0","TEXT": "#19483f","INPUT": "#5c868e","TEXT_INPUT": "#FFFFFF","SCROLL": "#19483f","BUTTON": ("#FFFFFF", "#19483f"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#19483f", "#5c868e", "#ff6a38", "#9ed0e0"],"DESCRIPTION": ["Orange", "Blue", "Turquoise"],}, - "LightGreen10": {"BACKGROUND": "#d8ebb5","TEXT": "#205d67","INPUT": "#639a67","TEXT_INPUT": "#FFFFFF","SCROLL": "#205d67","BUTTON": ("#d8ebb5", "#205d67"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#205d67", "#639a67", "#d9bf77", "#d8ebb5"],"DESCRIPTION": ["Blue", "Green", "Brown", "Vintage"],}, - "DarkBlue15": {"BACKGROUND": "#151680","TEXT": "#f1fea4","INPUT": "#375fc0","TEXT_INPUT": "#f1fea4","SCROLL": "#375fc0","BUTTON": ("#f1fea4", "#1c44ac"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#151680", "#1c44ac", "#375fc0", "#f1fea4"],"DESCRIPTION": ["Blue", "Yellow", "Cold"],}, - "DarkBlue16": {"BACKGROUND": "#1c44ac","TEXT": "#f1fea4","INPUT": "#375fc0","TEXT_INPUT": "#f1fea4","SCROLL": "#375fc0","BUTTON": ("#f1fea4", "#151680"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#151680", "#1c44ac", "#375fc0", "#f1fea4"],"DESCRIPTION": ["Blue", "Yellow", "Cold"],}, - "DarkTeal12": {"BACKGROUND": "#004a7c","TEXT": "#fafafa","INPUT": "#e8f1f5","TEXT_INPUT": "#000000","SCROLL": "#e8f1f5","BUTTON": ("#fafafa", "#005691"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#004a7c", "#005691", "#e8f1f5", "#fafafa"],"DESCRIPTION": ["Grey", "Blue", "Cold", "Winter"],}, - "LightBrown13": {"BACKGROUND": "#ebf5ee","TEXT": "#921224","INPUT": "#bdc6b8","TEXT_INPUT": "#921224","SCROLL": "#921224","BUTTON": ("#FFFFFF", "#921224"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#921224", "#bdc6b8", "#bce0da", "#ebf5ee"],"DESCRIPTION": ["Red", "Blue", "Grey", "Vintage", "Wedding"],}, - "DarkBlue17": {"BACKGROUND": "#21294c","TEXT": "#f9f2d7","INPUT": "#f2dea8","TEXT_INPUT": "#000000","SCROLL": "#f2dea8","BUTTON": ("#f9f2d7", "#141829"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#141829", "#21294c", "#f2dea8", "#f9f2d7"],"DESCRIPTION": ["#000000", "Blue", "Yellow"],}, - "DarkBrown6": {"BACKGROUND": "#785e4d","TEXT": "#f2eee3","INPUT": "#baaf92","TEXT_INPUT": "#000000","SCROLL": "#baaf92","BUTTON": ("#FFFFFF", "#785e4d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#785e4d", "#ff8426", "#baaf92", "#f2eee3"],"DESCRIPTION": ["Grey", "Brown", "Orange", "Autumn"],}, - "DarkGreen6": {"BACKGROUND": "#5c715e","TEXT": "#f2f9f1","INPUT": "#ddeedf","TEXT_INPUT": "#000000","SCROLL": "#ddeedf","BUTTON": ("#f2f9f1", "#5c715e"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#5c715e", "#b6cdbd", "#ddeedf", "#f2f9f1"],"DESCRIPTION": ["Grey", "Green", "Vintage"],}, - "DarkGreen7": {"BACKGROUND": "#0C231E","TEXT": "#efbe1c","INPUT": "#153C33","TEXT_INPUT": "#efbe1c","SCROLL": "#153C33","BUTTON": ("#efbe1c", "#153C33"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey7": {"BACKGROUND": "#4b586e","TEXT": "#dddddd","INPUT": "#574e6d","TEXT_INPUT": "#dddddd","SCROLL": "#574e6d","BUTTON": ("#dddddd", "#43405d"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#43405d", "#4b586e", "#574e6d", "#dddddd"],"DESCRIPTION": ["Grey", "Winter", "Cold"],}, - "DarkRed2": {"BACKGROUND": "#ab1212","TEXT": "#f6e4b5","INPUT": "#cd3131","TEXT_INPUT": "#f6e4b5","SCROLL": "#cd3131","BUTTON": ("#f6e4b5", "#ab1212"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#ab1212", "#1fad9f", "#cd3131", "#f6e4b5"],"DESCRIPTION": ["Turquoise", "Red", "Yellow"],}, - "LightGrey6": {"BACKGROUND": "#e3e3e3","TEXT": "#233142","INPUT": "#455d7a","TEXT_INPUT": "#e3e3e3","SCROLL": "#233142","BUTTON": ("#e3e3e3", "#455d7a"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,"COLOR_LIST": ["#233142", "#455d7a", "#f95959", "#e3e3e3"],"DESCRIPTION": ["#000000", "Blue", "Red", "Grey"],}, - "HotDogStand": {"BACKGROUND": "red","TEXT": "yellow","INPUT": "yellow","TEXT_INPUT": "#000000","SCROLL": "yellow","BUTTON": ("red", "yellow"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey8": {"BACKGROUND": "#19232D","TEXT": "#ffffff","INPUT": "#32414B","TEXT_INPUT": "#ffffff","SCROLL": "#505F69","BUTTON": ("#ffffff", "#32414B"),"PROGRESS": ("#505F69", "#32414B"),"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey9": {"BACKGROUND": "#36393F","TEXT": "#DCDDDE","INPUT": "#40444B","TEXT_INPUT": "#ffffff","SCROLL": "#202225","BUTTON": ("#202225", "#B9BBBE"),"PROGRESS": ("#202225", "#40444B"),"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey10": {"BACKGROUND": "#1c1e23","TEXT": "#cccdcf","INPUT": "#272a31","TEXT_INPUT": "#8b9fde","SCROLL": "#313641","BUTTON": ("#f5f5f6", "#2e3d5a"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey11": {"BACKGROUND": "#1c1e23","TEXT": "#cccdcf","INPUT": "#313641","TEXT_INPUT": "#cccdcf","SCROLL": "#313641","BUTTON": ("#f5f5f6", "#313641"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey12": {"BACKGROUND": "#1c1e23","TEXT": "#8b9fde","INPUT": "#313641","TEXT_INPUT": "#8b9fde","SCROLL": "#313641","BUTTON": ("#cccdcf", "#2e3d5a"),"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE,"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey13": {"BACKGROUND": "#1c1e23","TEXT": "#cccdcf","INPUT": "#272a31","TEXT_INPUT": "#cccdcf","SCROLL": "#313641","BUTTON": ("#8b9fde", "#313641"),"PROGRESS": ("#cccdcf", "#272a31"),"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkGrey14": {"BACKGROUND": "#24292e","TEXT": "#fafbfc","INPUT": "#1d2125","TEXT_INPUT": "#fafbfc","SCROLL": "#1d2125","BUTTON": ("#fafbfc", "#155398"),"PROGRESS": ("#155398", "#1d2125"),"BORDER": 1,"SLIDER_DEPTH": 0,"PROGRESS_DEPTH": 0,}, - "DarkBrown7": {"BACKGROUND": "#2c2417","TEXT": "#baa379","INPUT": "#baa379","TEXT_INPUT": "#000000","SCROLL": "#392e1c","BUTTON": ("#000000", "#baa379"),"PROGRESS": ("#baa379", "#453923"),"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, - "Python": {"BACKGROUND": "#3d7aab","TEXT": "#ffde56","INPUT": "#295273","TEXT_INPUT": "#ffde56","SCROLL": "#295273","BUTTON": ("#ffde56", "#295273"),"PROGRESS": ("#ffde56", "#295273"),"BORDER": 1,"SLIDER_DEPTH": 1,"PROGRESS_DEPTH": 0,}, + "SystemDefault": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, + "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, + "SLIDER_DEPTH": 1, "PROGRESS_DEPTH": 0, }, + "SystemDefaultForReal": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, + "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": COLOR_SYSTEM_DEFAULT, + "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, "SLIDER_DEPTH": 1, "PROGRESS_DEPTH": 0, }, + "SystemDefault1": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, + "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": COLOR_SYSTEM_DEFAULT, "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, "SLIDER_DEPTH": 1, + "PROGRESS_DEPTH": 0, }, + "Material1": {"BACKGROUND": "#E3F2FD", "TEXT": "#000000", "INPUT": "#86A8FF", "TEXT_INPUT": "#000000", "SCROLL": "#86A8FF", + "BUTTON": ("#FFFFFF", "#5079D3"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 0, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "ACCENT1": "#FF0266", "ACCENT2": "#FF5C93", "ACCENT3": "#C5003C", }, + "Material2": {"BACKGROUND": "#FAFAFA", "TEXT": "#000000", "INPUT": "#004EA1", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#5EA7FF", + "BUTTON": ("#FFFFFF", "#0079D3"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 0, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "ACCENT1": "#FF0266", "ACCENT2": "#FF5C93", "ACCENT3": "#C5003C", }, + "Reddit": {"BACKGROUND": "#ffffff", "TEXT": "#1a1a1b", "INPUT": "#dae0e6", "TEXT_INPUT": "#222222", "SCROLL": "#a5a4a4", "BUTTON": ("#FFFFFF", "#0079d3"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, "ACCENT1": "#ff5414", "ACCENT2": "#33a8ff", + "ACCENT3": "#dbf0ff", }, + "Topanga": {"BACKGROUND": "#282923", "TEXT": "#E7DB74", "INPUT": "#393a32", "TEXT_INPUT": "#E7C855", "SCROLL": "#E7C855", "BUTTON": ("#E7C855", "#284B5A"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, "ACCENT1": "#c15226", "ACCENT2": "#7a4d5f", + "ACCENT3": "#889743", }, + "GreenTan": {"BACKGROUND": "#9FB8AD", "TEXT": '#000000', "INPUT": "#F7F3EC", "TEXT_INPUT": "#000000", "SCROLL": "#F7F3EC", "BUTTON": ("#FFFFFF", "#475841"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Dark": {"BACKGROUND": "#404040", "TEXT": "#FFFFFF", "INPUT": "#4D4D4D", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#707070", "BUTTON": ("#FFFFFF", "#004F00"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightGreen": {"BACKGROUND": "#B7CECE", "TEXT": "#000000", "INPUT": "#FDFFF7", "TEXT_INPUT": "#000000", "SCROLL": "#FDFFF7", + "BUTTON": ("#FFFFFF", "#658268"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "ACCENT1": "#76506d", + "ACCENT2": "#5148f1", "ACCENT3": "#0a1c84", "PROGRESS_DEPTH": 0, }, + "Dark2": {"BACKGROUND": "#404040", "TEXT": "#FFFFFF", "INPUT": "#FFFFFF", "TEXT_INPUT": "#000000", "SCROLL": "#707070", "BUTTON": ("#FFFFFF", "#004F00"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Black": {"BACKGROUND": "#000000", "TEXT": "#FFFFFF", "INPUT": "#4D4D4D", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#707070", "BUTTON": ("#000000", "#FFFFFF"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Tan": {"BACKGROUND": "#fdf6e3", "TEXT": "#268bd1", "INPUT": "#eee8d5", "TEXT_INPUT": "#6c71c3", "SCROLL": "#eee8d5", "BUTTON": ("#FFFFFF", "#063542"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "TanBlue": {"BACKGROUND": "#e5dece", "TEXT": "#063289", "INPUT": "#f9f8f4", "TEXT_INPUT": "#242834", "SCROLL": "#eee8d5", "BUTTON": ("#FFFFFF", "#063289"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkTanBlue": {"BACKGROUND": "#242834", "TEXT": "#dfe6f8", "INPUT": "#97755c", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#a9afbb", + "BUTTON": ("#FFFFFF", "#063289"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkAmber": {"BACKGROUND": "#2c2825", "TEXT": "#fdcb52", "INPUT": "#705e52", "TEXT_INPUT": "#fdcb52", "SCROLL": "#705e52", + "BUTTON": ("#000000", "#fdcb52"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBlue": {"BACKGROUND": "#1a2835", "TEXT": "#d1ecff", "INPUT": "#335267", "TEXT_INPUT": "#acc2d0", "SCROLL": "#1b6497", "BUTTON": ("#000000", "#fafaf8"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Reds": {"BACKGROUND": "#280001", "TEXT": "#FFFFFF", "INPUT": "#d8d584", "TEXT_INPUT": "#000000", "SCROLL": "#763e00", "BUTTON": ("#000000", "#daad28"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Green": {"BACKGROUND": "#82a459", "TEXT": "#000000", "INPUT": "#d8d584", "TEXT_INPUT": "#000000", "SCROLL": "#e3ecf3", "BUTTON": ("#FFFFFF", "#517239"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "BluePurple": {"BACKGROUND": "#A5CADD", "TEXT": "#6E266E", "INPUT": "#E0F5FF", "TEXT_INPUT": "#000000", "SCROLL": "#E0F5FF", + "BUTTON": ("#FFFFFF", "#303952"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Purple": {"BACKGROUND": "#B0AAC2", "TEXT": "#000000", "INPUT": "#F2EFE8", "SCROLL": "#F2EFE8", "TEXT_INPUT": "#000000", "BUTTON": ("#000000", "#C2D4D8"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "BlueMono": {"BACKGROUND": "#AAB6D3", "TEXT": "#000000", "INPUT": "#F1F4FC", "SCROLL": "#F1F4FC", "TEXT_INPUT": "#000000", "BUTTON": ("#FFFFFF", "#7186C7"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "GreenMono": {"BACKGROUND": "#A8C1B4", "TEXT": "#000000", "INPUT": "#DDE0DE", "SCROLL": "#E3E3E3", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#6D9F85"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "BrownBlue": {"BACKGROUND": "#64778d", "TEXT": "#FFFFFF", "INPUT": "#f0f3f7", "SCROLL": "#A6B2BE", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#283b5b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "BrightColors": {"BACKGROUND": "#b4ffb4", "TEXT": "#000000", "INPUT": "#ffff64", "SCROLL": "#ffb482", "TEXT_INPUT": "#000000", + "BUTTON": ("#000000", "#ffa0dc"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "NeutralBlue": {"BACKGROUND": "#92aa9d", "TEXT": "#000000", "INPUT": "#fcfff6", "SCROLL": "#fcfff6", "TEXT_INPUT": "#000000", + "BUTTON": ("#000000", "#d0dbbd"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Kayak": {"BACKGROUND": "#a7ad7f", "TEXT": "#000000", "INPUT": "#e6d3a8", "SCROLL": "#e6d3a8", "TEXT_INPUT": "#000000", "BUTTON": ("#FFFFFF", "#5d907d"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "SandyBeach": {"BACKGROUND": "#efeccb", "TEXT": "#012f2f", "INPUT": "#e6d3a8", "SCROLL": "#e6d3a8", "TEXT_INPUT": "#012f2f", + "BUTTON": ("#FFFFFF", "#046380"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "TealMono": {"BACKGROUND": "#a8cfdd", "TEXT": "#000000", "INPUT": "#dfedf2", "SCROLL": "#dfedf2", "TEXT_INPUT": "#000000", "BUTTON": ("#FFFFFF", "#183440"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "Default": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, + "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, "SLIDER_DEPTH": 1, + "PROGRESS_DEPTH": 0, }, + "Default1": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, + "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": COLOR_SYSTEM_DEFAULT, "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, "SLIDER_DEPTH": 1, + "PROGRESS_DEPTH": 0, }, + "DefaultNoMoreNagging": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, + "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": OFFICIAL_PYSIMPLEGUI_BUTTON_COLOR, + "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, "SLIDER_DEPTH": 1, "PROGRESS_DEPTH": 0, }, + "GrayGrayGray": {"BACKGROUND": COLOR_SYSTEM_DEFAULT, "TEXT": COLOR_SYSTEM_DEFAULT, "INPUT": COLOR_SYSTEM_DEFAULT, "TEXT_INPUT": COLOR_SYSTEM_DEFAULT, + "SCROLL": COLOR_SYSTEM_DEFAULT, "BUTTON": COLOR_SYSTEM_DEFAULT, "PROGRESS": COLOR_SYSTEM_DEFAULT, "BORDER": 1, "SLIDER_DEPTH": 1, + "PROGRESS_DEPTH": 0, }, + "LightBlue": {"BACKGROUND": "#E3F2FD", "TEXT": "#000000", "INPUT": "#86A8FF", "TEXT_INPUT": "#000000", "SCROLL": "#86A8FF", + "BUTTON": ("#FFFFFF", "#5079D3"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 0, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "ACCENT1": "#FF0266", "ACCENT2": "#FF5C93", "ACCENT3": "#C5003C", }, + "LightGrey": {"BACKGROUND": "#FAFAFA", "TEXT": "#000000", "INPUT": "#004EA1", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#5EA7FF", + "BUTTON": ("#FFFFFF", "#0079D3"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 0, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "ACCENT1": "#FF0266", "ACCENT2": "#FF5C93", "ACCENT3": "#C5003C", }, + "LightGrey1": {"BACKGROUND": "#ffffff", "TEXT": "#1a1a1b", "INPUT": "#dae0e6", "TEXT_INPUT": "#222222", "SCROLL": "#a5a4a4", + "BUTTON": ("#FFFFFF", "#0079d3"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "ACCENT1": "#ff5414", "ACCENT2": "#33a8ff", "ACCENT3": "#dbf0ff", }, + "DarkBrown": {"BACKGROUND": "#282923", "TEXT": "#E7DB74", "INPUT": "#393a32", "TEXT_INPUT": "#E7C855", "SCROLL": "#E7C855", + "BUTTON": ("#E7C855", "#284B5A"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "ACCENT1": "#c15226", "ACCENT2": "#7a4d5f", "ACCENT3": "#889743", }, + "LightGreen1": {"BACKGROUND": "#9FB8AD", "TEXT": "#000000", "INPUT": "#F7F3EC", "TEXT_INPUT": "#000000", "SCROLL": "#F7F3EC", + "BUTTON": ("#FFFFFF", "#475841"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey": {"BACKGROUND": "#404040", "TEXT": "#FFFFFF", "INPUT": "#4D4D4D", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#707070", "BUTTON": ("#FFFFFF", "#004F00"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightGreen2": {"BACKGROUND": "#B7CECE", "TEXT": "#000000", "INPUT": "#FDFFF7", "TEXT_INPUT": "#000000", "SCROLL": "#FDFFF7", + "BUTTON": ("#FFFFFF", "#658268"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "ACCENT1": "#76506d", + "ACCENT2": "#5148f1", "ACCENT3": "#0a1c84", "PROGRESS_DEPTH": 0, }, + "DarkGrey1": {"BACKGROUND": "#404040", "TEXT": "#FFFFFF", "INPUT": "#FFFFFF", "TEXT_INPUT": "#000000", "SCROLL": "#707070", + "BUTTON": ("#FFFFFF", "#004F00"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBlack": {"BACKGROUND": "#000000", "TEXT": "#FFFFFF", "INPUT": "#4D4D4D", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#707070", + "BUTTON": ("#000000", "#FFFFFF"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBrown": {"BACKGROUND": "#fdf6e3", "TEXT": "#268bd1", "INPUT": "#eee8d5", "TEXT_INPUT": "#6c71c3", "SCROLL": "#eee8d5", + "BUTTON": ("#FFFFFF", "#063542"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBrown1": {"BACKGROUND": "#e5dece", "TEXT": "#063289", "INPUT": "#f9f8f4", "TEXT_INPUT": "#242834", "SCROLL": "#eee8d5", + "BUTTON": ("#FFFFFF", "#063289"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBlue1": {"BACKGROUND": "#242834", "TEXT": "#dfe6f8", "INPUT": "#97755c", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#a9afbb", + "BUTTON": ("#FFFFFF", "#063289"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBrown1": {"BACKGROUND": "#2c2825", "TEXT": "#fdcb52", "INPUT": "#705e52", "TEXT_INPUT": "#fdcb52", "SCROLL": "#705e52", + "BUTTON": ("#000000", "#fdcb52"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBlue2": {"BACKGROUND": "#1a2835", "TEXT": "#d1ecff", "INPUT": "#335267", "TEXT_INPUT": "#acc2d0", "SCROLL": "#1b6497", + "BUTTON": ("#000000", "#fafaf8"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBrown2": {"BACKGROUND": "#280001", "TEXT": "#FFFFFF", "INPUT": "#d8d584", "TEXT_INPUT": "#000000", "SCROLL": "#763e00", + "BUTTON": ("#000000", "#daad28"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGreen": {"BACKGROUND": "#82a459", "TEXT": "#000000", "INPUT": "#d8d584", "TEXT_INPUT": "#000000", "SCROLL": "#e3ecf3", + "BUTTON": ("#FFFFFF", "#517239"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBlue1": {"BACKGROUND": "#A5CADD", "TEXT": "#6E266E", "INPUT": "#E0F5FF", "TEXT_INPUT": "#000000", "SCROLL": "#E0F5FF", + "BUTTON": ("#FFFFFF", "#303952"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightPurple": {"BACKGROUND": "#B0AAC2", "TEXT": "#000000", "INPUT": "#F2EFE8", "SCROLL": "#F2EFE8", "TEXT_INPUT": "#000000", + "BUTTON": ("#000000", "#C2D4D8"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBlue2": {"BACKGROUND": "#AAB6D3", "TEXT": "#000000", "INPUT": "#F1F4FC", "SCROLL": "#F1F4FC", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#7186C7"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightGreen3": {"BACKGROUND": "#A8C1B4", "TEXT": "#000000", "INPUT": "#DDE0DE", "SCROLL": "#E3E3E3", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#6D9F85"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBlue3": {"BACKGROUND": "#64778d", "TEXT": "#FFFFFF", "INPUT": "#f0f3f7", "SCROLL": "#A6B2BE", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#283b5b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightGreen4": {"BACKGROUND": "#b4ffb4", "TEXT": "#000000", "INPUT": "#ffff64", "SCROLL": "#ffb482", "TEXT_INPUT": "#000000", + "BUTTON": ("#000000", "#ffa0dc"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightGreen5": {"BACKGROUND": "#92aa9d", "TEXT": "#000000", "INPUT": "#fcfff6", "SCROLL": "#fcfff6", "TEXT_INPUT": "#000000", + "BUTTON": ("#000000", "#d0dbbd"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBrown2": {"BACKGROUND": "#a7ad7f", "TEXT": "#000000", "INPUT": "#e6d3a8", "SCROLL": "#e6d3a8", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#5d907d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBrown3": {"BACKGROUND": "#efeccb", "TEXT": "#012f2f", "INPUT": "#e6d3a8", "SCROLL": "#e6d3a8", "TEXT_INPUT": "#012f2f", + "BUTTON": ("#FFFFFF", "#046380"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBlue3": {"BACKGROUND": "#a8cfdd", "TEXT": "#000000", "INPUT": "#dfedf2", "SCROLL": "#dfedf2", "TEXT_INPUT": "#000000", + "BUTTON": ("#FFFFFF", "#183440"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "LightBrown4": {"BACKGROUND": "#d7c79e", "TEXT": "#a35638", "INPUT": "#9dab86", "TEXT_INPUT": "#000000", "SCROLL": "#a35638", + "BUTTON": ("#FFFFFF", "#a35638"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#a35638", "#9dab86", "#e08f62", "#d7c79e"], }, + "DarkTeal": {"BACKGROUND": "#003f5c", "TEXT": "#fb5b5a", "INPUT": "#bc4873", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#bc4873", "BUTTON": ("#FFFFFF", "#fb5b5a"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#003f5c", "#472b62", "#bc4873", "#fb5b5a"], }, + "DarkPurple": {"BACKGROUND": "#472b62", "TEXT": "#fb5b5a", "INPUT": "#bc4873", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#bc4873", + "BUTTON": ("#FFFFFF", "#472b62"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#003f5c", "#472b62", "#bc4873", "#fb5b5a"], }, + "LightGreen6": {"BACKGROUND": "#eafbea", "TEXT": "#1f6650", "INPUT": "#6f9a8d", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#1f6650", + "BUTTON": ("#FFFFFF", "#1f6650"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#1f6650", "#6f9a8d", "#ea5e5e", "#eafbea"], }, + "DarkGrey2": {"BACKGROUND": "#2b2b28", "TEXT": "#f8f8f8", "INPUT": "#f1d6ab", "TEXT_INPUT": "#000000", "SCROLL": "#f1d6ab", + "BUTTON": ("#2b2b28", "#e3b04b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#2b2b28", "#e3b04b", "#f1d6ab", "#f8f8f8"], }, + "LightBrown6": {"BACKGROUND": "#f9b282", "TEXT": "#8f4426", "INPUT": "#de6b35", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#8f4426", + "BUTTON": ("#FFFFFF", "#8f4426"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#8f4426", "#de6b35", "#64ccda", "#f9b282"], }, + "DarkTeal1": {"BACKGROUND": "#396362", "TEXT": "#ffe7d1", "INPUT": "#f6c89f", "TEXT_INPUT": "#000000", "SCROLL": "#f6c89f", + "BUTTON": ("#ffe7d1", "#4b8e8d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#396362", "#4b8e8d", "#f6c89f", "#ffe7d1"], }, + "LightBrown7": {"BACKGROUND": "#f6c89f", "TEXT": "#396362", "INPUT": "#4b8e8d", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#396362", + "BUTTON": ("#FFFFFF", "#396362"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#396362", "#4b8e8d", "#f6c89f", "#ffe7d1"], }, + "DarkPurple1": {"BACKGROUND": "#0c093c", "TEXT": "#fad6d6", "INPUT": "#eea5f6", "TEXT_INPUT": "#000000", "SCROLL": "#eea5f6", + "BUTTON": ("#FFFFFF", "#df42d1"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#0c093c", "#df42d1", "#eea5f6", "#fad6d6"], }, + "DarkGrey3": {"BACKGROUND": "#211717", "TEXT": "#dfddc7", "INPUT": "#f58b54", "TEXT_INPUT": "#000000", "SCROLL": "#f58b54", + "BUTTON": ("#dfddc7", "#a34a28"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#211717", "#a34a28", "#f58b54", "#dfddc7"], }, + "LightBrown8": {"BACKGROUND": "#dfddc7", "TEXT": "#211717", "INPUT": "#a34a28", "TEXT_INPUT": "#dfddc7", "SCROLL": "#211717", + "BUTTON": ("#dfddc7", "#a34a28"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#211717", "#a34a28", "#f58b54", "#dfddc7"], }, + "DarkBlue4": {"BACKGROUND": "#494ca2", "TEXT": "#e3e7f1", "INPUT": "#c6cbef", "TEXT_INPUT": "#000000", "SCROLL": "#c6cbef", + "BUTTON": ("#FFFFFF", "#8186d5"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#494ca2", "#8186d5", "#c6cbef", "#e3e7f1"], }, + "LightBlue4": {"BACKGROUND": "#5c94bd", "TEXT": "#470938", "INPUT": "#1a3e59", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#470938", + "BUTTON": ("#FFFFFF", "#470938"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#470938", "#1a3e59", "#5c94bd", "#f2d6eb"], }, + "DarkTeal2": {"BACKGROUND": "#394a6d", "TEXT": "#c0ffb3", "INPUT": "#52de97", "TEXT_INPUT": "#000000", "SCROLL": "#52de97", + "BUTTON": ("#c0ffb3", "#394a6d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#394a6d", "#3c9d9b", "#52de97", "#c0ffb3"], }, + "DarkTeal3": {"BACKGROUND": "#3c9d9b", "TEXT": "#c0ffb3", "INPUT": "#52de97", "TEXT_INPUT": "#000000", "SCROLL": "#52de97", + "BUTTON": ("#c0ffb3", "#394a6d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#394a6d", "#3c9d9b", "#52de97", "#c0ffb3"], }, + "DarkPurple5": {"BACKGROUND": "#730068", "TEXT": "#f6f078", "INPUT": "#01d28e", "TEXT_INPUT": "#000000", "SCROLL": "#01d28e", + "BUTTON": ("#f6f078", "#730068"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#730068", "#434982", "#01d28e", "#f6f078"], }, + "DarkPurple2": {"BACKGROUND": "#202060", "TEXT": "#b030b0", "INPUT": "#602080", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#602080", + "BUTTON": ("#FFFFFF", "#202040"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#202040", "#202060", "#602080", "#b030b0"], }, + "DarkBlue5": {"BACKGROUND": "#000272", "TEXT": "#ff6363", "INPUT": "#a32f80", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#a32f80", + "BUTTON": ("#FFFFFF", "#341677"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#000272", "#341677", "#a32f80", "#ff6363"], }, + "LightGrey2": {"BACKGROUND": "#f6f6f6", "TEXT": "#420000", "INPUT": "#d4d7dd", "TEXT_INPUT": "#420000", "SCROLL": "#420000", + "BUTTON": ("#420000", "#d4d7dd"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#420000", "#d4d7dd", "#eae9e9", "#f6f6f6"], }, + "LightGrey3": {"BACKGROUND": "#eae9e9", "TEXT": "#420000", "INPUT": "#d4d7dd", "TEXT_INPUT": "#420000", "SCROLL": "#420000", + "BUTTON": ("#420000", "#d4d7dd"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#420000", "#d4d7dd", "#eae9e9", "#f6f6f6"], }, + "DarkBlue6": {"BACKGROUND": "#01024e", "TEXT": "#ff6464", "INPUT": "#8b4367", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#8b4367", + "BUTTON": ("#FFFFFF", "#543864"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#01024e", "#543864", "#8b4367", "#ff6464"], }, + "DarkBlue7": {"BACKGROUND": "#241663", "TEXT": "#eae7af", "INPUT": "#a72693", "TEXT_INPUT": "#eae7af", "SCROLL": "#a72693", + "BUTTON": ("#eae7af", "#160f30"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#160f30", "#241663", "#a72693", "#eae7af"], }, + "LightBrown9": {"BACKGROUND": "#f6d365", "TEXT": "#3a1f5d", "INPUT": "#c83660", "TEXT_INPUT": "#f6d365", "SCROLL": "#3a1f5d", + "BUTTON": ("#f6d365", "#c83660"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3a1f5d", "#c83660", "#e15249", "#f6d365"], }, + "DarkPurple3": {"BACKGROUND": "#6e2142", "TEXT": "#ffd692", "INPUT": "#e16363", "TEXT_INPUT": "#ffd692", "SCROLL": "#e16363", + "BUTTON": ("#ffd692", "#943855"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#6e2142", "#943855", "#e16363", "#ffd692"], }, + "LightBrown10": {"BACKGROUND": "#ffd692", "TEXT": "#6e2142", "INPUT": "#943855", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#6e2142", + "BUTTON": ("#FFFFFF", "#6e2142"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#6e2142", "#943855", "#e16363", "#ffd692"], }, + "DarkPurple4": {"BACKGROUND": "#200f21", "TEXT": "#f638dc", "INPUT": "#5a3d5c", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#5a3d5c", + "BUTTON": ("#FFFFFF", "#382039"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#200f21", "#382039", "#5a3d5c", "#f638dc"], }, + "LightBlue5": {"BACKGROUND": "#b2fcff", "TEXT": "#3e64ff", "INPUT": "#5edfff", "TEXT_INPUT": "#000000", "SCROLL": "#3e64ff", + "BUTTON": ("#FFFFFF", "#3e64ff"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3e64ff", "#5edfff", "#b2fcff", "#ecfcff"], }, + "DarkTeal4": {"BACKGROUND": "#464159", "TEXT": "#c7f0db", "INPUT": "#8bbabb", "TEXT_INPUT": "#000000", "SCROLL": "#8bbabb", + "BUTTON": ("#FFFFFF", "#6c7b95"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#464159", "#6c7b95", "#8bbabb", "#c7f0db"], }, + "LightTeal": {"BACKGROUND": "#c7f0db", "TEXT": "#464159", "INPUT": "#6c7b95", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#464159", + "BUTTON": ("#FFFFFF", "#464159"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#464159", "#6c7b95", "#8bbabb", "#c7f0db"], }, + "DarkTeal5": {"BACKGROUND": "#8bbabb", "TEXT": "#464159", "INPUT": "#6c7b95", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#464159", + "BUTTON": ("#c7f0db", "#6c7b95"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#464159", "#6c7b95", "#8bbabb", "#c7f0db"], }, + "LightGrey4": {"BACKGROUND": "#faf5ef", "TEXT": "#672f2f", "INPUT": "#99b19c", "TEXT_INPUT": "#672f2f", "SCROLL": "#672f2f", + "BUTTON": ("#672f2f", "#99b19c"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#672f2f", "#99b19c", "#d7d1c9", "#faf5ef"], }, + "LightGreen7": {"BACKGROUND": "#99b19c", "TEXT": "#faf5ef", "INPUT": "#d7d1c9", "TEXT_INPUT": "#000000", "SCROLL": "#d7d1c9", + "BUTTON": ("#FFFFFF", "#99b19c"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#672f2f", "#99b19c", "#d7d1c9", "#faf5ef"], }, + "LightGrey5": {"BACKGROUND": "#d7d1c9", "TEXT": "#672f2f", "INPUT": "#99b19c", "TEXT_INPUT": "#672f2f", "SCROLL": "#672f2f", + "BUTTON": ("#FFFFFF", "#672f2f"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#672f2f", "#99b19c", "#d7d1c9", "#faf5ef"], }, + "DarkBrown3": {"BACKGROUND": "#a0855b", "TEXT": "#f9f6f2", "INPUT": "#f1d6ab", "TEXT_INPUT": "#000000", "SCROLL": "#f1d6ab", + "BUTTON": ("#FFFFFF", "#38470b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#38470b", "#a0855b", "#f1d6ab", "#f9f6f2"], }, + "LightBrown11": {"BACKGROUND": "#f1d6ab", "TEXT": "#38470b", "INPUT": "#a0855b", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#38470b", + "BUTTON": ("#f9f6f2", "#a0855b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#38470b", "#a0855b", "#f1d6ab", "#f9f6f2"], }, + "DarkRed": {"BACKGROUND": "#83142c", "TEXT": "#f9d276", "INPUT": "#ad1d45", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#ad1d45", "BUTTON": ("#f9d276", "#ad1d45"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#44000d", "#83142c", "#ad1d45", "#f9d276"], }, + "DarkTeal6": {"BACKGROUND": "#204969", "TEXT": "#fff7f7", "INPUT": "#dadada", "TEXT_INPUT": "#000000", "SCROLL": "#dadada", + "BUTTON": ("#000000", "#fff7f7"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#204969", "#08ffc8", "#dadada", "#fff7f7"], }, + "DarkBrown4": {"BACKGROUND": "#252525", "TEXT": "#ff0000", "INPUT": "#af0404", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#af0404", + "BUTTON": ("#FFFFFF", "#252525"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#252525", "#414141", "#af0404", "#ff0000"], }, + "LightYellow": {"BACKGROUND": "#f4ff61", "TEXT": "#27aa80", "INPUT": "#32ff6a", "TEXT_INPUT": "#000000", "SCROLL": "#27aa80", + "BUTTON": ("#f4ff61", "#27aa80"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#27aa80", "#32ff6a", "#a8ff3e", "#f4ff61"], }, + "DarkGreen1": {"BACKGROUND": "#2b580c", "TEXT": "#fdef96", "INPUT": "#f7b71d", "TEXT_INPUT": "#000000", "SCROLL": "#f7b71d", + "BUTTON": ("#fdef96", "#2b580c"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#2b580c", "#afa939", "#f7b71d", "#fdef96"], }, + "LightGreen8": {"BACKGROUND": "#c8dad3", "TEXT": "#63707e", "INPUT": "#93b5b3", "TEXT_INPUT": "#000000", "SCROLL": "#63707e", + "BUTTON": ("#FFFFFF", "#63707e"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#63707e", "#93b5b3", "#c8dad3", "#f2f6f5"], }, + "DarkTeal7": {"BACKGROUND": "#248ea9", "TEXT": "#fafdcb", "INPUT": "#aee7e8", "TEXT_INPUT": "#000000", "SCROLL": "#aee7e8", + "BUTTON": ("#000000", "#fafdcb"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#248ea9", "#28c3d4", "#aee7e8", "#fafdcb"], }, + "DarkBlue8": {"BACKGROUND": "#454d66", "TEXT": "#d9d872", "INPUT": "#58b368", "TEXT_INPUT": "#000000", "SCROLL": "#58b368", + "BUTTON": ("#000000", "#009975"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#009975", "#454d66", "#58b368", "#d9d872"], }, + "DarkBlue9": {"BACKGROUND": "#263859", "TEXT": "#ff6768", "INPUT": "#6b778d", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#6b778d", + "BUTTON": ("#ff6768", "#263859"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#17223b", "#263859", "#6b778d", "#ff6768"], }, + "DarkBlue10": {"BACKGROUND": "#0028ff", "TEXT": "#f1f4df", "INPUT": "#10eaf0", "TEXT_INPUT": "#000000", "SCROLL": "#10eaf0", + "BUTTON": ("#f1f4df", "#24009c"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#24009c", "#0028ff", "#10eaf0", "#f1f4df"], }, + "DarkBlue11": {"BACKGROUND": "#6384b3", "TEXT": "#e6f0b6", "INPUT": "#b8e9c0", "TEXT_INPUT": "#000000", "SCROLL": "#b8e9c0", + "BUTTON": ("#e6f0b6", "#684949"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#684949", "#6384b3", "#b8e9c0", "#e6f0b6"], }, + "DarkTeal8": {"BACKGROUND": "#71a0a5", "TEXT": "#212121", "INPUT": "#665c84", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#212121", + "BUTTON": ("#fab95b", "#665c84"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#212121", "#665c84", "#71a0a5", "#fab95b"], }, + "DarkRed1": {"BACKGROUND": "#c10000", "TEXT": "#eeeeee", "INPUT": "#dedede", "TEXT_INPUT": "#000000", "SCROLL": "#dedede", "BUTTON": ("#c10000", "#eeeeee"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#c10000", "#ff4949", "#dedede", "#eeeeee"], }, + "LightBrown5": {"BACKGROUND": "#fff591", "TEXT": "#e41749", "INPUT": "#f5587b", "TEXT_INPUT": "#000000", "SCROLL": "#e41749", + "BUTTON": ("#fff591", "#e41749"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#e41749", "#f5587b", "#ff8a5c", "#fff591"], }, + "LightGreen9": {"BACKGROUND": "#f1edb3", "TEXT": "#3b503d", "INPUT": "#4a746e", "TEXT_INPUT": "#f1edb3", "SCROLL": "#3b503d", + "BUTTON": ("#f1edb3", "#3b503d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3b503d", "#4a746e", "#c8cf94", "#f1edb3"], "DESCRIPTION": ["Green", "Turquoise", "Yellow"], }, + "DarkGreen2": {"BACKGROUND": "#3b503d", "TEXT": "#f1edb3", "INPUT": "#c8cf94", "TEXT_INPUT": "#000000", "SCROLL": "#c8cf94", + "BUTTON": ("#f1edb3", "#3b503d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3b503d", "#4a746e", "#c8cf94", "#f1edb3"], "DESCRIPTION": ["Green", "Turquoise", "Yellow"], }, + "LightGray1": {"BACKGROUND": "#f2f2f2", "TEXT": "#222831", "INPUT": "#393e46", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#222831", + "BUTTON": ("#f2f2f2", "#222831"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#222831", "#393e46", "#f96d00", "#f2f2f2"], "DESCRIPTION": ["#000000", "Grey", "Orange", "Grey", "Autumn"], }, + "DarkGrey4": {"BACKGROUND": "#52524e", "TEXT": "#e9e9e5", "INPUT": "#d4d6c8", "TEXT_INPUT": "#000000", "SCROLL": "#d4d6c8", + "BUTTON": ("#FFFFFF", "#9a9b94"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#52524e", "#9a9b94", "#d4d6c8", "#e9e9e5"], "DESCRIPTION": ["Grey", "Pastel", "Winter"], }, + "DarkBlue12": {"BACKGROUND": "#324e7b", "TEXT": "#f8f8f8", "INPUT": "#86a6df", "TEXT_INPUT": "#000000", "SCROLL": "#86a6df", + "BUTTON": ("#FFFFFF", "#5068a9"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#324e7b", "#5068a9", "#86a6df", "#f8f8f8"], "DESCRIPTION": ["Blue", "Grey", "Cold", "Winter"], }, + "DarkPurple6": {"BACKGROUND": "#070739", "TEXT": "#e1e099", "INPUT": "#c327ab", "TEXT_INPUT": "#e1e099", "SCROLL": "#c327ab", + "BUTTON": ("#e1e099", "#521477"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#070739", "#521477", "#c327ab", "#e1e099"], "DESCRIPTION": ["#000000", "Purple", "Yellow", "Dark"], }, + "DarkPurple7": {"BACKGROUND": "#191930", "TEXT": "#B1B7C5", "INPUT": "#232B5C", "TEXT_INPUT": "#D0E3E7", "SCROLL": "#B1B7C5", + "BUTTON": ("#272D38", "#B1B7C5"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBlue13": {"BACKGROUND": "#203562", "TEXT": "#e3e8f8", "INPUT": "#c0c5cd", "TEXT_INPUT": "#000000", "SCROLL": "#c0c5cd", + "BUTTON": ("#FFFFFF", "#3e588f"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#203562", "#3e588f", "#c0c5cd", "#e3e8f8"], "DESCRIPTION": ["Blue", "Grey", "Wedding", "Cold"], }, + "DarkBrown5": {"BACKGROUND": "#3c1b1f", "TEXT": "#f6e1b5", "INPUT": "#e2bf81", "TEXT_INPUT": "#000000", "SCROLL": "#e2bf81", + "BUTTON": ("#3c1b1f", "#f6e1b5"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3c1b1f", "#b21e4b", "#e2bf81", "#f6e1b5"], "DESCRIPTION": ["Brown", "Red", "Yellow", "Warm"], }, + "DarkGreen3": {"BACKGROUND": "#062121", "TEXT": "#eeeeee", "INPUT": "#e4dcad", "TEXT_INPUT": "#000000", "SCROLL": "#e4dcad", + "BUTTON": ("#eeeeee", "#181810"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#062121", "#181810", "#e4dcad", "#eeeeee"], "DESCRIPTION": ["#000000", "#000000", "Brown", "Grey"], }, + "DarkBlack1": {"BACKGROUND": "#181810", "TEXT": "#eeeeee", "INPUT": "#e4dcad", "TEXT_INPUT": "#000000", "SCROLL": "#e4dcad", + "BUTTON": ("#FFFFFF", "#062121"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#062121", "#181810", "#e4dcad", "#eeeeee"], "DESCRIPTION": ["#000000", "#000000", "Brown", "Grey"], }, + "DarkGrey5": {"BACKGROUND": "#343434", "TEXT": "#f3f3f3", "INPUT": "#e9dcbe", "TEXT_INPUT": "#000000", "SCROLL": "#e9dcbe", + "BUTTON": ("#FFFFFF", "#8e8b82"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#343434", "#8e8b82", "#e9dcbe", "#f3f3f3"], "DESCRIPTION": ["Grey", "Brown"], }, + "LightBrown12": {"BACKGROUND": "#8e8b82", "TEXT": "#f3f3f3", "INPUT": "#e9dcbe", "TEXT_INPUT": "#000000", "SCROLL": "#e9dcbe", + "BUTTON": ("#f3f3f3", "#8e8b82"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#343434", "#8e8b82", "#e9dcbe", "#f3f3f3"], "DESCRIPTION": ["Grey", "Brown"], }, + "DarkTeal9": {"BACKGROUND": "#13445a", "TEXT": "#fef4e8", "INPUT": "#446878", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#446878", + "BUTTON": ("#fef4e8", "#446878"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#13445a", "#970747", "#446878", "#fef4e8"], "DESCRIPTION": ["Red", "Grey", "Blue", "Wedding", "Retro"], }, + "DarkBlue14": {"BACKGROUND": "#21273d", "TEXT": "#f1f6f8", "INPUT": "#b9d4f1", "TEXT_INPUT": "#000000", "SCROLL": "#b9d4f1", + "BUTTON": ("#FFFFFF", "#6a759b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#21273d", "#6a759b", "#b9d4f1", "#f1f6f8"], "DESCRIPTION": ["Blue", "#000000", "Grey", "Cold", "Winter"], }, + "LightBlue6": {"BACKGROUND": "#f1f6f8", "TEXT": "#21273d", "INPUT": "#6a759b", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#21273d", + "BUTTON": ("#f1f6f8", "#6a759b"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#21273d", "#6a759b", "#b9d4f1", "#f1f6f8"], "DESCRIPTION": ["Blue", "#000000", "Grey", "Cold", "Winter"], }, + "DarkGreen4": {"BACKGROUND": "#044343", "TEXT": "#e4e4e4", "INPUT": "#045757", "TEXT_INPUT": "#e4e4e4", "SCROLL": "#045757", + "BUTTON": ("#e4e4e4", "#045757"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#222222", "#044343", "#045757", "#e4e4e4"], "DESCRIPTION": ["#000000", "Turquoise", "Grey", "Dark"], }, + "DarkGreen5": {"BACKGROUND": "#1b4b36", "TEXT": "#e0e7f1", "INPUT": "#aebd77", "TEXT_INPUT": "#000000", "SCROLL": "#aebd77", + "BUTTON": ("#FFFFFF", "#538f6a"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#1b4b36", "#538f6a", "#aebd77", "#e0e7f1"], "DESCRIPTION": ["Green", "Grey"], }, + "DarkTeal10": {"BACKGROUND": "#0d3446", "TEXT": "#d8dfe2", "INPUT": "#71adb5", "TEXT_INPUT": "#000000", "SCROLL": "#71adb5", + "BUTTON": ("#FFFFFF", "#176d81"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#0d3446", "#176d81", "#71adb5", "#d8dfe2"], "DESCRIPTION": ["Grey", "Turquoise", "Winter", "Cold"], }, + "DarkGrey6": {"BACKGROUND": "#3e3e3e", "TEXT": "#ededed", "INPUT": "#68868c", "TEXT_INPUT": "#ededed", "SCROLL": "#68868c", + "BUTTON": ("#FFFFFF", "#405559"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3e3e3e", "#405559", "#68868c", "#ededed"], "DESCRIPTION": ["Grey", "Turquoise", "Winter"], }, + "DarkTeal11": {"BACKGROUND": "#405559", "TEXT": "#ededed", "INPUT": "#68868c", "TEXT_INPUT": "#ededed", "SCROLL": "#68868c", + "BUTTON": ("#ededed", "#68868c"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#3e3e3e", "#405559", "#68868c", "#ededed"], "DESCRIPTION": ["Grey", "Turquoise", "Winter"], }, + "LightBlue7": {"BACKGROUND": "#9ed0e0", "TEXT": "#19483f", "INPUT": "#5c868e", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#19483f", + "BUTTON": ("#FFFFFF", "#19483f"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#19483f", "#5c868e", "#ff6a38", "#9ed0e0"], "DESCRIPTION": ["Orange", "Blue", "Turquoise"], }, + "LightGreen10": {"BACKGROUND": "#d8ebb5", "TEXT": "#205d67", "INPUT": "#639a67", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#205d67", + "BUTTON": ("#d8ebb5", "#205d67"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#205d67", "#639a67", "#d9bf77", "#d8ebb5"], "DESCRIPTION": ["Blue", "Green", "Brown", "Vintage"], }, + "DarkBlue15": {"BACKGROUND": "#151680", "TEXT": "#f1fea4", "INPUT": "#375fc0", "TEXT_INPUT": "#f1fea4", "SCROLL": "#375fc0", + "BUTTON": ("#f1fea4", "#1c44ac"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#151680", "#1c44ac", "#375fc0", "#f1fea4"], "DESCRIPTION": ["Blue", "Yellow", "Cold"], }, + "DarkBlue16": {"BACKGROUND": "#1c44ac", "TEXT": "#f1fea4", "INPUT": "#375fc0", "TEXT_INPUT": "#f1fea4", "SCROLL": "#375fc0", + "BUTTON": ("#f1fea4", "#151680"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#151680", "#1c44ac", "#375fc0", "#f1fea4"], "DESCRIPTION": ["Blue", "Yellow", "Cold"], }, + "DarkTeal12": {"BACKGROUND": "#004a7c", "TEXT": "#fafafa", "INPUT": "#e8f1f5", "TEXT_INPUT": "#000000", "SCROLL": "#e8f1f5", + "BUTTON": ("#fafafa", "#005691"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#004a7c", "#005691", "#e8f1f5", "#fafafa"], "DESCRIPTION": ["Grey", "Blue", "Cold", "Winter"], }, + "LightBrown13": {"BACKGROUND": "#ebf5ee", "TEXT": "#921224", "INPUT": "#bdc6b8", "TEXT_INPUT": "#921224", "SCROLL": "#921224", + "BUTTON": ("#FFFFFF", "#921224"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#921224", "#bdc6b8", "#bce0da", "#ebf5ee"], "DESCRIPTION": ["Red", "Blue", "Grey", "Vintage", "Wedding"], }, + "DarkBlue17": {"BACKGROUND": "#21294c", "TEXT": "#f9f2d7", "INPUT": "#f2dea8", "TEXT_INPUT": "#000000", "SCROLL": "#f2dea8", + "BUTTON": ("#f9f2d7", "#141829"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#141829", "#21294c", "#f2dea8", "#f9f2d7"], "DESCRIPTION": ["#000000", "Blue", "Yellow"], }, + "DarkBrown6": {"BACKGROUND": "#785e4d", "TEXT": "#f2eee3", "INPUT": "#baaf92", "TEXT_INPUT": "#000000", "SCROLL": "#baaf92", + "BUTTON": ("#FFFFFF", "#785e4d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#785e4d", "#ff8426", "#baaf92", "#f2eee3"], "DESCRIPTION": ["Grey", "Brown", "Orange", "Autumn"], }, + "DarkGreen6": {"BACKGROUND": "#5c715e", "TEXT": "#f2f9f1", "INPUT": "#ddeedf", "TEXT_INPUT": "#000000", "SCROLL": "#ddeedf", + "BUTTON": ("#f2f9f1", "#5c715e"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#5c715e", "#b6cdbd", "#ddeedf", "#f2f9f1"], "DESCRIPTION": ["Grey", "Green", "Vintage"], }, + "DarkGreen7": {"BACKGROUND": "#0C231E", "TEXT": "#efbe1c", "INPUT": "#153C33", "TEXT_INPUT": "#efbe1c", "SCROLL": "#153C33", + "BUTTON": ("#efbe1c", "#153C33"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey7": {"BACKGROUND": "#4b586e", "TEXT": "#dddddd", "INPUT": "#574e6d", "TEXT_INPUT": "#dddddd", "SCROLL": "#574e6d", + "BUTTON": ("#dddddd", "#43405d"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#43405d", "#4b586e", "#574e6d", "#dddddd"], "DESCRIPTION": ["Grey", "Winter", "Cold"], }, + "DarkRed2": {"BACKGROUND": "#ab1212", "TEXT": "#f6e4b5", "INPUT": "#cd3131", "TEXT_INPUT": "#f6e4b5", "SCROLL": "#cd3131", "BUTTON": ("#f6e4b5", "#ab1212"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#ab1212", "#1fad9f", "#cd3131", "#f6e4b5"], "DESCRIPTION": ["Turquoise", "Red", "Yellow"], }, + "LightGrey6": {"BACKGROUND": "#e3e3e3", "TEXT": "#233142", "INPUT": "#455d7a", "TEXT_INPUT": "#e3e3e3", "SCROLL": "#233142", + "BUTTON": ("#e3e3e3", "#455d7a"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, + "COLOR_LIST": ["#233142", "#455d7a", "#f95959", "#e3e3e3"], "DESCRIPTION": ["#000000", "Blue", "Red", "Grey"], }, + "HotDogStand": {"BACKGROUND": "red", "TEXT": "yellow", "INPUT": "yellow", "TEXT_INPUT": "#000000", "SCROLL": "yellow", "BUTTON": ("red", "yellow"), + "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey8": {"BACKGROUND": "#19232D", "TEXT": "#ffffff", "INPUT": "#32414B", "TEXT_INPUT": "#ffffff", "SCROLL": "#505F69", + "BUTTON": ("#ffffff", "#32414B"), "PROGRESS": ("#505F69", "#32414B"), "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey9": {"BACKGROUND": "#36393F", "TEXT": "#DCDDDE", "INPUT": "#40444B", "TEXT_INPUT": "#ffffff", "SCROLL": "#202225", + "BUTTON": ("#202225", "#B9BBBE"), "PROGRESS": ("#202225", "#40444B"), "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey10": {"BACKGROUND": "#1c1e23", "TEXT": "#cccdcf", "INPUT": "#272a31", "TEXT_INPUT": "#8b9fde", "SCROLL": "#313641", + "BUTTON": ("#f5f5f6", "#2e3d5a"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey11": {"BACKGROUND": "#1c1e23", "TEXT": "#cccdcf", "INPUT": "#313641", "TEXT_INPUT": "#cccdcf", "SCROLL": "#313641", + "BUTTON": ("#f5f5f6", "#313641"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey12": {"BACKGROUND": "#1c1e23", "TEXT": "#8b9fde", "INPUT": "#313641", "TEXT_INPUT": "#8b9fde", "SCROLL": "#313641", + "BUTTON": ("#cccdcf", "#2e3d5a"), "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey13": {"BACKGROUND": "#1c1e23", "TEXT": "#cccdcf", "INPUT": "#272a31", "TEXT_INPUT": "#cccdcf", "SCROLL": "#313641", + "BUTTON": ("#8b9fde", "#313641"), "PROGRESS": ("#cccdcf", "#272a31"), "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkGrey14": {"BACKGROUND": "#24292e", "TEXT": "#fafbfc", "INPUT": "#1d2125", "TEXT_INPUT": "#fafbfc", "SCROLL": "#1d2125", + "BUTTON": ("#fafbfc", "#155398"), "PROGRESS": ("#155398", "#1d2125"), "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, }, + "DarkBrown7": {"BACKGROUND": "#2c2417", "TEXT": "#baa379", "INPUT": "#baa379", "TEXT_INPUT": "#000000", "SCROLL": "#392e1c", + "BUTTON": ("#000000", "#baa379"), "PROGRESS": ("#baa379", "#453923"), "BORDER": 1, "SLIDER_DEPTH": 1, "PROGRESS_DEPTH": 0, }, + "Python": {"BACKGROUND": "#3d7aab", "TEXT": "#ffde56", "INPUT": "#295273", "TEXT_INPUT": "#ffde56", "SCROLL": "#295273", "BUTTON": ("#ffde56", "#295273"), + "PROGRESS": ("#ffde56", "#295273"), "BORDER": 1, "SLIDER_DEPTH": 1, "PROGRESS_DEPTH": 0, }, } - def list_of_look_and_feel_values(): """ Get a list of the valid values to pass into your call to change_look_and_feel :return: list of valid string values - :rtype: List[str] + :rtype: List[str] """ return sorted(list(LOOK_AND_FEEL_TABLE.keys())) @@ -15683,9 +15806,9 @@ def theme(new_theme=None): This call replaces the ChangeLookAndFeel / change_look_and_feel call which only sets the theme. :param new_theme: the new theme name to use - :type new_theme: (str) - :return: the currently selected theme - :rtype: (str) + :type new_theme: (str) + :return: the currently selected theme + :rtype: (str) """ global TRANSPARENT_BUTTON @@ -15695,34 +15818,31 @@ def theme(new_theme=None): return CURRENT_LOOK_AND_FEEL - def theme_background_color(color=None): """ Sets/Returns the background color currently in use Used for Windows and containers (Column, Frame, Tab) and tables :param color: new background color to use (optional) - :type color: (str) - :return: color string of the background color currently in use - :rtype: (str) + :type color: (str) + :return: color string of the background color currently in use + :rtype: (str) """ if color is not None: set_options(background_color=color) return DEFAULT_BACKGROUND_COLOR - # This "constant" is misleading but rather than remove and break programs, will try this method instead TRANSPARENT_BUTTON = (theme_background_color(), theme_background_color()) # replaces an older version that had hardcoded numbers - def theme_element_background_color(color=None): """ Sets/Returns the background color currently in use for all elements except containers :return: (str) - color string of the element background color currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(element_background_color=color) @@ -15734,7 +15854,7 @@ def theme_text_color(color=None): Sets/Returns the text color currently in use :return: (str) - color string of the text color currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(text_color=color) @@ -15746,18 +15866,19 @@ def theme_text_element_background_color(color=None): Sets/Returns the background color for text elements :return: (str) - color string of the text background color currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(text_element_background_color=color) return DEFAULT_TEXT_ELEMENT_BACKGROUND_COLOR + def theme_input_background_color(color=None): """ Sets/Returns the input element background color currently in use :return: (str) - color string of the input element background color currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(input_elements_background_color=color) @@ -15769,20 +15890,19 @@ def theme_input_text_color(color=None): Sets/Returns the input element entry color (not the text but the thing that's displaying the text) :return: (str) - color string of the input element color currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(input_text_color=color) return DEFAULT_INPUT_TEXT_COLOR - def theme_button_color(color=None): """ Sets/Returns the button color currently in use :return: (str, str) - TUPLE with color strings of the button color currently in use (button text color, button background color) - :rtype: (str, str) + :rtype: (str, str) """ if color is not None: if color == COLOR_SYSTEM_DEFAULT: @@ -15794,7 +15914,7 @@ def theme_button_color(color=None): popup_error('theme_button_color - bad color string passed in', color) else: print('** Badly formatted button color... not a tuple nor string **', color) - set_options(button_color=color) # go ahead and try with their string + set_options(button_color=color) # go ahead and try with their string else: set_options(button_color=color_tuple) return DEFAULT_BUTTON_COLOR @@ -15805,7 +15925,7 @@ def theme_progress_bar_color(color=None): Sets/Returns the progress bar colors by the current color theme :return: (str, str) - TUPLE with color strings of the ProgressBar color currently in use(button text color, button background color) - :rtype: (str, str) + :rtype: (str, str) """ if color is not None: set_options(progress_meter_color=color) @@ -15817,7 +15937,7 @@ def theme_slider_color(color=None): Sets/Returns the slider color (used for sliders) :return: color string of the slider color currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(scrollbar_color=color) @@ -15830,7 +15950,7 @@ def theme_border_width(border_width=None): Used by non ttk elements at the moment :return: border width currently in use - :rtype: (int) + :rtype: (int) """ if border_width is not None: set_options(border_width=border_width) @@ -15842,7 +15962,7 @@ def theme_slider_border_width(border_width=None): Sets/Returns the slider border width currently in use :return: border width currently in use for sliders - :rtype: (int) + :rtype: (int) """ if border_width is not None: set_options(slider_border_width=border_width) @@ -15854,20 +15974,19 @@ def theme_progress_bar_border_width(border_width=None): Sets/Returns the progress meter border width currently in use :return: border width currently in use for progress meters - :rtype: (int) + :rtype: (int) """ if border_width is not None: set_options(progress_meter_border_depth=border_width) return DEFAULT_PROGRESS_BAR_BORDER_WIDTH - def theme_element_text_color(color=None): """ Sets/Returns the text color used by elements that have text as part of their display (Tables, Trees and Sliders) :return: color string currently in use - :rtype: (str) + :rtype: (str) """ if color is not None: set_options(element_text_color=color) @@ -15879,21 +15998,19 @@ def theme_list(): Returns a sorted list of the currently available color themes :return: A sorted list of the currently available color themes - :rtype: List[str] + :rtype: List[str] """ return list_of_look_and_feel_values() - - def theme_add_new(new_theme_name, new_theme_dict): """ Add a new theme to the dictionary of themes :param new_theme_name: text to display in element - :type new_theme_name: (str) + :type new_theme_name: (str) :param new_theme_dict: text to display in element - :type new_theme_dict: (dict) + :type new_theme_dict: (dict) """ global LOOK_AND_FEEL_TABLE try: @@ -15907,9 +16024,9 @@ def theme_global(new_theme=None): Sets / Gets the global PySimpleGUI Theme. If none is specified then returns the global theme from user settings :param new_theme: the new theme name to use - :type new_theme: (str) - :return: the currently selected theme - :rtype: (str) + :type new_theme: (str) + :return: the currently selected theme + :rtype: (str) """ if new_theme is not None: pysimplegui_user_settings.set('-theme-', new_theme) @@ -15924,22 +16041,23 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), Displays a "Quick Reference Window" showing all of the different Look and Feel settings that are available. They are sorted alphabetically. The legacy color names are mixed in, but otherwise they are sorted into Dark and Light halves - :param columns: The number of themes to display per row - :type columns: int - :param scrollable: If True then scrollbars will be added - :type scrollable: bool + :param columns: The number of themes to display per row + :type columns: int + :param scrollable: If True then scrollbars will be added + :type scrollable: bool :param scroll_area_size: Size of the scrollable area (The Column Element used to make scrollable) - :type scroll_area_size: (int, int) - :param search_string: If specified then only themes containing this string will be shown - :type search_string: str - :param location: Location on the screen to place the window. Defaults to the center like all windows - :type location: (int, int) + :type scroll_area_size: (int, int) + :param search_string: If specified then only themes containing this string will be shown + :type search_string: str + :param location: Location on the screen to place the window. Defaults to the center like all windows + :type location: (int, int) """ current_theme = theme() # Show a "splash" type message so the user doesn't give up waiting - popup_quick_message('Hang on for a moment, this will take a bit to create....', keep_on_top=True, background_color='red', text_color='#FFFFFF', auto_close=True, non_blocking=True) + popup_quick_message('Hang on for a moment, this will take a bit to create....', keep_on_top=True, background_color='red', text_color='#FFFFFF', + auto_close=True, non_blocking=True) web = False @@ -15949,11 +16067,10 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), return [[Text('Text element'), InputText('Input data here', size=(10, 1))], [Button('Ok'), Button('Disabled', disabled=True), Slider((1, 10), orientation='h', size=(5, 15))]] - names = list_of_look_and_feel_values() names.sort() if search_string not in (None, ''): - names = [name for name in names if search_string.lower().replace(" ","") in name.lower().replace(" ","")] + names = [name for name in names if search_string.lower().replace(" ", "") in name.lower().replace(" ", "")] if search_string not in (None, ''): layout = [[Text('Themes containing "{}"'.format(search_string), font='Default 18', background_color=win_bg)]] @@ -15967,13 +16084,13 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), if not count % columns: col_layout += [row] row = [] - row += [Frame(theme_name, sample_layout() if not web else [[T(theme_name)]] + sample_layout(), pad=(2,2))] + row += [Frame(theme_name, sample_layout() if not web else [[T(theme_name)]] + sample_layout(), pad=(2, 2))] if row: col_layout += [row] - layout += [[Column(col_layout, scrollable=scrollable, size=scroll_area_size, pad=(0,0), background_color=win_bg, key='-COL-')]] + layout += [[Column(col_layout, scrollable=scrollable, size=scroll_area_size, pad=(0, 0), background_color=win_bg, key='-COL-')]] window = Window('Preview of Themes', layout, background_color=win_bg, resizable=True, location=location, keep_on_top=True, finalize=True, modal=True) - window['-COL-'].expand(True, True, True) # needed so that col will expand with the window + window['-COL-'].expand(True, True, True) # needed so that col will expand with the window window.read(close=True) theme(current_theme) @@ -15981,13 +16098,12 @@ def theme_previewer(columns=12, scrollable=False, scroll_area_size=(None, None), preview_all_look_and_feel_themes = theme_previewer - def _theme_preview_window_swatches(): # Begin the layout with a header layout = [[Text('Themes as color swatches', text_color='white', background_color='black', font='Default 25')], [Text('Tooltip and right click a color to get the value', text_color='white', background_color='black', font='Default 15')], [Text('Left click a color to copy to clipboard', text_color='white', background_color='black', font='Default 15')]] - layout =[[Column(layout, element_justification='c', background_color='black')]] + layout = [[Column(layout, element_justification='c', background_color='black')]] # Create the pain part, the rows of Text with color swatches for i, theme_name in enumerate(theme_list()): theme(theme_name) @@ -15996,22 +16112,22 @@ def _theme_preview_window_swatches(): if theme_button_color() != COLOR_SYSTEM_DEFAULT: colors.append(theme_button_color()[0]) colors.append(theme_button_color()[1]) - colors = list(set(colors)) # de-duplicate items - row = [T(theme(), background_color='black', text_color='white', size=(20,1), justification='r')] + colors = list(set(colors)) # de-duplicate items + row = [T(theme(), background_color='black', text_color='white', size=(20, 1), justification='r')] for color in colors: if color != COLOR_SYSTEM_DEFAULT: - row.append(T(SYMBOL_SQUARE, text_color=color, background_color='black', pad=(0,0), font='DEFAUlT 20', right_click_menu=['Nothing',[color]], tooltip=color, enable_events=True, key=(i,color))) + row.append(T(SYMBOL_SQUARE, text_color=color, background_color='black', pad=(0, 0), font='DEFAUlT 20', right_click_menu=['Nothing', [color]], + tooltip=color, enable_events=True, key=(i, color))) layout += [row] # place layout inside of a Column so that it's scrollable - layout = [[Column(layout, size=(500, 900), scrollable=True,vertical_scroll_only=True, background_color='black')]] + layout = [[Column(layout, size=(500, 900), scrollable=True, vertical_scroll_only=True, background_color='black')]] # finish the layout by adding an exit button layout += [[B('Exit')]] -# create and return Window that uses the layout + # create and return Window that uses the layout return Window('Theme Color Swatches', layout, background_color='black', finalize=True, keep_on_top=True) - def theme_previewer_swatches(): """ Display themes in a window as color swatches. @@ -16025,13 +16141,13 @@ def theme_previewer_swatches(): # col_height = window.get_screen_size()[1]-200 # if window.size[1] > 100: # window.size = (window.size[0], col_height) - window.move(window.get_screen_size()[0]//2-window.size[0]//2, 0) + window.move(window.get_screen_size()[0] // 2 - window.size[0] // 2, 0) - while True: # Event Loop + while True: # Event Loop event, values = window.read() if event == WIN_CLOSED or event == 'Exit': break - if isinstance(event, tuple): # someone clicked a swatch + if isinstance(event, tuple): # someone clicked a swatch chosen_color = event[1] else: if event[0] == '#': # someone right clicked @@ -16045,6 +16161,7 @@ def theme_previewer_swatches(): window.close() theme(current_theme) + def change_look_and_feel(index, force=False): """ Change the "color scheme" of all future PySimpleGUI Windows. @@ -16060,11 +16177,11 @@ def change_look_and_feel(index, force=False): Default = The default settings (only button color is different than system default) Default1 = The full system default including the button (everything's gray... how sad... don't be all gray... please....) :param index: the name of the index into the Look and Feel table (does not have to be exact, can be "fuzzy") - :type index: (str) + :type index: (str) :param force: no longer used - :type force: (bool) - :return: None - :rtype: None + :type force: (bool) + :return: None + :rtype: None """ global CURRENT_LOOK_AND_FEEL @@ -16137,8 +16254,9 @@ def change_look_and_feel(index, force=False): # ------------------------ Color processing functions ------------------------ def _hex_to_hsl(hex): - r,g,b = _hex_to_rgb(hex) - return _rgb_to_hsl(r,g,b) + r, g, b = _hex_to_rgb(hex) + return _rgb_to_hsl(r, g, b) + def _hex_to_rgb(hex): hex = hex.lstrip('#') @@ -16152,7 +16270,7 @@ def _rgb_to_hsl(r, g, b): b = float(b) high = max(r, g, b) low = min(r, g, b) - h, s, v = ((high + low) / 2,)*3 + h, s, v = ((high + low) / 2,) * 3 if high == low: h = s = 0.0 else: @@ -16172,9 +16290,9 @@ def _hsl_to_rgb(h, s, l): def hue_to_rgb(p, q, t): t += 1 if t < 0 else 0 t -= 1 if t > 1 else 0 - if t < 1/6: return p + (q - p) * 6 * t - if t < 1/2: return q - if t < 2/3: p + (q - p) * (2/3 - t) * 6 + if t < 1 / 6: return p + (q - p) * 6 * t + if t < 1 / 2: return q + if t < 2 / 3: p + (q - p) * (2 / 3 - t) * 6 return p if s == 0: @@ -16182,31 +16300,34 @@ def _hsl_to_rgb(h, s, l): else: q = l * (1 + s) if l < 0.5 else l + s - l * s p = 2 * l - q - r = hue_to_rgb(p, q, h + 1/3) + r = hue_to_rgb(p, q, h + 1 / 3) g = hue_to_rgb(p, q, h) - b = hue_to_rgb(p, q, h - 1/3) + b = hue_to_rgb(p, q, h - 1 / 3) return r, g, b + def _hsv_to_hsl(h, s, v): - l = 0.5 * v * (2 - s) - s = v * s / (1 - fabs(2*l-1)) + l = 0.5 * v * (2 - s) + s = v * s / (1 - fabs(2 * l - 1)) return h, s, l + def _hsl_to_hsv(h, s, l): - v = (2*l + s*(1- fabs(2*l-1)))/2 - s = 2*(v-l)/v + v = (2 * l + s * (1 - fabs(2 * l - 1))) / 2 + s = 2 * (v - l) / v return h, s, v + # Converts an object's contents into a nice printable string. Great for dumping debug data def obj_to_string_single_obj(obj): """ Dumps an Object's values as a formatted string. Very nicely done. Great way to display an object's member variables in human form Returns only the top-most object's variables instead of drilling down to dispolay more :param obj: The object to display - :type obj: (Any) - :return: Formatted output of the object's values - :rtype: (str) + :type obj: (Any) + :return: Formatted output of the object's values + :rtype: (str) """ if obj is None: return 'None' @@ -16217,12 +16338,12 @@ def obj_to_string_single_obj(obj): def obj_to_string(obj, extra=' '): """ Dumps an Object's values as a formatted string. Very nicely done. Great way to display an object's member variables in human form - :param obj: The object to display - :type obj: (Any) + :param obj: The object to display + :type obj: (Any) :param extra: extra stuff (Default value = ' ') - :type extra: (str) - :return: Formatted output of the object's values - :rtype: (str) + :type extra: (str) + :return: Formatted output of the object's values + :rtype: (str) """ if obj is None: return 'None' @@ -16233,21 +16354,21 @@ def obj_to_string(obj, extra=' '): for item in sorted(obj.__dict__))) -#...######..##.......####.########..########...#######.....###....########..########. -#..##....##.##........##..##.....##.##.....##.##.....##...##.##...##.....##.##.....## -#..##.......##........##..##.....##.##.....##.##.....##..##...##..##.....##.##.....## -#..##.......##........##..########..########..##.....##.##.....##.########..##.....## -#..##.......##........##..##........##.....##.##.....##.#########.##...##...##.....## -#..##....##.##........##..##........##.....##.##.....##.##.....##.##....##..##.....## -#...######..########.####.##........########...#######..##.....##.##.....##.########. -#................................................................................ -#..########.##.....##.##....##..######..########.####..#######..##....##..######. -#..##.......##.....##.###...##.##....##....##.....##..##.....##.###...##.##....## -#..##.......##.....##.####..##.##..........##.....##..##.....##.####..##.##...... -#..######...##.....##.##.##.##.##..........##.....##..##.....##.##.##.##..######. -#..##.......##.....##.##..####.##..........##.....##..##.....##.##..####.......## -#..##.......##.....##.##...###.##....##....##.....##..##.....##.##...###.##....## -#..##........#######..##....##..######.....##....####..#######..##....##..######. +# ...######..##.......####.########..########...#######.....###....########..########. +# ..##....##.##........##..##.....##.##.....##.##.....##...##.##...##.....##.##.....## +# ..##.......##........##..##.....##.##.....##.##.....##..##...##..##.....##.##.....## +# ..##.......##........##..########..########..##.....##.##.....##.########..##.....## +# ..##.......##........##..##........##.....##.##.....##.#########.##...##...##.....## +# ..##....##.##........##..##........##.....##.##.....##.##.....##.##....##..##.....## +# ...######..########.####.##........########...#######..##.....##.##.....##.########. +# ................................................................................ +# ..########.##.....##.##....##..######..########.####..#######..##....##..######. +# ..##.......##.....##.###...##.##....##....##.....##..##.....##.###...##.##....## +# ..##.......##.....##.####..##.##..........##.....##..##.....##.####..##.##...... +# ..######...##.....##.##.##.##.##..........##.....##..##.....##.##.##.##..######. +# ..##.......##.....##.##..####.##..........##.....##..##.....##.##..####.......## +# ..##.......##.....##.##...###.##....##....##.....##..##.....##.##...###.##....## +# ..##........#######..##....##..######.....##....####..#######..##....##..######. def clipboard_set(new_value): """ @@ -16257,7 +16378,7 @@ def clipboard_set(new_value): need to stay running for Linux systems. :param new_value: value to set the clipboard to. Will be converted to a string - :type new_value: (str) + :type new_value: (str) """ # Create and use a temp window root = tk.Tk() @@ -16273,7 +16394,7 @@ def clipboard_get(): Gets the clipboard current value. :return: The current value of the clipboard - :rtype: (str) + :rtype: (str) """ # Create and use a temp window root = tk.Tk() @@ -16287,14 +16408,6 @@ def clipboard_get(): return value - - - - - - - - # MM"""""""`YM # MM mmmmm M # M' .M .d8888b. 88d888b. dP dP 88d888b. .d8888b. @@ -16308,53 +16421,55 @@ def clipboard_get(): # ------------------------------------------------------------------------------------------------------------------ # # ----------------------------------- The mighty Popup! ------------------------------------------------------------ # -def popup(*args, title=None, button_color=None, background_color=None, text_color=None, button_type=POPUP_BUTTONS_OK, auto_close=False, auto_close_duration=None, custom_text=(None, None), non_blocking=False, icon=None, line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), any_key_closes=False, image=None, modal=True): +def popup(*args, title=None, button_color=None, background_color=None, text_color=None, button_type=POPUP_BUTTONS_OK, auto_close=False, + auto_close_duration=None, custom_text=(None, None), non_blocking=False, icon=None, line_width=None, font=None, no_titlebar=False, grab_anywhere=False, + keep_on_top=False, location=(None, None), any_key_closes=False, image=None, modal=True): """ Popup - Display a popup Window with as many parms as you wish to include. This is the GUI equivalent of the "print" statement. It's also great for "pausing" your program's flow until the user can read some error messages. - :param *args: Variable number of your arguments. Load up the call with stuff to see! - :type *args: (Any) - :param title: Optional title for the window. If none provided, the first arg will be used instead. - :type title: (str) - :param button_color: Color of the buttons shown (text color, button color) - :type button_color: (str, str) | None - :param background_color: Window's background color - :type background_color: (str) - :param text_color: text color - :type text_color: (str) - :param button_type: NOT USER SET! Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). There are many Popup functions and they call Popup, changing this parameter to get the desired effect. - :type button_type: (int) - :param auto_close: If True the window will automatically close - :type auto_close: (bool) + :param *args: Variable number of your arguments. Load up the call with stuff to see! + :type *args: (Any) + :param title: Optional title for the window. If none provided, the first arg will be used instead. + :type title: (str) + :param button_color: Color of the buttons shown (text color, button color) + :type button_color: (str, str) | None + :param background_color: Window's background color + :type background_color: (str) + :param text_color: text color + :type text_color: (str) + :param button_type: NOT USER SET! Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). There are many Popup functions and they call Popup, changing this parameter to get the desired effect. + :type button_type: (int) + :param auto_close: If True the window will automatically close + :type auto_close: (bool) :param auto_close_duration: time in seconds to keep window open before closing it automatically - :type auto_close_duration: (int) - :param custom_text: A string or pair of strings that contain the text to display on the buttons - :type custom_text: (str, str) | str - :param non_blocking: If True then will immediately return from the function without waiting for the user's input. - :type non_blocking: (bool) - :param icon: icon to display on the window. Same format as a Window call - :type icon: str | bytes - :param line_width: Width of lines in characters. Defaults to MESSAGE_BOX_LINE_WIDTH - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[font_name, size, modifiers] - :param no_titlebar: If True will not show the frame around the window and the titlebar across the top - :type no_titlebar: (bool) - :param grab_anywhere: If True can grab anywhere to move the window. If no_titlebar is True, grab_anywhere should likely be enabled too - :type grab_anywhere: (bool) - :param location: Location on screen to display the top left corner of window. Defaults to window centered on screen - :type location: (int, int) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param any_key_closes: If True then will turn on return_keyboard_events for the window which will cause window to close as soon as any key is pressed. Normally the return key only will close the window. Default is false. - :type any_key_closes: (bool) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None + :type auto_close_duration: (int) + :param custom_text: A string or pair of strings that contain the text to display on the buttons + :type custom_text: (str, str) | str + :param non_blocking: If True then will immediately return from the function without waiting for the user's input. + :type non_blocking: (bool) + :param icon: icon to display on the window. Same format as a Window call + :type icon: str | bytes + :param line_width: Width of lines in characters. Defaults to MESSAGE_BOX_LINE_WIDTH + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[font_name, size, modifiers] + :param no_titlebar: If True will not show the frame around the window and the titlebar across the top + :type no_titlebar: (bool) + :param grab_anywhere: If True can grab anywhere to move the window. If no_titlebar is True, grab_anywhere should likely be enabled too + :type grab_anywhere: (bool) + :param location: Location on screen to display the top left corner of window. Defaults to window centered on screen + :type location: (int, int) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param any_key_closes: If True then will turn on return_keyboard_events for the window which will cause window to close as soon as any key is pressed. Normally the return key only will close the window. Default is false. + :type any_key_closes: (bool) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None """ if not args: @@ -16379,10 +16494,10 @@ def popup(*args, title=None, button_color=None, background_color=None, text_colo # fancy code to check if string and convert if not is not need. Just always convert to string :-) # if not isinstance(message, str): message = str(message) message = str(message) - if message.count('\n'): # if there are line breaks, then wrap each segment separately + if message.count('\n'): # if there are line breaks, then wrap each segment separately # message_wrapped = message # used to just do this, but now breaking into smaller pieces message_wrapped = '' - msg_list = message.split('\n') # break into segments that will each be wrapped + msg_list = message.split('\n') # break into segments that will each be wrapped message_wrapped = '\n'.join([textwrap.fill(msg, local_line_width) for msg in msg_list]) else: message_wrapped = textwrap.fill(message, local_line_width) @@ -16433,7 +16548,8 @@ def popup(*args, title=None, button_color=None, background_color=None, text_colo window = Window(_title, layout, auto_size_text=True, background_color=background_color, button_color=button_color, auto_close=auto_close, auto_close_duration=auto_close_duration, icon=icon, font=font, - no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, return_keyboard_events=any_key_closes, modal=modal) + no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, return_keyboard_events=any_key_closes, + modal=modal) if non_blocking: button, values = window.read(timeout=0) @@ -16462,51 +16578,52 @@ def MsgBox(*args): # ======================== Scrolled Text Box =====# # ===================================================# def popup_scrolled(*args, title=None, button_color=None, background_color=None, text_color=None, yes_no=False, auto_close=False, auto_close_duration=None, - size=(None, None), location=(None, None), non_blocking=False, no_titlebar=False, grab_anywhere=False, keep_on_top=False, font=None, image=None, icon=None, modal=True, no_sizegrip=False): + size=(None, None), location=(None, None), non_blocking=False, no_titlebar=False, grab_anywhere=False, keep_on_top=False, font=None, + image=None, icon=None, modal=True, no_sizegrip=False): """ Show a scrolled Popup window containing the user's text that was supplied. Use with as many items to print as you want, just like a print statement. - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param yes_no: If True, displays Yes and No buttons instead of Ok - :type yes_no: (bool) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param yes_no: If True, displays Yes and No buttons instead of Ok + :type yes_no: (bool) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param size: (w,h) w=characters-wide, h=rows-high - :type size: (int, int) - :param location: Location on the screen to place the upper left corner of the window - :type location: (int, int) - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True, than can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :param no_sizegrip: If True no Sizegrip will be shown when there is no titlebar. It's only shown if there is no titlebar - :type no_sizegrip: (bool) - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param size: (w,h) w=characters-wide, h=rows-high + :type size: (int, int) + :param location: Location on the screen to place the upper left corner of the window + :type location: (int, int) + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True, than can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :param no_sizegrip: If True no Sizegrip will be shown when there is no titlebar. It's only shown if there is no titlebar + :type no_sizegrip: (bool) + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ if not args: return width, height = size @@ -16536,7 +16653,8 @@ def popup_scrolled(*args, title=None, button_color=None, background_color=None, height_computed = MAX_SCROLLED_TEXT_BOX_HEIGHT if height_computed > MAX_SCROLLED_TEXT_BOX_HEIGHT else height_computed if height: height_computed = height - layout += [[Multiline(complete_output, size=(max_line_width, height_computed), background_color=background_color, text_color=text_color, expand_x=True, expand_y=True, k='-MLINE-')]] + layout += [[Multiline(complete_output, size=(max_line_width, height_computed), background_color=background_color, text_color=text_color, expand_x=True, + expand_y=True, k='-MLINE-')]] pad = max_line_total - 15 if max_line_total > 15 else 1 # show either an OK or Yes/No depending on paramater button = DummyButton if non_blocking else Button @@ -16560,7 +16678,6 @@ def popup_scrolled(*args, title=None, button_color=None, background_color=None, return button - # ============================== sprint ======# # Is identical to the Scrolled Text Box # # Provides a crude 'print' mechanism but in a # @@ -16570,45 +16687,44 @@ def popup_scrolled(*args, title=None, button_color=None, background_color=None, # ============================================# - # --------------------------- popup_no_buttons --------------------------- def popup_no_buttons(*args, title=None, background_color=None, text_color=None, auto_close=False, - auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, - no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, + no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """Show a Popup but without any buttons - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: If True then will immediately return from the function without waiting for the user's input. (Default = False) - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True, than can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY """ + :type auto_close_duration: int | float + :param non_blocking: If True then will immediately return from the function without waiting for the user's input. (Default = False) + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True, than can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ Popup(*args, title=title, background_color=background_color, text_color=text_color, button_type=POPUP_BUTTONS_NO_BUTTONS, auto_close=auto_close, auto_close_duration=auto_close_duration, non_blocking=non_blocking, icon=icon, @@ -16618,48 +16734,48 @@ def popup_no_buttons(*args, title=None, background_color=None, text_color=None, # --------------------------- popup_non_blocking --------------------------- def popup_non_blocking(*args, title=None, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, - text_color=None, auto_close=False, auto_close_duration=None, non_blocking=True, icon=None, - line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, - location=(None, None), image=None, modal=False): + text_color=None, auto_close=False, auto_close_duration=None, non_blocking=True, icon=None, + line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, + location=(None, None), image=None, modal=False): """ Show Popup window and immediately return (does not block) - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). - :type button_type: (int) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). + :type button_type: (int) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = False - :type modal: bool - :return: Reason for popup closing - :rtype: str | None + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = False + :type modal: bool + :return: Reason for popup closing + :rtype: str | None """ return popup(*args, title=title, button_color=button_color, background_color=background_color, text_color=text_color, @@ -16669,54 +16785,51 @@ def popup_non_blocking(*args, title=None, button_type=POPUP_BUTTONS_OK, button_c font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, image=image, modal=modal) - - - # --------------------------- popup_quick - a NonBlocking, Self-closing Popup --------------------------- def popup_quick(*args, title=None, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, - text_color=None, auto_close=True, auto_close_duration=2, non_blocking=True, icon=None, line_width=None, - font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=False): + text_color=None, auto_close=True, auto_close_duration=2, non_blocking=True, icon=None, line_width=None, + font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=False): """ Show Popup box that doesn't block and closes itself - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). - :type button_type: (int) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). + :type button_type: (int) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = False - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = False + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ return popup(*args, title=title, button_color=button_color, background_color=background_color, text_color=text_color, @@ -16728,49 +16841,49 @@ def popup_quick(*args, title=None, button_type=POPUP_BUTTONS_OK, button_color=No # --------------------------- popup_quick_message - a NonBlocking, Self-closing Popup with no titlebar and no buttons --------------------------- def popup_quick_message(*args, title=None, button_type=POPUP_BUTTONS_NO_BUTTONS, button_color=None, background_color=None, - text_color=None, auto_close=True, auto_close_duration=2, non_blocking=True, icon=None, line_width=None, - font=None, no_titlebar=True, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=False): + text_color=None, auto_close=True, auto_close_duration=2, non_blocking=True, icon=None, line_width=None, + font=None, no_titlebar=True, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=False): """ Show Popup window with no titlebar, doesn't block, and auto closes itself. - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). - :type button_type: (int) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). + :type button_type: (int) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = False - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = False + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ return popup(*args, title=title, button_color=button_color, background_color=background_color, text_color=text_color, button_type=button_type, @@ -16781,47 +16894,47 @@ def popup_quick_message(*args, title=None, button_type=POPUP_BUTTONS_NO_BUTTONS, # --------------------------- PopupNoTitlebar --------------------------- def popup_no_titlebar(*args, title=None, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, - text_color=None, auto_close=False, auto_close_duration=None, non_blocking=False, icon=None, - line_width=None, font=None, grab_anywhere=True, keep_on_top=False, location=(None, None), image=None, modal=True): + text_color=None, auto_close=False, auto_close_duration=None, non_blocking=False, icon=None, + line_width=None, font=None, grab_anywhere=True, keep_on_top=False, location=(None, None), image=None, modal=True): """ Display a Popup without a titlebar. Enables grab anywhere so you can move it - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). - :type button_type: (int) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). + :type button_type: (int) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ return popup(*args, title=title, button_color=button_color, background_color=background_color, text_color=text_color, button_type=button_type, @@ -16830,54 +16943,51 @@ def popup_no_titlebar(*args, title=None, button_type=POPUP_BUTTONS_OK, button_co font=font, no_titlebar=True, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, image=image, modal=modal) - - - # --------------------------- PopupAutoClose --------------------------- def popup_auto_close(*args, title=None, button_type=POPUP_BUTTONS_OK, button_color=None, background_color=None, text_color=None, - auto_close=True, auto_close_duration=None, non_blocking=False, icon=None, - line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, - location=(None, None), image=None, modal=True): + auto_close=True, auto_close_duration=None, non_blocking=False, icon=None, + line_width=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, + location=(None, None), image=None, modal=True): """Popup that closes itself after some time period - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). - :type button_type: (int) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_type: Determines which pre-defined buttons will be shown (Default value = POPUP_BUTTONS_OK). + :type button_type: (int) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ return popup(*args, title=title, button_color=button_color, background_color=background_color, text_color=text_color, @@ -16887,52 +16997,49 @@ def popup_auto_close(*args, title=None, button_type=POPUP_BUTTONS_OK, button_col font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, image=image, modal=modal) - - - # --------------------------- popup_error --------------------------- def popup_error(*args, title=None, button_color=(None, None), background_color=None, text_color=None, auto_close=False, - auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, - no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, + no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """ Popup with colored button and 'Error' as button text - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ tbutton_color = DEFAULT_ERROR_BUTTON_COLOR if button_color == (None, None) else button_color return popup(*args, title=title, button_type=POPUP_BUTTONS_ERROR, background_color=background_color, text_color=text_color, @@ -16944,47 +17051,47 @@ def popup_error(*args, title=None, button_color=(None, None), background_color=N # --------------------------- popup_cancel --------------------------- def popup_cancel(*args, title=None, button_color=None, background_color=None, text_color=None, auto_close=False, - auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, - no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, + no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """ Display Popup with "cancelled" button text - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ return popup(*args, title=title, button_type=POPUP_BUTTONS_CANCELLED, background_color=background_color, text_color=text_color, @@ -16995,47 +17102,47 @@ def popup_cancel(*args, title=None, button_color=None, background_color=None, te # --------------------------- popup_ok --------------------------- def popup_ok(*args, title=None, button_color=None, background_color=None, text_color=None, auto_close=False, - auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, - no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, + no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """ Display Popup with OK button only - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Returns text of the button that was pressed. None will be returned if user closed window with X - :rtype: str | None | TIMEOUT_KEY + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Returns text of the button that was pressed. None will be returned if user closed window with X + :rtype: str | None | TIMEOUT_KEY """ return popup(*args, title=title, button_type=POPUP_BUTTONS_OK, background_color=background_color, text_color=text_color, non_blocking=non_blocking, icon=icon, line_width=line_width, button_color=button_color, auto_close=auto_close, @@ -17045,47 +17152,47 @@ def popup_ok(*args, title=None, button_color=None, background_color=None, text_c # --------------------------- popup_ok_cancel --------------------------- def popup_ok_cancel(*args, title=None, button_color=None, background_color=None, text_color=None, auto_close=False, - auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None, font=None, - no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + auto_close_duration=None, non_blocking=False, icon=DEFAULT_WINDOW_ICON, line_width=None, font=None, + no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """ Display popup with OK and Cancel buttons - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: clicked button - :rtype: "OK" | "Cancel" | None + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: clicked button + :rtype: "OK" | "Cancel" | None """ return popup(*args, title=title, button_type=POPUP_BUTTONS_OK_CANCEL, background_color=background_color, text_color=text_color, @@ -17096,47 +17203,47 @@ def popup_ok_cancel(*args, title=None, button_color=None, background_color=None, # --------------------------- popup_yes_no --------------------------- def popup_yes_no(*args, title=None, button_color=None, background_color=None, text_color=None, auto_close=False, - auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, - no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + auto_close_duration=None, non_blocking=False, icon=None, line_width=None, font=None, + no_titlebar=False, grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """ Display Popup with Yes and No buttons - :param *args: Variable number of items to display - :type *args: (Any) - :param title: Title to display in the window. - :type title: (str) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param auto_close: if True window will close itself - :type auto_close: (bool) + :param *args: Variable number of items to display + :type *args: (Any) + :param title: Title to display in the window. + :type title: (str) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param auto_close: if True window will close itself + :type auto_close: (bool) :param auto_close_duration: Older versions only accept int. Time in seconds until window will close - :type auto_close_duration: int | float - :param non_blocking: if True the call will immediately return rather than waiting on user input - :type non_blocking: (bool) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param line_width: Width of lines in characters - :type line_width: (int) - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: clicked button - :rtype: "Yes" | "No" | None + :type auto_close_duration: int | float + :param non_blocking: if True the call will immediately return rather than waiting on user input + :type non_blocking: (bool) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param line_width: Width of lines in characters + :type line_width: (int) + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: clicked button + :rtype: "Yes" | "No" | None """ return popup(*args, title=title, button_type=POPUP_BUTTONS_YES_NO, background_color=background_color, text_color=text_color, @@ -17153,54 +17260,54 @@ def popup_yes_no(*args, title=None, button_color=None, background_color=None, te def popup_get_folder(message, title=None, default_path='', no_window=False, size=(None, None), button_color=None, - background_color=None, text_color=None, icon=None, font=None, no_titlebar=False, - grab_anywhere=False, keep_on_top=False, location=(None, None), initial_folder=None, image=None, modal=True, history=False, history_setting_filename=None): + background_color=None, text_color=None, icon=None, font=None, no_titlebar=False, + grab_anywhere=False, keep_on_top=False, location=(None, None), initial_folder=None, image=None, modal=True, history=False, + history_setting_filename=None): """ Display popup with text entry field and browse button so that a folder can be chosen. - :param message: message displayed to user - :type message: (str) - :param title: Window title - :type title: (str) - :param default_path: path to display to user as starting point (filled into the input field) - :type default_path: (str) - :param no_window: if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown - :type no_window: (bool) - :param size: (width, height) of the InputText Element - :type size: (int, int) - :param button_color: button color (foreground, background) - :type button_color: (str, str) or str - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param initial_folder: location in filesystem to begin browsing - :type initial_folder: (str) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :param history: If True then enable a "history" feature that will display previous entries used. Uses settings filename provided or default if none provided - :type history: bool + :param message: message displayed to user + :type message: (str) + :param title: Window title + :type title: (str) + :param default_path: path to display to user as starting point (filled into the input field) + :type default_path: (str) + :param no_window: if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown + :type no_window: (bool) + :param size: (width, height) of the InputText Element + :type size: (int, int) + :param button_color: button color (foreground, background) + :type button_color: (str, str) or str + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param initial_folder: location in filesystem to begin browsing + :type initial_folder: (str) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :param history: If True then enable a "history" feature that will display previous entries used. Uses settings filename provided or default if none provided + :type history: bool :param history_setting_filename: Filename to use for the User Settings. Will store list of previous entries in this settings file - :type history_setting_filename: (str) - :return: string representing the path chosen, None if cancelled or window closed with X - :rtype: str | None + :type history_setting_filename: (str) + :return: string representing the path chosen, None if cancelled or window closed with X + :rtype: str | None """ - # First setup the history settings file if history feature is enabled if history and history_setting_filename is not None: try: @@ -17273,13 +17380,14 @@ def popup_get_folder(message, title=None, default_path='', no_window=False, size else: file_list = history_settings.get('-PSG folder list-', []) last_entry = file_list[0] if file_list else '' - layout += [[Combo(file_list, default_value=last_entry, key='-INPUT-', size=size if size != (None, None) else (80,1), bind_return_key=True), + layout += [[Combo(file_list, default_value=last_entry, key='-INPUT-', size=size if size != (None, None) else (80, 1), bind_return_key=True), browse_button, Button('Clear History', tooltip='Clears the list of folders shown in the combobox')]] layout += [[Button('Ok', size=(6, 1), bind_return_key=True), Button('Cancel', size=(6, 1))]] window = Window(title=title or message, layout=layout, icon=icon, auto_size_text=True, button_color=button_color, - font=font, background_color=background_color, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, modal=modal) + font=font, background_color=background_color, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, + location=location, modal=modal) while True: event, values = window.read() @@ -17299,77 +17407,77 @@ def popup_get_folder(message, title=None, default_path='', no_window=False, size history_settings.set('-PSG folder list-', list_of_entries) break - window.close(); del window + window.close(); + del window if event in ('Cancel', WIN_CLOSED): return None return values['-INPUT-'] - # --------------------------- popup_get_file --------------------------- def popup_get_file(message, title=None, default_path='', default_extension='', save_as=False, multiple_files=False, - file_types=(("ALL Files", "*.*"),), - no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None, - icon=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, - location=(None, None), initial_folder=None, image=None, files_delimiter=BROWSE_FILES_DELIMITER, modal=True, history=False, history_setting_filename=None): + file_types=(("ALL Files", "*.*"),), + no_window=False, size=(None, None), button_color=None, background_color=None, text_color=None, + icon=None, font=None, no_titlebar=False, grab_anywhere=False, keep_on_top=False, + location=(None, None), initial_folder=None, image=None, files_delimiter=BROWSE_FILES_DELIMITER, modal=True, history=False, + history_setting_filename=None): """ Display popup window with text entry field and browse button so that a file can be chosen by user. - :param message: message displayed to user - :type message: (str) - :param title: Window title - :type title: (str) - :param default_path: path to display to user as starting point (filled into the input field) - :type default_path: (str) - :param default_extension: If no extension entered by user, add this to filename (only used in saveas dialogs) - :type default_extension: (str) - :param save_as: if True, the "save as" dialog is shown which will verify before overwriting - :type save_as: (bool) - :param multiple_files: if True, then allows multiple files to be selected that are returned with ';' between each filename - :type multiple_files: (bool) - :param file_types: List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) - :type file_types: Tuple[Tuple[str,str]] - :param no_window: if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown - :type no_window: (bool) - :param size: (width, height) of the InputText Element or Combo element if using history feature - :type size: (int, int) - :param button_color: Color of the button (text, background) - :type button_color: (str, str) or str - :param background_color: background color of the entire window - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: Location of upper left corner of the window - :type location: (int, int) - :param initial_folder: location in filesystem to begin browsing - :type initial_folder: (str) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param files_delimiter: String to place between files when multiple files are selected. Normally a ; - :type files_delimiter: str - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :param history: If True then enable a "history" feature that will display previous entries used. Uses settings filename provided or default if none provided - :type history: bool + :param message: message displayed to user + :type message: (str) + :param title: Window title + :type title: (str) + :param default_path: path to display to user as starting point (filled into the input field) + :type default_path: (str) + :param default_extension: If no extension entered by user, add this to filename (only used in saveas dialogs) + :type default_extension: (str) + :param save_as: if True, the "save as" dialog is shown which will verify before overwriting + :type save_as: (bool) + :param multiple_files: if True, then allows multiple files to be selected that are returned with ';' between each filename + :type multiple_files: (bool) + :param file_types: List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) + :type file_types: Tuple[Tuple[str,str]] + :param no_window: if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown + :type no_window: (bool) + :param size: (width, height) of the InputText Element or Combo element if using history feature + :type size: (int, int) + :param button_color: Color of the button (text, background) + :type button_color: (str, str) or str + :param background_color: background color of the entire window + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True: can grab anywhere to move the window (Default = False) + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: Location of upper left corner of the window + :type location: (int, int) + :param initial_folder: location in filesystem to begin browsing + :type initial_folder: (str) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param files_delimiter: String to place between files when multiple files are selected. Normally a ; + :type files_delimiter: str + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :param history: If True then enable a "history" feature that will display previous entries used. Uses settings filename provided or default if none provided + :type history: bool :param history_setting_filename: Filename to use for the User Settings. Will store list of previous entries in this settings file - :type history_setting_filename: (str) - :return: string representing the file(s) chosen, None if cancelled or window closed with X - :rtype: str | None + :type history_setting_filename: (str) + :return: string representing the file(s) chosen, None if cancelled or window closed with X + :rtype: str | None """ - # First setup the history settings file if history feature is enabled if history and history_setting_filename is not None: try: @@ -17452,7 +17560,6 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s else: browse_button = FileBrowse(file_types=file_types, initial_folder=initial_folder) - if image is not None: if isinstance(image, str): layout = [[Image(filename=image)]] @@ -17468,7 +17575,7 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s else: file_list = history_settings.get("-PSG file list-", []) last_entry = file_list[0] if file_list else '' - layout += [[Combo(file_list, default_value=last_entry, key='-INPUT-', size=size if size != (None, None) else (80,1), bind_return_key=True), + layout += [[Combo(file_list, default_value=last_entry, key='-INPUT-', size=size if size != (None, None) else (80, 1), bind_return_key=True), browse_button, Button('Clear History', tooltip='Clears the list of files shown in the combobox')]] layout += [[Button('Ok', size=(6, 1), bind_return_key=True), Button('Cancel', size=(6, 1))]] @@ -17496,59 +17603,58 @@ def popup_get_file(message, title=None, default_path='', default_extension='', s history_settings.set('-PSG file list-', list_of_entries) break - window.close(); del window + window.close(); + del window if event in ('Cancel', WIN_CLOSED): return None return values['-INPUT-'] - # --------------------------- popup_get_text --------------------------- def popup_get_text(message, title=None, default_text='', password_char='', size=(None, None), button_color=None, - background_color=None, text_color=None, icon=None, font=None, no_titlebar=False, - grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): + background_color=None, text_color=None, icon=None, font=None, no_titlebar=False, + grab_anywhere=False, keep_on_top=False, location=(None, None), image=None, modal=True): """ Display Popup with text entry field. Returns the text entered or None if closed / cancelled - :param message: message displayed to user - :type message: (str) - :param title: Window title - :type title: (str) - :param default_text: default value to put into input area - :type default_text: (str) - :param password_char: character to be shown instead of actually typed characters - :type password_char: (str) - :param size: (width, height) of the InputText Element - :type size: (int, int) - :param button_color: Color of the button (text, background) - :type button_color: (str, str) or str + :param message: message displayed to user + :type message: (str) + :param title: Window title + :type title: (str) + :param default_text: default value to put into input area + :type default_text: (str) + :param password_char: character to be shown instead of actually typed characters + :type password_char: (str) + :param size: (width, height) of the InputText Element + :type size: (int, int) + :param button_color: Color of the button (text, background) + :type button_color: (str, str) or str :param background_color: background color of the entire window - :type background_color: (str) - :param text_color: color of the message text - :type text_color: (str) - :param icon: filename or base64 string to be used for the window's icon - :type icon: bytes | str - :param font: specifies the font family, size, etc - :type font: str | Tuple[str, int] - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True can click and drag anywhere in the window to move the window - :type grab_anywhere: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param location: (x,y) Location on screen to display the upper left corner of window - :type location: (int, int) - :param image: Image to include at the top of the popup window - :type image: (str) or (bytes) - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Text entered or None if window was closed or cancel button clicked - :rtype: str | None + :type background_color: (str) + :param text_color: color of the message text + :type text_color: (str) + :param icon: filename or base64 string to be used for the window's icon + :type icon: bytes | str + :param font: specifies the font family, size, etc + :type font: str | Tuple[str, int] + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True can click and drag anywhere in the window to move the window + :type grab_anywhere: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param location: (x,y) Location on screen to display the upper left corner of window + :type location: (int, int) + :param image: Image to include at the top of the popup window + :type image: (str) or (bytes) + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Text entered or None if window was closed or cancel button clicked + :rtype: str | None """ - if image is not None: if isinstance(image, str): layout = [[Image(filename=image)]] @@ -17561,8 +17667,8 @@ def popup_get_text(message, title=None, default_text='', password_char='', size= [InputText(default_text=default_text, size=size, key='_INPUT_', password_char=password_char)], [Button('Ok', size=(6, 1), bind_return_key=True), Button('Cancel', size=(6, 1))]] - window = Window(title=title or message, layout=layout, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, background_color=background_color, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, finalize=True, modal=modal) - + window = Window(title=title or message, layout=layout, icon=icon, auto_size_text=True, button_color=button_color, no_titlebar=no_titlebar, + background_color=background_color, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, finalize=True, modal=modal) button, values = window.read() window.close() @@ -17574,41 +17680,41 @@ def popup_get_text(message, title=None, default_text='', password_char='', size= return path - -def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sunday_plus=0, no_titlebar=True, title='Choose Date', keep_on_top=True, location=(None, None), close_when_chosen=False, icon=None, locale=None, month_names=None, day_abbreviations=None, modal=True): +def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sunday_plus=0, no_titlebar=True, title='Choose Date', keep_on_top=True, + location=(None, None), close_when_chosen=False, icon=None, locale=None, month_names=None, day_abbreviations=None, modal=True): """ Display a calendar window, get the user's choice, return as a tuple (mon, day, year) - :param start_mon: The starting month - :type start_mon: (int) - :param start_day: The starting day - optional. Set to None or 0 if no date to be chosen at start - :type start_day: int | None - :param start_year: The starting year - :type start_year: (int) + :param start_mon: The starting month + :type start_mon: (int) + :param start_day: The starting day - optional. Set to None or 0 if no date to be chosen at start + :type start_day: int | None + :param start_year: The starting year + :type start_year: (int) :param begin_at_sunday_plus: Determines the left-most day in the display. 0=sunday, 1=monday, etc - :type begin_at_sunday_plus: (int) - :param icon: Same as Window icon parameter. Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO - :type icon: (str) - :param location: (x,y) location on the screen to place the top left corner of your window. Default is to center on screen - :type location: (int, int) - :param title: Title that will be shown on the window - :type title: (str) - :param close_when_chosen: If True, the window will close and function return when a day is clicked - :type close_when_chosen: (bool) - :param locale: locale used to get the day names - :type locale: (str) - :param no_titlebar: If True no titlebar will be shown - :type no_titlebar: (bool) - :param keep_on_top: If True the window will remain above all current windows - :type keep_on_top: (bool) - :param month_names: optional list of month names to use (should be 12 items) - :type month_names: List[str] - :param day_abbreviations: optional list of abbreviations to display as the day of week - :type day_abbreviations: List[str] - :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True - :type modal: bool - :return: Tuple containing (month, day, year) of chosen date or None if was cancelled - :rtype: None | (int, int, int) + :type begin_at_sunday_plus: (int) + :param icon: Same as Window icon parameter. Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO + :type icon: (str) + :param location: (x,y) location on the screen to place the top left corner of your window. Default is to center on screen + :type location: (int, int) + :param title: Title that will be shown on the window + :type title: (str) + :param close_when_chosen: If True, the window will close and function return when a day is clicked + :type close_when_chosen: (bool) + :param locale: locale used to get the day names + :type locale: (str) + :param no_titlebar: If True no titlebar will be shown + :type no_titlebar: (bool) + :param keep_on_top: If True the window will remain above all current windows + :type keep_on_top: (bool) + :param month_names: optional list of month names to use (should be 12 items) + :type month_names: List[str] + :param day_abbreviations: optional list of abbreviations to display as the day of week + :type day_abbreviations: List[str] + :param modal: If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True + :type modal: bool + :return: Tuple containing (month, day, year) of chosen date or None if was cancelled + :rtype: None | (int, int, int) """ if month_names is not None and len(month_names) != 12: @@ -17632,7 +17738,6 @@ def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sun cur_day = cur_day cur_year = start_year or cur_year - def update_days(window, month, year, begin_at_sunday_plus): [window[(week, day)].update('') for day in range(7) for week in range(6)] weeks = calendar.monthcalendar(year, month) @@ -17656,7 +17761,6 @@ def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sun days_layout.append(row) return days_layout - # Create table of month names and week day abbreviations if day_abbreviations is None or len(day_abbreviations) != 7: @@ -17668,25 +17772,27 @@ def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sun _cal = calendar.TextCalendar(fwday) day_names = _cal.formatweekheader(3).split() except Exception as e: - print('Exception building day names from locale', locale, e) + print('Exception building day names from locale', locale, e) day_names = ('Sun', 'Mon', 'Tue', 'Wed', 'Th', 'Fri', 'Sat') else: day_names = day_abbreviations - mon_names = month_names if month_names is not None and len(month_names) == 12 else [calendar.month_name[i] for i in range(1,13)] + mon_names = month_names if month_names is not None and len(month_names) == 12 else [calendar.month_name[i] for i in range(1, 13)] days_layout = make_days_layout() - layout = [[B('◄◄', font=arrow_font, border_width=0, key='-YEAR-DOWN-', pad=((10,2),2)), - B('◄', font=arrow_font, border_width=0, key='-MON-DOWN-', pad=(0,2)), - Text('{} {}'.format(mon_names[cur_month - 1], cur_year), size=(16, 1), justification='c', font=mon_year_font, key='-MON-YEAR-', pad=(0,2)), - B('►', font=arrow_font,border_width=0, key='-MON-UP-', pad=(0,2)), - B('►►', font=arrow_font,border_width=0, key='-YEAR-UP-', pad=(2,2))]] - layout += [[Col([[T(day_names[i - (7 - begin_at_sunday_plus) % 7], size=(4,1), font=day_font, background_color=theme_text_color(), text_color=theme_background_color(), pad=(0,0)) for i in range(7)]], background_color=theme_text_color(), pad=(0,0))]] + layout = [[B('◄◄', font=arrow_font, border_width=0, key='-YEAR-DOWN-', pad=((10, 2), 2)), + B('◄', font=arrow_font, border_width=0, key='-MON-DOWN-', pad=(0, 2)), + Text('{} {}'.format(mon_names[cur_month - 1], cur_year), size=(16, 1), justification='c', font=mon_year_font, key='-MON-YEAR-', pad=(0, 2)), + B('►', font=arrow_font, border_width=0, key='-MON-UP-', pad=(0, 2)), + B('►►', font=arrow_font, border_width=0, key='-YEAR-UP-', pad=(2, 2))]] + layout += [[Col([[T(day_names[i - (7 - begin_at_sunday_plus) % 7], size=(4, 1), font=day_font, background_color=theme_text_color(), + text_color=theme_background_color(), pad=(0, 0)) for i in range(7)]], background_color=theme_text_color(), pad=(0, 0))]] layout += days_layout if not close_when_chosen: - layout += [[Button('Ok', border_width=0,font='TkFixedFont 8'), Button('Cancel',border_width=0, font='TkFixedFont 8')]] + layout += [[Button('Ok', border_width=0, font='TkFixedFont 8'), Button('Cancel', border_width=0, font='TkFixedFont 8')]] - window = Window(title, layout, no_titlebar=no_titlebar, grab_anywhere=True, keep_on_top=keep_on_top, font='TkFixedFont 12', use_default_focus=False, location=location, finalize=True, icon=icon) + window = Window(title, layout, no_titlebar=no_titlebar, grab_anywhere=True, keep_on_top=keep_on_top, font='TkFixedFont 12', use_default_focus=False, + location=location, finalize=True, icon=icon) update_days(window, cur_month, cur_year, begin_at_sunday_plus) @@ -17696,22 +17802,22 @@ def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sun chosen_mon_day_year = cur_month, cur_day, cur_year for week in range(6): for day in range(7): - if window[(week,day)].DisplayText == str(cur_day): - window[(week,day)].update(background_color=theme_text_color(), text_color=theme_background_color()) - prev_choice = (week,day) + if window[(week, day)].DisplayText == str(cur_day): + window[(week, day)].update(background_color=theme_text_color(), text_color=theme_background_color()) + prev_choice = (week, day) break if modal: window.make_modal() - while True: # Event Loop + while True: # Event Loop event, values = window.read() if event in (None, 'Cancel'): chosen_mon_day_year = None break if event == 'Ok': break - if event in ('-MON-UP-', '-MON-DOWN-', '-YEAR-UP-','-YEAR-DOWN-'): + if event in ('-MON-UP-', '-MON-DOWN-', '-YEAR-UP-', '-YEAR-DOWN-'): cur_month += (event == '-MON-UP-') cur_month -= (event == '-MON-DOWN-') cur_year += (event == '-YEAR-UP-') @@ -17739,47 +17845,46 @@ def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sun return chosen_mon_day_year - - # --------------------------- PopupAnimated --------------------------- -def popup_animated(image_source, message=None, background_color=None, text_color=None, font=None, no_titlebar=True, grab_anywhere=True, keep_on_top=True, location=(None, None), alpha_channel=None, time_between_frames=0, transparent_color=None, title='', icon=None): +def popup_animated(image_source, message=None, background_color=None, text_color=None, font=None, no_titlebar=True, grab_anywhere=True, keep_on_top=True, + location=(None, None), alpha_channel=None, time_between_frames=0, transparent_color=None, title='', icon=None): """ Show animation one frame at a time. This function has its own internal clocking meaning you can call it at any frequency and the rate the frames of video is shown remains constant. Maybe your frames update every 30 ms but your event loop is running every 10 ms. You don't have to worry about delaying, just call it every time through the loop. - :param image_source: Either a filename or a base64 string. Use None to close the window. - :type image_source: str | bytes | None - :param message: An optional message to be shown with the animation - :type message: (str) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param font: specifies the font family, size, etc - :type font: str | tuple - :param no_titlebar: If True then the titlebar and window frame will not be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True then you can move the window just clicking anywhere on window, hold and drag - :type grab_anywhere: (bool) - :param keep_on_top: If True then Window will remain on top of all other windows currently shownn - :type keep_on_top: (bool) - :param location: (x,y) location on the screen to place the top left corner of your window. Default is to center on screen - :type location: (int, int) - :param alpha_channel: Window transparency 0 = invisible 1 = completely visible. Values between are see through - :type alpha_channel: (float) + :param image_source: Either a filename or a base64 string. Use None to close the window. + :type image_source: str | bytes | None + :param message: An optional message to be shown with the animation + :type message: (str) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param font: specifies the font family, size, etc + :type font: str | tuple + :param no_titlebar: If True then the titlebar and window frame will not be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True then you can move the window just clicking anywhere on window, hold and drag + :type grab_anywhere: (bool) + :param keep_on_top: If True then Window will remain on top of all other windows currently shownn + :type keep_on_top: (bool) + :param location: (x,y) location on the screen to place the top left corner of your window. Default is to center on screen + :type location: (int, int) + :param alpha_channel: Window transparency 0 = invisible 1 = completely visible. Values between are see through + :type alpha_channel: (float) :param time_between_frames: Amount of time in milliseconds between each frame - :type time_between_frames: (int) - :param transparent_color: This color will be completely see-through in your window. Can even click through - :type transparent_color: (str) - :param title: Title that will be shown on the window - :type title: (str) - :param icon: Same as Window icon parameter. Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO - :type icon: str - :return: True if the window updated OK. False if the window was closed - :rtype: bool + :type time_between_frames: (int) + :param transparent_color: This color will be completely see-through in your window. Can even click through + :type transparent_color: (str) + :param title: Title that will be shown on the window + :type title: (str) + :param icon: Same as Window icon parameter. Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO + :type icon: str + :return: True if the window updated OK. False if the window was closed + :rtype: bool """ if image_source is None: for image in Window._animated_popup_dict: @@ -17810,6 +17915,7 @@ def popup_animated(image_source, message=None, background_color=None, text_color # window.refresh() # call refresh instead of Read to save significant CPU time return True + # Popup Notify def popup_notify(*args, title='', icon=SYSTEM_TRAY_MESSAGE_ICON_INFORMATION, display_duration_in_ms=SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS, fade_in_duration=SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION, alpha=0.9, location=None): @@ -17820,22 +17926,22 @@ def popup_notify(*args, title='', icon=SYSTEM_TRAY_MESSAGE_ICON_INFORMATION, dis The return code specifies why the call is returning (e.g. did the user click the message to dismiss it) - :param title: Text to be shown at the top of the window in a larger font - :type title: (str) - :param message: Text message that makes up the majority of the window - :type message: (str) - :param icon: A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window - :type icon: bytes | str + :param title: Text to be shown at the top of the window in a larger font + :type title: (str) + :param message: Text message that makes up the majority of the window + :type message: (str) + :param icon: A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window + :type icon: bytes | str :param display_duration_in_ms: Number of milliseconds to show the window - :type display_duration_in_ms: (int) - :param fade_in_duration: Number of milliseconds to fade window in and out - :type fade_in_duration: (int) - :param alpha: Alpha channel. 0 - invisible 1 - fully visible - :type alpha: (float) - :param location: Location on the screen to display the window - :type location: (int, int) - :return: reason for returning - :rtype: (int) + :type display_duration_in_ms: (int) + :param fade_in_duration: Number of milliseconds to fade window in and out + :type fade_in_duration: (int) + :param alpha: Alpha channel. 0 - invisible 1 - fully visible + :type alpha: (float) + :param location: Location on the screen to display the window + :type location: (int, int) + :return: reason for returning + :rtype: (int) """ if not args: @@ -17858,15 +17964,14 @@ def popup_notify(*args, title='', icon=SYSTEM_TRAY_MESSAGE_ICON_INFORMATION, dis max_line_total = max(max_line_total, width_used) # height = _GetNumLinesNeeded(message, width_used) height = message_wrapped_lines - output += message_wrapped+'\n' + output += message_wrapped + '\n' total_lines += height message = output # def __init__(self, menu=None, filename=None, data=None, data_base64=None, tooltip=None, metadata=None): - return SystemTray.notify(title=title, message=message, icon=icon, display_duration_in_ms=display_duration_in_ms, fade_in_duration=fade_in_duration, alpha=alpha, location=location) - - + return SystemTray.notify(title=title, message=message, icon=icon, display_duration_in_ms=display_duration_in_ms, fade_in_duration=fade_in_duration, + alpha=alpha, location=location) def popup_menu(window, element, menu_def, title=None, location=(None, None)): @@ -17876,16 +17981,16 @@ def popup_menu(window, element, menu_def, title=None, location=(None, None)): The settings for the menu are obtained from the window parameter's Window - :param window: The window associated with the popup menu. The theme and right click menu settings for this window will be used - :type window: Window - :param element: An element in your window to associate the menu to. It can be any element - :type element: Element + :param window: The window associated with the popup menu. The theme and right click menu settings for this window will be used + :type window: Window + :param element: An element in your window to associate the menu to. It can be any element + :type element: Element :param menu_def: A menu definition. This will be the same format as used for Right Click Menus1 - :type menu_def: List[List[ List[str] | str ]] - :param title: The title that will be shown on the torn off menu window. Defaults to window titlr - :type title: str + :type menu_def: List[List[ List[str] | str ]] + :param title: The title that will be shown on the torn off menu window. Defaults to window titlr + :type title: str :param location: The location on the screen to place the window - :type location: (int, int) | (None, None) + :type location: (int, int) | (None, None) """ element._popup_menu_location = location @@ -17898,9 +18003,9 @@ def popup_menu(window, element, menu_def, title=None, location=(None, None)): top_menu.config(disabledforeground=window.right_click_menu_disabled_text_color) if window.right_click_menu_font is not None: top_menu.config(font=window.right_click_menu_font) - if window.right_click_menu_selected_colors[0] != COLOR_SYSTEM_DEFAULT: + if window.right_click_menu_selected_colors[0] != COLOR_SYSTEM_DEFAULT: top_menu.config(activeforeground=window.right_click_menu_selected_colors[0]) - if window.right_click_menu_selected_colors[1] != COLOR_SYSTEM_DEFAULT: + if window.right_click_menu_selected_colors[1] != COLOR_SYSTEM_DEFAULT: top_menu.config(activebackground=window.right_click_menu_selected_colors[1]) top_menu.config(title=window.Title if title is None else title) AddMenuItem(top_menu, menu_def[1], element, right_click_menu=True) @@ -17914,17 +18019,16 @@ def popup_error_with_traceback(title, *messages): Will show the same error window as PySimpleGUI uses internally. Has a button to take the user to the line of code you called this popup from - :param title: The title that will be shown in the popup's titlebar and in the first line of the window - :type title: str + :param title: The title that will be shown in the popup's titlebar and in the first line of the window + :type title: str :param messages: A variable number of lines of messages you wish to show your user - :type messages: *Any + :type messages: *Any """ # For now, call the function that PySimpleGUI uses internally _error_popup_with_traceback(str(title), *messages) - def _error_popup_with_traceback(title, *args): if SUPPRESS_ERROR_POPUPS: return @@ -17937,24 +18041,24 @@ def _error_popup_with_traceback(title, *args): error_message = line break if file_info_pysimplegui is None: - _error_popup_with_code(title,None, None, 'Did not find your error info') + _error_popup_with_code(title, None, None, 'Did not find your error info') return error_parts = None if error_message != '': error_parts = error_message.split(', ') - if len(error_parts) < 4: - error_message = error_parts[0]+'\n'+error_parts[1]+ '\n' + ''.join(error_parts[2:]) + if len(error_parts) < 4: + error_message = error_parts[0] + '\n' + error_parts[1] + '\n' + ''.join(error_parts[2:]) if error_parts is None: print('*** Error popup attempted but unable to parse error details ***') print(trace_details) return - filename = error_parts[0][error_parts[0].index('File ')+5:] - line_num = error_parts[1][error_parts[1].index('line ')+5:] + filename = error_parts[0][error_parts[0].index('File ') + 5:] + line_num = error_parts[1][error_parts[1].index('line ') + 5:] _error_popup_with_code(title, filename, line_num, error_message, *args) -def _error_popup_with_code(title, filename=None, line_num=None, *args): +def _error_popup_with_code(title, filename=None, line_num=None, *args): layout = [[Text('ERROR'), Text(title)], [Image(data=_random_error_emoji())]] # make max length of line be 90 chars and allow the height to vary based on number of needed lines @@ -17983,7 +18087,6 @@ def _error_popup_with_code(title, filename=None, line_num=None, *args): window.close() - ##################################################################### # Animated window while shell command is executed ##################################################################### @@ -17999,42 +18102,44 @@ def _process_thread(*args): __shell_process__ = None -def shell_with_animation(command, args=None, image_source=DEFAULT_BASE64_LOADING_GIF, message=None, background_color=None, text_color=None, font=None, no_titlebar=True, grab_anywhere=True, keep_on_top=True, location=(None, None), alpha_channel=None, time_between_frames=100, transparent_color=None): +def shell_with_animation(command, args=None, image_source=DEFAULT_BASE64_LOADING_GIF, message=None, background_color=None, text_color=None, font=None, + no_titlebar=True, grab_anywhere=True, keep_on_top=True, location=(None, None), alpha_channel=None, time_between_frames=100, + transparent_color=None): """ Execute a "shell command" (anything capable of being launched using subprocess.run) and while the command is running, show an animated popup so that the user knows that a long-running command is being executed. Without this mechanism, the GUI appears locked up. - :param command: The command to run - :type command: (str) - :param args: List of arguments - :type args: List[str] - :param image_source: Either a filename or a base64 string. - :type image_source: str | bytes - :param message: An optional message to be shown with the animation - :type message: (str) - :param background_color: color of background - :type background_color: (str) - :param text_color: color of the text - :type text_color: (str) - :param font: specifies the font family, size, etc - :type font: str | tuple - :param no_titlebar: If True then the titlebar and window frame will not be shown - :type no_titlebar: (bool) - :param grab_anywhere: If True then you can move the window just clicking anywhere on window, hold and drag - :type grab_anywhere: (bool) - :param keep_on_top: If True then Window will remain on top of all other windows currently shownn - :type keep_on_top: (bool) - :param location: (x,y) location on the screen to place the top left corner of your window. Default is to center on screen - :type location: (int, int) - :param alpha_channel: Window transparency 0 = invisible 1 = completely visible. Values between are see through - :type alpha_channel: (float) + :param command: The command to run + :type command: (str) + :param args: List of arguments + :type args: List[str] + :param image_source: Either a filename or a base64 string. + :type image_source: str | bytes + :param message: An optional message to be shown with the animation + :type message: (str) + :param background_color: color of background + :type background_color: (str) + :param text_color: color of the text + :type text_color: (str) + :param font: specifies the font family, size, etc + :type font: str | tuple + :param no_titlebar: If True then the titlebar and window frame will not be shown + :type no_titlebar: (bool) + :param grab_anywhere: If True then you can move the window just clicking anywhere on window, hold and drag + :type grab_anywhere: (bool) + :param keep_on_top: If True then Window will remain on top of all other windows currently shownn + :type keep_on_top: (bool) + :param location: (x,y) location on the screen to place the top left corner of your window. Default is to center on screen + :type location: (int, int) + :param alpha_channel: Window transparency 0 = invisible 1 = completely visible. Values between are see through + :type alpha_channel: (float) :param time_between_frames: Amount of time in milliseconds between each frame - :type time_between_frames: (int) - :param transparent_color: This color will be completely see-through in your window. Can even click through - :type transparent_color: (str) - :return: The resulting string output from stdout - :rtype: (str) + :type time_between_frames: (int) + :param transparent_color: This color will be completely see-through in your window. Can even click through + :type transparent_color: (str) + :return: The resulting string output from stdout + :rtype: (str) """ global __shell_process__ @@ -18049,14 +18154,16 @@ def shell_with_animation(command, args=None, image_source=DEFAULT_BASE64_LOADING # Poll to see if the thread is still running. If so, then continue showing the animation while True: - popup_animated(image_source=image_source, message=message, time_between_frames=time_between_frames, transparent_color=transparent_color, text_color=text_color, background_color=background_color, font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, keep_on_top=keep_on_top, location=location, alpha_channel=alpha_channel) - thread.join(timeout=time_between_frames/1000) + popup_animated(image_source=image_source, message=message, time_between_frames=time_between_frames, transparent_color=transparent_color, + text_color=text_color, background_color=background_color, font=font, no_titlebar=no_titlebar, grab_anywhere=grab_anywhere, + keep_on_top=keep_on_top, location=location, alpha_channel=alpha_channel) + thread.join(timeout=time_between_frames / 1000) if not thread.is_alive(): break - popup_animated(None) # stop running the animation + popup_animated(None) # stop running the animation - output = __shell_process__.__str__().replace('\\r\\n', '\n') # fix up the output string - output = output[output.index("stdout=b'")+9:-2] + output = __shell_process__.__str__().replace('\\r\\n', '\n') # fix up the output string + output = output[output.index("stdout=b'") + 9:-2] return output @@ -18091,7 +18198,7 @@ def _create_error_message(): Creates an error message containing the filename and line number of the users code that made the call into PySimpleGUI :return: Error string to display with file, line number, and line of code - :rtype: str + :rtype: str """ called_func = inspect.stack()[1].function @@ -18110,7 +18217,6 @@ def _create_error_message(): 'The error originated from:\n' + error_message - # .d8888b. 888 888 d8b # d88P Y88b 888 888 Y8P # Y88b. 888 888 @@ -18131,16 +18237,16 @@ def _create_error_message(): class UserSettings: # A reserved settings object for use by the setting functions. It's a way for users # to access the user settings without diarectly using the UserSettings class - _default_for_function_interface = None # type: UserSettings + _default_for_function_interface = None # type: UserSettings def __init__(self, filename=None, path=None, silent_on_error=False): """ User Settings :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str or None) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str or None) + :type filename: (str or None) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str or None) """ self.path = path self.filename = filename @@ -18151,7 +18257,6 @@ class UserSettings: if filename is not None or path is not None: self.load(filename=filename, path=path) - def __repr__(self): """ Converts the settings dictionary into a string for easy display @@ -18160,28 +18265,25 @@ class UserSettings: """ return str(self.dict) - def set_default_value(self, default): """ Set the value that will be returned if a requested setting is not found :param default: value to be returned if a setting is not found in the settings dictionary - :type default: Any + :type default: Any """ self.default_value = default - - def _compute_filename(self, filename=None, path=None): """ Creates the full filename given the path or the filename or both. :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str or None) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str or None) - :return: Tuple with (full filename, path, filename) - :rtype: Tuple[str, str, str] + :type filename: (str or None) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str or None) + :return: Tuple with (full filename, path, filename) + :rtype: Tuple[str, str, str] """ if filename is not None: dirname_from_filename = os.path.dirname(filename) # see if a path was provided as part of filename @@ -18196,8 +18298,8 @@ class UserSettings: if path is None: if self.path is not None: # path = self.path - path = os.path.expanduser(self.path) # expand user provided path in case it has user ~ in it. Don't think it'll hurt - elif DEFAULT_USER_SETTINGS_PATH is not None: # if user set the path manually system-wide using set options + path = os.path.expanduser(self.path) # expand user provided path in case it has user ~ in it. Don't think it'll hurt + elif DEFAULT_USER_SETTINGS_PATH is not None: # if user set the path manually system-wide using set options path = os.path.expanduser(DEFAULT_USER_SETTINGS_PATH) elif running_windows(): path = os.path.expanduser(DEFAULT_USER_SETTINGS_WIN_PATH) @@ -18211,15 +18313,14 @@ class UserSettings: full_filename = os.path.join(path, filename) return (full_filename, path, filename) - def set_location(self, filename=None, path=None): """ Sets the location of the settings file :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str or None) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str or None) + :type filename: (str or None) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str or None) """ cfull_filename, cpath, cfilename = self._compute_filename(filename=filename, path=path) @@ -18227,7 +18328,6 @@ class UserSettings: self.path = cpath self.full_filename = cfull_filename - def get_filename(self, filename=None, path=None): """ Sets the filename and path for your settings file. Either paramter can be optional. @@ -18241,29 +18341,28 @@ class UserSettings: can be combined so that the filename contains both the path and filename. :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str or None) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str or None) - :return: The full pathname of the settings file that has both the path and filename combined. - :rtype: (str) + :type filename: (str or None) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str or None) + :return: The full pathname of the settings file that has both the path and filename combined. + :rtype: (str) """ if filename is not None or path is not None or (filename is None and path is None): self.set_location(filename=filename, path=path) self.read() return self.full_filename - def save(self, filename=None, path=None): """ Saves the current settings dictionary. If a filename or path is specified in the call, then it will override any previously specitfied filename to create a new settings file. The settings dictionary is then saved to the newly defined file. :param filename: The fFilename to save to. Can specify a path or just the filename. If no filename specified, then the caller's filename will be used. - :type filename: (str or None) - :param path: The (optional) path to use to save the file. - :type path: (str or None) - :return: The full path and filename used to save the settings - :rtype: (str) + :type filename: (str or None) + :param path: The (optional) path to use to save the file. + :type path: (str or None) + :return: The full path and filename used to save the settings + :rtype: (str) """ if filename is not None or path is not None: self.set_location(filename=filename, path=path) @@ -18278,7 +18377,6 @@ class UserSettings: print(_create_error_message()) return self.full_filename - def load(self, filename=None, path=None): """ Specifies the path and filename to use for the settings and reads the contents of the file. @@ -18286,18 +18384,17 @@ class UserSettings: If no filename is specified, then the caller's filename will be used with the extension ".json" :param filename: Filename to load settings from (and save to in the future) - :type filename: (str or None) - :param path: Path to the file. Defaults to a specific folder depending on the operating system - :type path: (str or None) - :return: The settings dictionary (i.e. all settings) - :rtype: (dict) + :type filename: (str or None) + :param path: Path to the file. Defaults to a specific folder depending on the operating system + :type path: (str or None) + :return: The settings dictionary (i.e. all settings) + :rtype: (dict) """ if filename is not None or path is not None or self.full_filename is None: self.set_location(filename, path) self.read() return self.dict - def delete_file(self, filename=None, path=None): """ Deltes the filename and path for your settings file. Either paramter can be optional. @@ -18307,9 +18404,9 @@ class UserSettings: Also sets your current dictionary to a blank one. :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str or None) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str or None) + :type filename: (str or None) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str or None) """ if filename is not None or path is not None or (filename is None and path is None): self.set_location(filename=filename, path=path) @@ -18321,26 +18418,24 @@ class UserSettings: print(_create_error_message()) self.dict = {} - def write_new_dictionary(self, settings_dict): """ Writes a specified dictionary to the currently defined settings filename. :param settings_dict: The dictionary to be written to the currently defined settings file - :type settings_dict: (dict) + :type settings_dict: (dict) """ if self.full_filename is None: self.set_location() self.dict = settings_dict self.save() - def read(self): """ Reads settings file and returns the dictionary. :return: settings dictionary - :rtype: (dict) + :rtype: (dict) """ if self.full_filename is None: return {} @@ -18355,30 +18450,28 @@ class UserSettings: return self.dict - def exists(self, filename=None, path=None): """ Check if a particular settings file exists. Returns True if file exists :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str or None) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str or None) + :type filename: (str or None) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str or None) """ cfull_filename, cpath, cfilename = self._compute_filename(filename=filename, path=path) if os.path.exists(cfull_filename): return True return False - def delete_entry(self, key): """ Deletes an individual entry. If no filename has been specified up to this point, then a default filename will be used. After value has been deleted, the settings file is written to disk. - :param key: Setting to be deleted. Can be any valid dictionary key type (i.e. must be hashable) - :type key: (Any) + :param key: Setting to be deleted. Can be any valid dictionary key type (i.e. must be hashable) + :type key: (Any) """ if self.full_filename is None: self.set_location() @@ -18391,19 +18484,18 @@ class UserSettings: print('*** Warning - key ', key, ' not found in settings ***\n') print(_create_error_message()) - def set(self, key, value): """ Sets an individual setting to the specified value. If no filename has been specified up to this point, then a default filename will be used. After value has been modified, the settings file is written to disk. - :param key: Setting to be saved. Can be any valid dictionary key type - :type key: (Any) + :param key: Setting to be saved. Can be any valid dictionary key type + :type key: (Any) :param value: Value to save as the setting's value. Can be anything - :type value: (Any) - :return: value that key was set to - :rtype: (Any) + :type value: (Any) + :return: value that key was set to + :rtype: (Any) """ if self.full_filename is None: self.set_location() @@ -18419,12 +18511,12 @@ class UserSettings: the "default value" is returned. This default can be specified in this call, or previously defined by calling set_default. If nothing specified now or previously, then None is returned as default. - :param key: Key used to lookup the setting in the settings dictionary - :type key: (Any) + :param key: Key used to lookup the setting in the settings dictionary + :type key: (Any) :param default: Value to use should the key not be found in the dictionary - :type default: (Any) - :return: Value of specified settings - :rtype: (Any) + :type default: (Any) + :return: Value of specified settings + :rtype: (Any) """ if self.default_value is not None: default = self.default_value @@ -18441,7 +18533,6 @@ class UserSettings: # self.save() return value - def get_dict(self): """ Returns the current settings dictionary. If you've not setup the filename for the @@ -18450,7 +18541,7 @@ class UserSettings: Note that you can display the dictionary in text format by printing the object itself. :return: The current settings dictionary - :rtype: Dict + :rtype: Dict """ if self.full_filename is None: self.set_location() @@ -18458,7 +18549,6 @@ class UserSettings: self.save() return self.dict - def __setitem__(self, item, value): """ Enables setting a setting by using [ ] notation like a dictionary. @@ -18466,15 +18556,14 @@ class UserSettings: settings = sg.UserSettings() settings[item] = value - :param item: The key for the setting to change. Needs to be a hashable type. Basically anything but a list - :type item: Any + :param item: The key for the setting to change. Needs to be a hashable type. Basically anything but a list + :type item: Any :param value: The value to set the setting to - :type value: Any + :type value: Any """ self.set(item, value) - def __getitem__(self, item): """ Enables accessing a setting using [ ] notation like a dictionary. @@ -18482,26 +18571,23 @@ class UserSettings: value is None unless user sets by calling UserSettings.set_default_value(default_value) :param item: The key for the setting to change. Needs to be a hashable type. Basically anything but a list - :type item: Any - :return: The setting value - :rtype: Any + :type item: Any + :return: The setting value + :rtype: Any """ return self.get(item, self.default_value) - - def __delitem__(self, item): """ Delete an individual user setting. This is the same as calling delete_entry. The syntax for deleting the item using this manner is: del settings['entry'] :param item: The key for the setting to delete - :type item: Any + :type item: Any """ self.delete_entry(key=item) - # Create a singleton for the settings information so that the settings functions can be used if UserSettings._default_for_function_interface is None: UserSettings._default_for_function_interface = UserSettings() @@ -18520,11 +18606,11 @@ def user_settings_filename(filename=None, path=None): can be combined so that the filename contains both the path and filename. :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str) - :return: The full pathname of the settings file that has both the path and filename combined. - :rtype: (str) + :type filename: (str) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str) + :return: The full pathname of the settings file that has both the path and filename combined. + :rtype: (str) """ settings = UserSettings._default_for_function_interface return settings.get_filename(filename, path) @@ -18539,9 +18625,9 @@ def user_settings_delete_filename(filename=None, path=None): Also sets your current dictionary to a blank one. :param filename: The name of the file to use. Can be a full path and filename or just filename - :type filename: (str) - :param path: The folder that the settings file will be stored in. Do not include the filename. - :type path: (str) + :type filename: (str) + :param path: The folder that the settings file will be stored in. Do not include the filename. + :type path: (str) """ settings = UserSettings._default_for_function_interface settings.delete_file(filename, path) @@ -18553,10 +18639,10 @@ def user_settings_set_entry(key, value): then a default filename will be used. After value has been modified, the settings file is written to disk. - :param key: Setting to be saved. Can be any valid dictionary key type - :type key: (Any) + :param key: Setting to be saved. Can be any valid dictionary key type + :type key: (Any) :param value: Value to save as the setting's value. Can be anything - :type value: (Any) + :type value: (Any) """ settings = UserSettings._default_for_function_interface settings.set(key, value) @@ -18569,13 +18655,12 @@ def user_settings_delete_entry(key): After value has been deleted, the settings file is written to disk. :param key: Setting to be saved. Can be any valid dictionary key type (hashable) - :type key: (Any) + :type key: (Any) """ settings = UserSettings._default_for_function_interface settings.delete_entry(key) - def user_settings_get_entry(key, default=None): """ Returns the value of a specified setting. If the setting is not found in the settings dictionary, then @@ -18584,12 +18669,12 @@ def user_settings_get_entry(key, default=None): If no filename has been specified up to this point, then a default filename will be assigned and used. The settings are SAVED prior to returning. - :param key: Key used to lookup the setting in the settings dictionary - :type key: (Any) + :param key: Key used to lookup the setting in the settings dictionary + :type key: (Any) :param default: Value to use should the key not be found in the dictionary - :type default: (Any) - :return: Value of specified settings - :rtype: (Any) + :type default: (Any) + :return: Value of specified settings + :rtype: (Any) """ settings = UserSettings._default_for_function_interface return settings.get(key, default) @@ -18601,11 +18686,11 @@ def user_settings_save(filename=None, path=None): previously specitfied filename to create a new settings file. The settings dictionary is then saved to the newly defined file. :param filename: The fFilename to save to. Can specify a path or just the filename. If no filename specified, then the caller's filename will be used. - :type filename: (str) - :param path: The (optional) path to use to save the file. - :type path: (str) - :return: The full path and filename used to save the settings - :rtype: (str) + :type filename: (str) + :param path: The (optional) path to use to save the file. + :type path: (str) + :return: The full path and filename used to save the settings + :rtype: (str) """ settings = UserSettings._default_for_function_interface return settings.save(filename, path) @@ -18618,11 +18703,11 @@ def user_settings_load(filename=None, path=None): If no filename is specified, then the caller's filename will be used with the extension ".json" :param filename: Filename to load settings from (and save to in the future) - :type filename: (str) - :param path: Path to the file. Defaults to a specific folder depending on the operating system - :type path: (str) - :return: The settings dictionary (i.e. all settings) - :rtype: (dict) + :type filename: (str) + :param path: Path to the file. Defaults to a specific folder depending on the operating system + :type path: (str) + :return: The settings dictionary (i.e. all settings) + :rtype: (dict) """ settings = UserSettings._default_for_function_interface return settings.load(filename, path) @@ -18635,23 +18720,22 @@ def user_settings_file_exists(filename=None, path=None): will be used. :param filename: Filename to check - :type filename: (str) - :param path: Path to the file. Defaults to a specific folder depending on the operating system - :type path: (str) - :return: True if the file exists - :rtype: (bool) + :type filename: (str) + :param path: Path to the file. Defaults to a specific folder depending on the operating system + :type path: (str) + :return: True if the file exists + :rtype: (bool) """ settings = UserSettings._default_for_function_interface return settings.exists(filename=filename, path=path) - def user_settings_write_new_dictionary(settings_dict): """ Writes a specified dictionary to the currently defined settings filename. :param settings_dict: The dictionary to be written to the currently defined settings file - :type settings_dict: (dict) + :type settings_dict: (dict) """ settings = UserSettings._default_for_function_interface settings.write_new_dictionary(settings_dict) @@ -18662,7 +18746,7 @@ def user_settings_silent_on_error(silent_on_error=False): Used to control the display of error messages. By default, error messages are displayed to stdout. :param silent_on_error: If True then all error messages are silenced (not displayed on the console) - :type silent_on_error: (bool) + :type silent_on_error: (bool) """ settings = UserSettings._default_for_function_interface settings.silent_on_error = silent_on_error @@ -18674,13 +18758,12 @@ def user_settings(): settings, a default one will be used and then read. :return: The current settings dictionary - :rtype: (dict) + :rtype: (dict) """ settings = UserSettings._default_for_function_interface return settings.get_dict() - ''' '########:'##::::'##:'########::'######::'##::::'##:'########:'########: ##.....::. ##::'##:: ##.....::'##... ##: ##:::: ##:... ##..:: ##.....:: @@ -18706,7 +18789,6 @@ These are the functions used to implement the subprocess APIs (Exec APIs) of PyS ''' - def execute_command_subprocess(command, *args, wait=False, cwd=None, pipe_output=False): """ Runs the specified command as a subprocess. @@ -18714,31 +18796,31 @@ def execute_command_subprocess(command, *args, wait=False, cwd=None, pipe_output The function will immediately return without waiting for the process to complete running. You can use the returned Popen object to communicate with the subprocess and get the results. Returns a subprocess Popen object. - :param command: Filename to load settings from (and save to in the future) - :type command: (str) - :param *args: Variable number of arguments that are passed to the program being started as command line parms - :type *args: (Any) - :param wait: If True then wait for the subprocess to finish - :type wait: (bool) - :param cwd: Working directory to use when executing the subprocess - :type cwd: (str)) + :param command: Filename to load settings from (and save to in the future) + :type command: (str) + :param *args: Variable number of arguments that are passed to the program being started as command line parms + :type *args: (Any) + :param wait: If True then wait for the subprocess to finish + :type wait: (bool) + :param cwd: Working directory to use when executing the subprocess + :type cwd: (str)) :param pipe_output: If True then output from the subprocess will be piped. You MUST empty the pipe by calling execute_get_results or your subprocess will block until no longer full - :type pipe_output: (bool) - :return: Popen object - :rtype: (subprocess.Popen) + :type pipe_output: (bool) + :return: Popen object + :rtype: (subprocess.Popen) """ try: if args is not None: expanded_args = ' '.join(args) # print('executing subprocess command:',command, 'args:',expanded_args) if command[0] != '"' and ' ' in command: - command = '"'+command+'"' + command = '"' + command + '"' # print('calling popen with:', command +' '+ expanded_args) # sp = subprocess.Popen(command +' '+ expanded_args, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cwd) if pipe_output: - sp = subprocess.Popen(command +' '+ expanded_args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) + sp = subprocess.Popen(command + ' ' + expanded_args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) else: - sp = subprocess.Popen(command +' '+ expanded_args, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cwd) + sp = subprocess.Popen(command + ' ' + expanded_args, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, cwd=cwd) else: sp = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd) if wait: @@ -18761,20 +18843,20 @@ def execute_py_file(pyfile, parms=None, cwd=None, interpreter_command=None, wait 1. interpreter_command paramter 2. global setting "-python command-" 3. the interpreter running running PySimpleGUI - :param pyfile: the file to run - :type pyfile: (str) - :param parms: parameters to pass on the command line - :type parms: (str) - :param cwd: the working directory to use - :type cwd: (str) + :param pyfile: the file to run + :type pyfile: (str) + :param parms: parameters to pass on the command line + :type parms: (str) + :param cwd: the working directory to use + :type cwd: (str) :param interpreter_command: the command used to invoke the Python interpreter - :type interpreter_command: (str) - :param wait: the working directory to use - :type wait: (bool) - :param pipe_output: If True then output from the subprocess will be piped. You MUST empty the pipe by calling execute_get_results or your subprocess will block until no longer full - :type pipe_output: (bool) - :return: Popen object - :rtype: (subprocess.Popen) | None + :type interpreter_command: (str) + :param wait: the working directory to use + :type wait: (bool) + :param pipe_output: If True then output from the subprocess will be piped. You MUST empty the pipe by calling execute_get_results or your subprocess will block until no longer full + :type pipe_output: (bool) + :return: Popen object + :rtype: (subprocess.Popen) | None """ if cwd is None: # if the specific file is not found (not an absolute path) then assume it's relative to '.' @@ -18782,7 +18864,7 @@ def execute_py_file(pyfile, parms=None, cwd=None, interpreter_command=None, wait cwd = '.' if pyfile[0] != '"' and ' ' in pyfile: - pyfile = '"'+pyfile+'"' + pyfile = '"' + pyfile + '"' if interpreter_command is not None: python_program = interpreter_command else: @@ -18799,7 +18881,6 @@ def execute_py_file(pyfile, parms=None, cwd=None, interpreter_command=None, wait return sp - def execute_py_get_interpreter(): """ Returns the command that was specified in the global options that will be used to execute Python files @@ -18807,14 +18888,12 @@ def execute_py_get_interpreter(): :return: Full path to python interpreter or '' if nothing entered - :rtype: (str) + :rtype: (str) """ interpreter = pysimplegui_user_settings.get('-python command-', '') return interpreter - - def execute_editor(file_to_edit, line_number=None): """ Runs the editor that was configured in the global settings and opens the file to a specific line number. @@ -18824,11 +18903,11 @@ def execute_editor(file_to_edit, line_number=None): '-editor format string-' a string containing 3 "tokens" that describes the command that is executed :param file_to_edit: the full path to the file to edit - :type file_to_edit: (str) - :param line_number: optional line number to place the cursor - :type line_number: (int) - :return: Popen object - :rtype: (subprocess.Popen) | None + :type file_to_edit: (str) + :param line_number: optional line number to place the cursor + :type line_number: (int) + :return: Popen object + :rtype: (subprocess.Popen) | None """ if file_to_edit is not None and len(file_to_edit) != 0 and file_to_edit[0] not in ('\"', "\'") and ' ' in file_to_edit: file_to_edit = '"' + file_to_edit + '"' @@ -18840,9 +18919,9 @@ def execute_editor(file_to_edit, line_number=None): if not format_string or line_number is None: sp = execute_command_subprocess(editor_program, file_to_edit) else: - command = _create_full_editor_command(file_to_edit, line_number, format_string) - # print('final command line = ', command) - sp = execute_command_subprocess(editor_program, command) + command = _create_full_editor_command(file_to_edit, line_number, format_string) + # print('final command line = ', command) + sp = execute_command_subprocess(editor_program, command) else: print('No editor has been configured in the global settings') sp = None @@ -18854,11 +18933,11 @@ def execute_get_results(subprocess_id, timeout=None): Get the text results of a previously executed execute call Returns a tuple of the strings (stdout, stderr) :param subprocess_id: a Popen subprocess ID returned from a previous execute call - :type subprocess_id: (subprocess.Popen) - :param timeout: Time in fractions of a second to wait. Returns '','' if timeout. Default of None means wait forever - :type timeout: (None | float) - :returns: Tuple with 2 strings (stdout, stderr) - :rtype: (str, str) + :type subprocess_id: (subprocess.Popen) + :param timeout: Time in fractions of a second to wait. Returns '','' if timeout. Default of None means wait forever + :type timeout: (None | float) + :returns: Tuple with 2 strings (stdout, stderr) + :rtype: (str, str) """ out_decoded = err_decoded = None @@ -18875,15 +18954,14 @@ def execute_get_results(subprocess_id, timeout=None): return out_decoded, err_decoded - def execute_subprocess_still_running(subprocess_id): """ Returns True is the subprocess ID provided is for a process that is still running :param subprocess_id: ID previously returned from Exec API calls that indicate this value is returned - :type subprocess_id: (subprocess.Popen) - :return: True if the subproces is running - :rtype: bool + :type subprocess_id: (subprocess.Popen) + :return: True if the subproces is running + :rtype: bool """ if subprocess_id.poll() == 0: return False @@ -18897,9 +18975,9 @@ def execute_file_explorer(folder_to_open=''): The optional folder paramter specified which path should be opened. :param folder_to_open: The path to open in the explorer program - :type folder_to_open: str - :return: Popen object - :rtype: (subprocess.Popen) | None + :type folder_to_open: str + :return: Popen object + :rtype: (subprocess.Popen) | None """ explorer_program = pysimplegui_user_settings.get('-explorer program-', None) @@ -18917,9 +18995,9 @@ def execute_find_callers_filename(): Used internally with the debugger for example. :return: filename of the caller, asseumed to be the first non PySimpleGUI file - :rtype: str + :rtype: str """ - try: # lots can go wrong so wrapping the entire thing + try: # lots can go wrong so wrapping the entire thing trace_details = traceback.format_stack() file_info_pysimplegui, error_message = None, '' for line in reversed(trace_details): @@ -18932,19 +19010,18 @@ def execute_find_callers_filename(): error_parts = None if error_message != '': error_parts = error_message.split(', ') - if len(error_parts) < 4: - error_message = error_parts[0]+'\n'+error_parts[1]+ '\n' + ''.join(error_parts[2:]) + if len(error_parts) < 4: + error_message = error_parts[0] + '\n' + error_parts[1] + '\n' + ''.join(error_parts[2:]) if error_parts is None: print('*** Error popup attempted but unable to parse error details ***') print(trace_details) return '' - filename = error_parts[0][error_parts[0].index('File ')+5:] + filename = error_parts[0][error_parts[0].index('File ') + 5:] return filename except: return '' - def _create_full_editor_command(file_to_edit, line_number, edit_format_string): """ The global settings has a setting called - "-editor format string-" @@ -18952,9 +19029,9 @@ def _create_full_editor_command(file_to_edit, line_number, edit_format_string): :param file_to_edit: - :type file_to_edit: str + :type file_to_edit: str :param edit_format_string: - :type edit_format_string: str + :type edit_format_string: str :return: """ @@ -18970,15 +19047,16 @@ def _get_editor(): Get the path to the editor based on user settings or on PySimpleGUI's global settings :return: Path to the editor - :rtype: str + :rtype: str """ - try: # in case running with old version of PySimpleGUI that doesn't have a global PSG settings path + try: # in case running with old version of PySimpleGUI that doesn't have a global PSG settings path global_editor = pysimplegui_user_settings.get('-editor program-') except: global_editor = '' return user_settings_get_entry('-editor program-', global_editor) + ''' '########::'########:'########::'##::::'##::'######::::'######:::'########:'########:: ##.... ##: ##.....:: ##.... ##: ##:::: ##:'##... ##::'##... ##:: ##.....:: ##.... ##: @@ -18990,14 +19068,11 @@ def _get_editor(): ........:::........::........::::.......::::......:::::......::::........::..:::::..:: ''' - ##################################################################################################### # Debugger ##################################################################################################### - - red_x = b"R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw==" COLOR_SCHEME = 'dark grey 13' @@ -19084,11 +19159,12 @@ class _Debugger(): ] # Tab based layout - layout = [ [Text('Debugging: ' + self._find_users_code())], - [TabGroup([[Tab('Variables', col1), Tab('REPL & Watches', col2)]])]] + layout = [[Text('Debugging: ' + self._find_users_code())], + [TabGroup([[Tab('Variables', col1), Tab('REPL & Watches', col2)]])]] # ------------------------------- Create main window ------------------------------- - window = Window("PySimpleGUI Debugger", layout, icon=PSG_DEBUGGER_LOGO, margins=(0, 0), location=location, keep_on_top=True, right_click_menu=[[''], ['Exit',]]) + window = Window("PySimpleGUI Debugger", layout, icon=PSG_DEBUGGER_LOGO, margins=(0, 0), location=location, keep_on_top=True, + right_click_menu=[[''], ['Exit', ]]) Window._read_call_from_debugger = True window.finalize() @@ -19228,7 +19304,7 @@ class _Debugger(): return True # return indicating the window stayed open def _find_users_code(self): - try: # lots can go wrong so wrapping the entire thing + try: # lots can go wrong so wrapping the entire thing trace_details = traceback.format_stack() file_info_pysimplegui, error_message = None, '' for line in reversed(trace_details): @@ -19241,13 +19317,13 @@ class _Debugger(): error_parts = None if error_message != '': error_parts = error_message.split(', ') - if len(error_parts) < 4: - error_message = error_parts[0]+'\n'+error_parts[1]+ '\n' + ''.join(error_parts[2:]) + if len(error_parts) < 4: + error_message = error_parts[0] + '\n' + error_parts[1] + '\n' + ''.join(error_parts[2:]) if error_parts is None: print('*** Error popup attempted but unable to parse error details ***') print(trace_details) return '' - filename = error_parts[0][error_parts[0].index('File ')+5:] + filename = error_parts[0][error_parts[0].index('File ') + 5:] return filename except: return '' @@ -19304,12 +19380,12 @@ class _Debugger(): # # ## ##### # ## ##### # ###### #### # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # ##### # ##### #### # # # # # # # - # # ###### ##### # ###### # # # # # # # # # # # # - # # # # # # # # # # # # # # # # # # # # ## - # # # # # # # # ##### ###### ###### #### ## ## # # # + # # ###### ##### # ###### # # # # # # # # # # # # + # # # # # # # # # # # # # # # # # # # # ## + # # # # # # # # ##### ###### ###### #### ## ## # # # def _choose_auto_watches(self, my_locals): - old_theme = theme() + old_theme = theme() theme(COLOR_SCHEME) num_cols = 3 output_text = '' @@ -19350,7 +19426,7 @@ class _Debugger(): break elif event == 'Clear All': popup_quick_message('Cleared Auto Watches', auto_close=True, auto_close_duration=3, non_blocking=True, - text_color='red', font='ANY 18') + text_color='red', font='ANY 18') for key in sorted_dict: window.Element(key).Update(False) window.Element('_CUSTOM_WATCH_').Update('') @@ -19390,7 +19466,7 @@ class _Debugger(): """ if self.popout_window: # if floating window already exists, close it first self.popout_window.Close() - old_theme = theme() + old_theme = theme() theme(DEBUGGER_POPOUT_THEME) num_cols = 2 width_var = 15 @@ -19421,7 +19497,7 @@ class _Debugger(): col = 0 if col != 0: layout.append(line) - layout = [[T(SYMBOL_X, enable_events=True, key='-EXIT-', font='_ 7')],[Column(layout)]] + layout = [[T(SYMBOL_X, enable_events=True, key='-EXIT-', font='_ 7')], [Column(layout)]] self.popout_window = Window('Floating', layout, alpha_channel=0, no_titlebar=True, grab_anywhere=True, element_padding=(0, 0), margins=(0, 0), keep_on_top=True, @@ -19438,29 +19514,29 @@ class _Debugger(): theme(old_theme) return True -###### -# # ###### ###### ##### ###### #### # # -# # # # # # # # # # -###### ##### ##### # # ##### #### ###### -# # # # ##### # # # # -# # # # # # # # # # # -# # ###### # # # ###### #### # # + ###### + # # ###### ###### ##### ###### #### # # + # # # # # # # # # # + ###### ##### ##### # # ##### #### ###### + # # # # ##### # # # # + # # # # # # # # # # # + # # ###### # # # ###### #### # # -####### -# # #### ## ##### # # # #### -# # # # # # # # ## # # # -##### # # # # # # # # # # # -# # # # ###### # # # # # # ### -# # # # # # # # # ## # # -# ###### #### # # # # # # #### + ####### + # # #### ## ##### # # # #### + # # # # # # # # ## # # # + ##### # # # # # # # # # # # + # # # # ###### # # # # # # ### + # # # # # # # # # ## # # + # ###### #### # # # # # # #### -# # -# # # # # # ##### #### # # -# # # # ## # # # # # # # -# # # # # # # # # # # # # -# # # # # # # # # # # # ## # -# # # # # ## # # # # ## ## - ## ## # # # ##### #### # # + # # + # # # # # # ##### #### # # + # # # # ## # # # # # # # + # # # # # # # # # # # # # + # # # # # # # # # # # # ## # + # # # # # ## # # # # ## ## + ## ## # # # ##### #### # # def _refresh_floating_window(self): if not self.popout_window: @@ -19500,9 +19576,9 @@ def show_debugger_window(location=(None, None), *args): """ Shows the large main debugger window :param location: Locations (x,y) on the screen to place upper left corner of the window - :type location: (int, int) - :return: None - :rtype: None + :type location: (int, int) + :return: None + :rtype: None """ if _Debugger.debugger is None: _Debugger.debugger = _Debugger() @@ -19526,9 +19602,9 @@ def show_debugger_popout_window(location=(None, None), *args): Shows the smaller "popout" window. Default location is the upper right corner of your screen :param location: Locations (x,y) on the screen to place upper left corner of the window - :type location: (int, int) - :return: None - :rtype: None + :type location: (int, int) + :return: None + :rtype: None """ if _Debugger.debugger is None: _Debugger.debugger = _Debugger() @@ -19553,7 +19629,7 @@ def _refresh_debugger(): Refreshes the debugger windows. USERS should NOT be calling this function. Within PySimpleGUI it is called for the USER every time the Window.Read function is called. :return: return code False if user closed the main debugger window. - :rtype: (bool) + :rtype: (bool) """ if _Debugger.debugger is None: _Debugger.debugger = _Debugger() @@ -19586,12 +19662,17 @@ def get_versions(): The format is a newline between each value and descriptive text for each line :return: - :rtype: str + :rtype: str """ - versions = "Python version: {}.{}.{}\nPort: {}\ntkinter version: {}\nPySimpleGUI version: {}\nPySimpleGUI filename: {}".format(sys.version_info.major, sys.version_info.minor, sys.version_info.micro, port, tclversion_detailed, ver, __file__) + versions = "Python version: {}.{}.{}\nPort: {}\ntkinter version: {}\nPySimpleGUI version: {}\nPySimpleGUI filename: {}".format(sys.version_info.major, + sys.version_info.minor, + sys.version_info.micro, port, + tclversion_detailed, ver, + __file__) return versions -#==================================================# + +# ==================================================# # # MM""""""""`M oo oo # MM mmmmmmmM @@ -19611,7 +19692,7 @@ def get_versions(): # # When things look bleak, show your user an emoji # and a little hope -#==================================================# +# ==================================================# EMOJI_BASE64_FACEPALM = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6REQ2OTE2M0Q2RENEMTFFQkEwODdCNUZBQjI1NEUxQTAiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6REQ2OTE2M0U2RENEMTFFQkEwODdCNUZBQjI1NEUxQTAiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpERDY5MTYzQjZEQ0QxMUVCQTA4N0I1RkFCMjU0RTFBMCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpERDY5MTYzQzZEQ0QxMUVCQTA4N0I1RkFCMjU0RTFBMCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrG3klYAABf+SURBVHjaxFoJcFzVlT3//+6Wete+2NosybLlfcM2YHDYjFkcEnBqwIS1SELCFEySmUwlFJXKZJJUMksmM0NNJRkSYsAmYDZDjDE2YAwYGxvvtrxoX1pLq9Xqffv/z3n/tyx5QZITZqZdXS3//v+9e96999xz32sJn+MrX4J1toS/VWryn6ieV2J/+MoBLFlSBKvHDeiKeZOu851AbHgIBz4dwK4PkmhuA06dwXvBNJ5qz2BrGPBrn5NN0ucxiMxRiiXMnF6Q+0/6bfesLl37sGVFQz4WWX2oUwKokP28Kyru5DuXAFUgw/+rISDVh4GuZrSebMHePd3pgweixw82Y0cggZd8Kj5OANr/K0ABbpYVqxprrM+Gnlhf3Lj6TswSzkpzcH4X5udgIoS8xBGsSL6KZZntkPQAQVr4MD0r5wA2O2C1EkoY6cEuNB3qxju7gPc/wScnu/BsXwYvDurw6f/XABU+3WDDquXVePnvfljpLF31j/Cr9TitT4NPKscOxtqbg8BwSoSmeCKJpfperNM24Db9NdTovgutEYtjM/8e7AM+2g28tQPde47j+ZYYnhoCTlwKUOUvAVifg/mLyrH5hz/yehtueAT2jBOFNLoBp1E58O9o69uHDq0YA3KpabxkQbdcja3KrXhOuQ+H5flwSDFUSF2wSBnzHmF9xnw7nMCMOcCqlfAsbMQV7jTuS/pRG0+hhaE78L8KsECBt9GN1374PXna7FseonFzzNySmWfBZ+Aceh0rpV14xPo73KTsoFNS6NHKEJY8xvMxOHBEmofn5K9is3wbwnBjCnqQj+DoJJoZ6jKtrJgGXLcStqWzsSg3jnvj/ShJZXA0ISGsf94ARd7NtOLfHr0Ht15/7/XkjZsIjktu0ZHueApvPf8R/rABePUN4NB+FXXJdjzofQMPuTdinnwcIc2NLkyFmp2+XyrFdvkGPCPfg2NcKC+GUYUOUlLW9BGv8rOsygQ6qxbLMwO4K+RHJA7sT+ufYw7WWnDjHcuw5We/KJeVaT/gFRfBZRA79d/48eN78P4e2uLyQLKRMZNxKMkwKsuAqy4DbroKqJ7BsuCcj/Xa3diorkULpl0wxxJ9H+7XnsYd2ksoQ++FVpOXonT2C5uADS/j5YNBPBrQ0a3pf6EHGZr2ufn44+PfkcqKF91LYNM5Shrpzqfxk+/vxjt7ZNgaiKCyDlJhifGWvQy8qIJDR9LYsiODT/azZob7cLfnbXzL+wwWWI4hqHvosypGpWzM0yNNwRb5ZvxRvhNdUqURvqXoHzWEoWsjGS1cRhavQ2OwBbclQzgQ0NCh/7kABWvOsOLhdbfigdXr5gPuO7iajB3/M3jyp7vwxg7JAKfm010a81HXjOXWc+hJbyHkohJodhd6+nTs2p3Ctvd09DbHcaVyGN8uXI+1ji1w6HF0alMRkrzGnCHm7MfS5fi9/AA+kZYyUyP0dysN18zQJdApDIDLl6Cg8xTWMmSP0JOn9D8HYLEF+WTN9d99TMlzTX+QT5fTgg3Y8oft+O16/remBmpRBQt45twHDfWiG2yh292QCoqhFBQiptpw4mQab72Txt59QGHEhwfytuLhvA1oUFrg00rQzVyFkYIWnJRmYKO8zvCszoWbpreRquIGSFcBsGAOclpP4MvxIPbSky36pQC00nt1Fnx93RrcedXtjAv3FwnuJbTvfh0//mcg4S6CNrWenptAeAigNE+3sMC78yHRq3C60Tug4cOP6NWdOoY7orjJsQ/fLv49rrN9iISeS5/VEIfNGMLH8H1DvhUvyl9BQCrgN+3ITwfhLib51cN6eD9uGAjj9aiOwUkDdMpwLCnFbx77lqXYPfMbBPcptJ4N+Pm/Ak1dOZDrZtFDlpGKfhE6k0y+l6TzvEquzHVBys96NW3FkWNJvPlOBscOa5itN+PRohdxt/sVuPUI2rQqDGfDNyjlY6e0Es+y1HRJFajOdGKmt194zdXRhJl9KWycNMApMtasvQaPrFp3BUOQEwR+i+3bNDz3EnlmWj00V76ZdxetK7IRtnJ4kCmbpvcoyxSLCXYE6IhXPflmruY40NGRxo6dSez6mJfDftxfuB3fzN+AKgqDDq3CKC/iFWeg7pWW4Q/K/TiiNWJGYQ8cvu661g40KZP0HuZ68ItvfS2noXT6AhaulxALJvDzXxGnlgd9at044BRIiShsbUdhjwVgjRCkv8e4ZnjPmmt69vxcdbDMFJVC8uQhENQo2ZIGKcV9UdyRvwffKXoai5VDGNAKGb7TssRqxVFlHl7Lvx+xqhko3rO1eFIAvRLqr5mFn93zVUeOHG+nASFs3QZs3iZBmdZAlrRnvXAhODkRhq3lIFwsF7bZl8NSVgOH2wsrr8sDXcBQr7k4QnALz46MM/JJTyK/KBu+Cg4cTGDrOyq6WjO4xnkcj5Wsx42WnRhWXTgj1UOVyK+6jK6p81B2anfJpADWWHD33V/El+YvompOJZBOAr/6LzoynUdpUZ0tBxeGpcQib2sluLJKqLXzMTgcRiyVQirHBaWkErm8bmcxUwLdQF8HW0aL4blzFiv7t24V4VsApagYaXYgTU1JbN2RxvHjwMriNnyj/EXckt6CeNqCM6hHOicHjmjQqkwmPGfl4WdfvxfTCop4galz6CDVA3NPqpxmEMQF3pPMnLO1HYKLq68R3FAwaDIs780QZCIeRzzDv90FsLGQOey50NubRCYynwuyY2aJSZQd8awIXV5XVZ15WmqopbYzCWxnmamjhFta58OKrs1YMPAq89mOjkjxxGXCqqPquln4hzvXIte4mQCffwE40srcKa8eZcjzxKql8wScFnpx5mXwB0Owc0WLi4vh8XiQw7/FS81kGBDs7hMpSHnFcNM7avNRaAxVPUtalv42WLpPwTLkMwE686AFA9AiIcPblooqJINhnD6ewDVXUnOwLObF/FgV2Yzavp3C3PFfZRYsbmxAnpWOYkMAFlHSOIzkVzMUVpIGSRlTHmiEQmNyY0NQFqyEPxyD1+1CSUkJFMVcT7fbTYdoSCaTCIfDiEQiCA3RaG8ePLMWQj9xACmOKQ/2IFdNwDNvqbEQ4ZOHmO8OSFwgPZkgUD9UqwWWqhp0nDiEfQd0TK0h2Sjm5kFJui8r/MZ52WVcRYVg2k8cXUyXbrGYNEZnjl0g2bnqir8TuVUNCKoynLk5KCsrY0rKBqiRt3jl5uYawCsrK1FaWsrcTiDiKoWjog6WMyfgsFlQtPI25NY0IuoqZjtJ0kqa7GtGjURPRpi7Nn5nQSftUrXRoIplML4HmX9SRT6WVFZkezOO20oSjXKJZJH00RiBO88p5hIZSFHTyDCP8gvyMaOuDj6fj19JFxE1uvG20LiCggJ4vWyU6FFUzoCL190zF8Lq8sLX24sUK7cwNuOl8hkOjh0FUlb3audNEY1OAJDRV1BRgqqiQpEwJsD2TrGlwBAR+ZBOXVSaaexZcu123L72K4hHI+jq6jJAfLZ6M4EKLxcQZIZjSoUrYGGYDg8NITw4AHugB6lS1jsurJ7JnNs7sdGWVBUu17nj8tHxQ5TDlBXkodTpzQLkq68PRr3SKcvERDrzaGyMCuDCwEKPG5VVlXA4HBf13mcB1QRQ3i/AJhmy/gDFARs/nf9XPRSbYlHVMaJCIQTaYGdAucYQupixxwdVniD/iooKkGv4OWtjKAITnAhHvjV6CGrazAsxumKFTA8P9XQgGBw2WNNOb2rape3+iemCLC0pAlLoIZFnYmxjUUXZyC6aIDg9ETfAibeYRnwVT7BO96F7XIAVFhTm5ZkEQyY2vJhOZ7VlNud0assMQ0iwmnFdyC+2RGFfJzo7OpDHAQTISwVoRBDBCBiZXDfkVAxyPHRBWkhWAucik/Pg9ZhfiWwYGKAHB9A0LkDe68rNMWO1jaHZ25/FxhU0SkOWzUSYZgb6oJLqjRX2Um0EB9F0cL/Rt5WXlxvhd6kvV9YlGS6YqIuiJmosF2PVkixxXOraigpzazXboKC9jfaGsGNcgPwynGKKaRmxmnQ5yau6lpESGYYlGoDMFmesdtRCQWT6upFSJQa/graP30UbvVhXWzsuyVx0cQlMABQ5rDHn0sXVUOLDkCNDTA8zHSQSjqym6N0ESNZnTRG2UsJl+tLYNi7ArjQ6u3zEp5oPi9y+gt3S4oVkudaTsGWikNmdn217xNJxdDUSpt70Itp+Grvf3gIX40eomEwmc2l5yHGLiooM0lGpX/UcJ5R07CwfSLkU6FzUQi/lVpVpn/AiqwpOt+JTNrxHxgXIdDvd3IK2nj4zrkV8ky+w+AsyLHlku5Ym2OIBCmDWJpEL2Qw38sbqhEpSaN65BceOHsX0hoZLDlNxvyAor1fkMK0nnSta+mz+KxQC+tAgauvBOmoCFGt87CjFyDA2xPUJWJTRPtzUg9c+3G3uYAnDEwzZ/W0W5NTnoKqR131tsPJtoxFCvo3tAJLOIqQG/fjotedZWXJQWFh4yWQjQAppJxmdvxOyyBfWWclOb1LVWOjRRYtH+2qhEw4egH9AxQvZNBuHxWhnexJPvrkNQVE0hUbuG5bQ2ieh2Kvha/eBfRRXD376+hhytAT7NrYcYheNykKVbUjbPQgc2YMDH+1EaVn5pR+eCBLLNsIay5NQLbwC2emEPtCLGur96fUmu4vwPH5MbKHgBX8GvkntqtFhQ2mmlDWDGxfMJ5v2y9h3xoLlDSrmVmgonwrMmSuITIXvRICdehwWSjQI5hP5KFmgsLmN9nXBXlHLVVZoTGrSxV/cFwqFEGN7JWdYE4fI1gVlsAj10tuJNWtIfNVmeKYI8tVXENvTg4eYf/5JARTBxpv3av2oY/czz1Mi4WCbgqtnZVDs0Y1BuZiYT/BTCXawJ4Fgq5+hwVaHNVC3u4xclAZ6KDhisBZPpXPVS2LTARY1VYh4xqAlOgjdUwidQmJmbQq33mIKbJFCBz4F/vQu1rek8btL2hdNUyqGVWyJdGIWGbUxalMwp1IzAIrBs32sAXDhQrPgBjqjiHT5qULYUuXTIIcLmY7TsDjcsLG8TAakkGtDQosysQz5xtprCVNUDA8hR43irruAwiJzbjoYmzYhvK8X99IhgUve2Y4zpYYzeFX2oyhHx2XlFRLqp+oYy/wiTATb1jMnFhCox6Uj5Isi2tlPI8iunC3V24acIoaY03NRoS6JTSqxl8PeMcJuZcDvNzeuRO3j4MpQLwVFGKtuBJYv43gpkxve3wns2I1ftmbwwp+9dS9A9qfxJ4R1X7JXv8LhhGMKeUP0sSO2itUUoMWk07NAS1lFksE4woE0uwuVzNoH55QKyMZmlWiYFVMZie2MaBjxwUEMd3ag71QT1IAfemiYmjdqrKDw3qz6JNioGFtBYkF7eoBXNqH5WBgPMtLif9HhS4oABjLY3xfEaz0nMJUytJG12KhDgjfOAZotvDXsshctAlgKSfkM394kQ7gfrgqqEwrzJEEMnTqJwSP7EWs5Ale4CWXWLjSWBzF7Shg1ecMotgzBOtyHIX/KUC2LF5kRI+bZ9CKwtxlf60zjU/1Sjs/s5gJMZ3D0c/0CF9uQmqJgbV0BHr9iKRYsvxzUnSZI4cWxdV2AF6st3v3UtM8+A3QMMxctubBGetBQreKyxcb5gjGGIGLxewVk957EdkkgBOx6H/g1n33sr82F27YNePkV/H5vDA/G1Es4AGWGTLmhUtl49+rynzZ6w+uUCObaVAwndLSnR8kHAQ3HySe/bm5GW/NR1DGCSp3UyKILsVjGbFxjFLj4jsSKg3tiWH1FCPeu03HNtcCsWTSaYW0fAZYePc42FtxpnD1g+7vZUwK+ntuIYwdCuCt0XmiOC5D2Tb9lRuHmH/3HQyu+fH+DbdXV1vyrZvcscir6AxjGapeGxVNtmF9uRSM/K5MaPGEd21sj+E+q+K6Wo7i5rR2y2JTMFyXRMQpwRHEIL7Z3AA8+QEe5zT4zShMLHeYx3UWPOFTTq3Q43v4AaDmF4OFe3EHN3PxZjrJcBFzjFxuU137yL0um11RupTQ4CYmabzqL+f0ki0VLsfy5jZblEdciyk+KYBb2qmgI6SF/iy8Q2cTED8TcU5S90TIcerUbVW4/Fs6hKJgHlJWN6vJqiuM0PdN0khPOZh3jdSVlHDQYv7IQu9N9UinzogAhxlOSyBLI4VcaUksDGHxlv34yrT/anMK+8dLsHIBcyBlrGrD5p0+gvrqIwd2vmz4WHTSFaR5DRGwNqDYP3DMWwGa3nY2/TCxS6+1t+1645SQisTBs1I3qlDqcydSi+cMOvPded6JxJnLnURBUM3dKS8262XIGWEKArZZinHHOwQbLUpxSlqJVrkGvVIYh5BOz/Rzl4ZgxhOtrZ+HEod4T6gT63TIm56puqsPLP3mc4OrV0R8mjaGjgPjdy1tALG8JiuxWaKK7Hol1ti6u2jlwVs9EYqAbYbZTke4TSDD+rLY0fAH8zeEPsGfHXnyzYQqun96AWiun2d8/FR9V/xL7pKXw2apH5dNn0R+fUd0eRNxTpBpbb2NfchIe9ErwfGEqXvjR32NWTUM2TKRzO98kE37nh8DR3jqULK8nuPQY7DrbmIzRGassyLllVbCXVSM/FEC04wzCXWeg2bCaJfDo6SS+0dQMZ3k7VhTJuMc533X3zpzbkREqYJKNRpKFP+IoAZv56gnVEIkib0k+Nn7/MSybMS8L7rxCIurNcYbSlncdcM1czjzSswylMydU/pPRjjy08m1ELKlSy6RhceUhb+4yTLn2DrgXrfzStNqqD5YVWHZU5WLamTTeOpbE487+9qi3t+mSK7JUWiZMK5roPsvMHPzgvq/g5mVXGb/OuQCcMJiSEq++zl7LswwlhflGaApwQxBHy/k4QyIYhNN44AtowWy9H9E0+zcqfhtri8J6kV9VC5/oyIsqr61vP/q+pX/43u4M3lD9iS59cGCGccSnjlH4Y3KrFH0o132Yim7M0Y/iMvUgDqbfw2bAOSHAO1ZLN9y+Rjf6ootJACoW7GDdOexrQMmyRnomxbjWDW/tQYUBUjeS1dz6PqIXY6bix/Rqs8k/fVo4VDMOXzwOB4JC3jRcll9pOfRS3sDAIykVfVf2bJoRopSzJqJwZoKoye1HQ24PqrU2A5z4nUyZ3st5M2d3w3xpozxOuNFjefAmpc/uyoyu3lhwbHI/PQy89WEh8hdeKU4CDI+KnOsgLdWSxP1woI0eHJl5MO1E3dUufHddyOjC334beP55c7dbbCHGKftFi6XXL7K5bMd+E+3oGr712JNYU/WksVsgupOKYjJ26Wcf9xt5qBlmJifMQXuOFDsnuWVzkh6GJckAmzbbYZl+HXJcdopb7WwENTAoT6OQUW3lCoeMkB1ZnW1dRWeL+g03sCGeI1S/eQaRz8pvLJRYjpp5klRQkid261JUNlGxYcv5Q5PYuoma6RSeECDnksZ6boh6r72PodVGGfS8gljZtfCUlzA0M2cZU88+IsovA4tBxKb27DAyTvbmIhYZHXbFCjOXRfPqZHdsp7QRi2XIOGceIhHzzPTsVslErSK/D0cM0dA/YYiO9ZyfIdnOR9il4M2tMuJTr0FRbS20VPJs5IqfWr2PSpxC8RhQQjfKhmWVziCeuL4bbu9oMRNbemIPVxxjiNZqdHdNN5pY0dNl0uf96GKczdpkxASoyMyUSQHkQ4NBsaFkqvWtu4pRMH85iiqrzoIzy4JmsOUJgsMIsbCRtdC7KysDuHPRINYsi6C0TD9HJYwYLfZX0qyfqVRqtMWIh5BRskcCk9mm4b1BRlmQtvam0TkxQNoxzEjuJcDDJJR3PnRhysqbkeNxn6NUsidxfEAzal/KqCESKSaNp+46hb+6OgIpR8oCk852+N3dwObN5pZCDr9PJNK8rhoduiSOAGLDyNjNeyX54ifi5wP0s3EbHMIg1WP3hADDbIF9dMSRo8AG5pxn8UrYPK4LwJmhL8HLvCtk5vmEuKNR00riuPNqrlCO5ZxzOQGopYV937NmaNps2b3WkbMF8SuMSIAAI+1qAaqN7Q5lEgBhHsIyaDrZdUwIUG7JFDkOHZHwzHr2nhVz4a2aBn2MDLvQ5RrmklaMX/sprIeDdnbTjrOcHiO7DQ+bn6IhHekgRnbIEmMPT4IDakzVnybJxMXlkfvSmXF+8sZpjh7noxnsC2Uw4VnA/wgwAK0YlGkaGdQ3AAAAAElFTkSuQmCC' @@ -19631,17 +19712,14 @@ EMOJI_BASE64_HAPPY_IDEA = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRF EMOJI_BASE64_HAPPY_JOY = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NjUxQTFBQzI3NkRGMTFFQkI5NDZCQjFDNkFDNjQ2OTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NjUxQTFBQzM3NkRGMTFFQkI5NDZCQjFDNkFDNjQ2OTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2NTFBMUFDMDc2REYxMUVCQjk0NkJCMUM2QUM2NDY5NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2NTFBMUFDMTc2REYxMUVCQjk0NkJCMUM2QUM2NDY5NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoEmG4sAABmjSURBVHjaxFoJeBxn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' - EMOJI_BASE64_HAPPY_LAUGH = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QkFBNDU4OUE3NkRFMTFFQkJCQzhBRTkwQjJGMzAyNUMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QkFBNDU4OUI3NkRFMTFFQkJCQzhBRTkwQjJGMzAyNUMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCQUE0NTg5ODc2REUxMUVCQkJDOEFFOTBCMkYzMDI1QyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCQUE0NTg5OTc2REUxMUVCQkJDOEFFOTBCMkYzMDI1QyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Po9obewAABRZSURBVHjaxFoJkBTXef66557Znb1vFhCwIMAcMgsCSSAOybKELazE2JKrXJGqrNjypdixZaccl8uJo7KrfCaKHVUqtiVRliInciRkGUfGQoeRACEECBYtsCwse18zO/dMH/n+1zO7C7uY4VBloGu7Z/q9/r/3X9//v9Zs28bkz65du7BhwwZc7qechwE0ctZaudSAMM99cz3wlLrhlXtOpJCKAyZPkzxivGdEB/o5bih5mc9dv349XnrppSnfu3GFnyBQU+fCYr+GFeUleP+1jWguKUGV24PykpAeqqqygwG/7fHySV7Cs4g2mwVyOdjxBDJDI0ilM4jxOjI4iqFjPegwctjbm8UB3naUgJP2Fch3WQCDGrz1Oj7QWIpPrGjBjUuWYOby6+pQ2dCIuuaZCJaXAtoYRXsXSJ0AbHO6aag4+NVhowJZzByLAn0D2Dg4hE/teQtoP462Ayfw4kgW23pN7EtY7zHAEO2oXsPHF1Thq+vXYMUdW2Zh8eoVQOVSwEOLzESAyAFg9HUg3UV1ZYufXGy5gkcNMJ/nN9JLsnEs3LMXC1/4X3xu70E8353Ew8epXct+DwBW6GhcHsSPb1uPrffctxQzV20k4kWUgtLE3iaop4D4MYLKD9AvcalFaDN/5D9eD7CWj1l7E1w7X8KWp5/BbWXH8YOOHP5xyEDmqgB0Uf4FHiydV4GnP/35GQs++MmPQQ+3wsh5MDByBvGhP8JMnJDAAkNfBsPlpYwuXrupFGep5do6D7GL3+qwJgliqO/caqRz7rFz8KUy8LmyWL4uC39D2j/79+lvvPYHe+neBD4xZCJ+xQDrgWuaZlY9E3r43+Yat67Gs7lqJDMGfj0I7IvEEbc/CcMThKF5FBA5cEVBYQKoBzmG3aw6fHoG7gVpeBel4Vr20odbf/K1p/aPWX8xaCB72QBDGjzXVrr/3fzmY3NbP7gZvQxpJpXyaD9wKCJqKHFCxVX8GHkdUm/TSyuGsGUFVsQimxc98k/ffNXAN63LAeih4C1u3Dt495c2bbxjM6pSnFuzsWcsja5IDM1cUTEhWWW12pqsuPyVa8eRNN7vVsbrrINoQkxVANjK7TR1Lhd2HlzOdmbM2Q5QeYLoMKP5kLZ8yPDIJb3Y/9Hv4Ma3Xv1Kw0uvPN1t4/AlAwxoCM6rxZfuvWMA12m/h9ekadhJrBt6BN9wn0XIJQCzCphuGdAMApGDKtaIz+Ky2haUwQqXME2co22X7lxbPHSeazxsV97pmURtF5dJcyuwWYJLmj6M5Xw41udDJBtALhTGwKph//N78OXuBO6zLxVglY6Nq1qxcPNCycpdjgTxP6EiuxtHGDSffQMYHGZm4M/ZHLERQM5w/pp5gKblaKYAUJsGoJ4HKNcuAvS4qHU3F46BRaKon5Y6cwZwyzrg2vl0Gz6Drg9vmuI0MVfOxJ2H2tDE1NFdFEA7v9BVHmzdcHOAWf19lJZP1m2Ykd149FHg6e0E5Q5A8/gmll8k5LlWuBY0BUSF88nLLM5coImiasu5ti0zf543Aa6UvTuJXz2XxZc+CyxdxhRLgBJZfAwBixaisq4Nt3LEL4sCaDn+EF7YhBtbFjGGarV54U7huf88gW3PMPLMngV3dZMyo6v9kSWxMmnY5HMaVap5PLRaG/EzJ/HDRwbxdw8BZVWON8j6tFCrARfuYMyYFuC06Zj8qWXWTMwum0HbsLxKM6muvdj+Av2tuhpW/WzYoimutp5N8Uir86tyUGtK8SMDsHpOw+jvgZni/LPnI2YFsONFx2iUEfD2Gq7/vBosL9VQWjRA6m3xgrmMD4EZzi16FO3730LnWVqizGg75qTRfKLXLEeqphmuTBJ6LnvFGtSzzHcEmm1ZjtjC1URhwBwdhpllfqyqQXs7SdOo468CMBxmyVKJZsPCrKIA5hnTkjmzJa7X8Q6aYbodb+4ZREb3wQ6UOr4hg40MIi2teOsrj+H41q8j0TAPLtGocelAZYyMlTmOf/QhHPzWrxFdso7fpR3XiZO8l1VgOKLhbLcDUI0jgoZ6+Bt9mFmUD0r+C7uo9VrRXImCbA3uw+EjUkaUwpbAYjl5zvT4MXPnL2H6Qjh7+yfQt+YjqNv7WzS9/CRKeo+r3239zzMbjXO5cmnEG1rQffM96F+1GVbIgxk7nkLzH35BD/Erx7Tpl1ZpCZ/vR8fJFJYumZijmj6ZjmFuUQDDxNUcRn2wVCYOceZBDJ1qw9k+4hV7OEc6TUWluf/zA4RPHcTJu/4Wvbd+BIPLN6Fp11OYsesJaiZ3wWCk0fws5rwzmx5A9/q7YdSUwtc1gLmP/QA1h8lxfX7kEnm6KffyWa5ACGdOp1SQKXxKKZZF7lFsFPUFAigJhnwOwEwb+rrHMEy712tCOJ8WSbAxfUHUHnwRpV1tOHHXlzH8/vU4veV+xGa9D/Of/DY8qbEpmhTN5YJlaL/nWxhZvkZVIVW7d2Heb36IwMhZGMwBtk4UMs500NgZFhDBEkQiQ4iKxebXOxhUplpbnA/aCPq8CPgkw2qMoGP70d3DJE5WoczTnp4zGDRTX7Qfi3/xNVQeekP1LUZa12Bk8VoGn6mVjXwnv8k9cq+MkbEyh8yliJykCdfEwtgMYlogiFiMFdqY438iDuUVUlBeLECP2w2Ph7aOHBl16l30DiBPnzw4N1tP/Vg0K8MfUrkm0HkG5SfepBl6p97H7+Q3uUfulTEydooLTAbIsCnmnmINGo/n0zPF8bjVESg2TbiFDYJ1HZLHCTKK0QgcPxJzuYAGJdqJyR2593sYYwQoYTxf/POH4B/untYH5Tv5Te6Re2WMjJU5CpFTYSwkPcUALHViE3Q8fu468NCKBWipQ3HPQ0phiSQc+nWBiOhKJxBvnI+DX3gUo8tXo+HFZ7Hk0S8g2HcSlsd3YW3zN7lH7pUxMlbmkLlkzvE8UEDI9GQLGsqRTk9Lgi4OkONzpImGmaZdpk+oYU4lMH0PQmOU7F/5IRz4m1/y4ToW/etX0fL0d+BORp0Qf5GP3CP3yhgZK3PIXDKnzH2+/yiBKKRlTWhPCD4TfabYaiKTyyGdS47ALy7nyXPmaUxTkvNoyyp0r7sH1zz/z6jf8xzcZMKmN3Bu6XCxdgx92yahqDn0R1S070Xf9XeqOT2JCMJ7f3du5Lbtc2SRx1BeMP7EigLIoiDBaJwQEyjNx6VAwGH8EsWUsStTJQGgYMH+U1j6swegm7nxVCDAxccUX71oye9QPs0sFMY2Gl9/BvV7t8Mka7ImW46az1a+6J9k+SIrS7XhogByMezRBMaSqQkDriBQTXqbwvJFiFBJvq7S4I2PKkDRa5ah48MPou7ADpR2HoYvMkANjDqCX0ibUh5xIXKhCmTKaxGbvQT9130Qc7b/BGUkDkIScgVbFK0RrKYWxEBoErVOOO3wvqIAjhHH2Ti6FIHIA2ysl0SX4+QWmT25JnNRQWjRkmhOzCnR2ILjC5dAixnwj/bCQ/De2LD6TZHxPEeVFCHkIBcqR7a0CrmSCqQrGmCXMnhH0+p+AW6J1UyiLBq/0xgQfG4bpaV5zBRjbEyJ2lUUQM0Joyf6GGMW5b9rZuXstmh28kCW6UJ8dRLfgqdbEvIJKNjXgVhoEWwm0lR9M1J6c3FOaOX7ocQic8hcMoctqim0AvIJz04nFThhjfJ4SZODQ9RiEJ1Fl0ucrq2za7zNhcYG1l3EY6eS0JiMzShXOJXIV/NOz0EIc9XR15wZnQ6SU3YXcxj5MRxb1fYnuFilyKaQlRg7V1gfg0E8hqpKlkhlDkCJoIMDiPVk0FM0QBrziY5OumNe0GpWTbOoDDNKf3MiDozhIdZpI1zRtAo+puZC3b7n4R0ZvbwdD2EjQyOoee2/YNANDEqtuGdBe9SoijHJGK6Zoy7VtdA2muhZt46zRQNkUDrV3Yeu+LBqQUNjqri+FYoAugS1UCounxWLUpA+GAP9yA0Pw922D82/ethppV1K/zd/f/OTD8PT9iZyYzFVHo0HJymuWUXo9GOfncH8+Q5mMU/WwugYxLGYhVRRAKXLxf/Rti68I4Wl0gZN4YZVJMRBgwFkhP5XOVEea3mGwSBkkJDX/uExND/xPSkXnL0j7SINGHWPrcbU7XwCpvDY8SaVkxLE91ysieyhfjQ1ciGandwnt3TRlZImXs5dqJCe7plimfE0dhw47KzsGK2uln64ilrMdnXDw4Dj4hdasDTf0JygFZbbhxn//X0s+O59KDnylvME/wUO/ib3LPjuvWrMOCkvJHMSfC1cDndNA9xjQ7BGRrCi1cnLhVbk8XYYdKlXLrnx229i5543kfj4xxCSPmRnP3DzRqC9I4PTxw7BxzLaKq+BGayAaWuqCyZ0Qhi/xbRRycq+/NDLiM27DvH5rUiRXxqhMuehiSgCPe0k2W+i9MQB6GQ/VqDEAcSxmtfrdNNoOq4sA9vpo/T/KFYS3KpVjvbEBwcHGSzO4DBt8x39UgEyQB8/fByvHTuK22bRqXsZisuY8D/7WS7XaxZe/tMgsqcGma98jKzMi8y8mj8IO+BTLXlbq6CV2qjsbkPFmcMY788XzESSNp3IlkkrKuCSbpocWUZQugGScebOhNqnKqsGNm8Bli93AotETtktPvoOTXQYvxZ+omuXCpBudTqGnzz9G9z2919jXPE5K1dCF1m9VsOBGJ+QsvC+igz6uzMYZMk/Ri0nM5pTN7odfmmrotWjIoJWIAfiV6zohUxLZa/YDs91K4dSrlUZFd1APwtUAfv6vWiaRc2tzKrOuZil1H/DXIM9b1CJJh6/7N2lPhs7dr2BJ9+/A/dI4d0z4Pi8cD/DlvSh4UO3Ok1tYRO0ItaONkZHsuqQ7xIJp70vfSpp5QtEoaxuHn76YSjkWEYl82xFpXMuOS5M9+4e1XB4h1PepDOO9gr09ne/Bd4+i38gwO7LBphgAX04iS/+9DG03G+j9doljqBSZQhdEnoq/Fs6+9IXEYbRPA15MYyJ/YrCvoTUwK5pUonldOvViwpm1tneD3htePNbZ/Lbc88Cb+zDLzpz+KlpX+EG6IiJob0j2GL+HNtu2YgNN28A6ittzKi2yed0xNIaqkpsqcfGAUxTYzobLJMaAmZ+k+aC23eUbCShKZNf0GSpyHmaqfwFau7A2/jZO2k8SDeyiuAPF/+Mmug5EMPm6O/w9aNH8YWb16FiSaOJd/tceKfbhVuXGOp9gwsBHN9jKeLlAdWG0Z1ttf2dLrWY9X4L27cDr7+OjrZ+fPu0gcfj5lV+CWHYQIpAv3W6HY+3ncb98xqsu0oqs/P3HyBF82qY1WCDQRRu/WJtqT+f92UrTvz27eM6uk/SNBM5+z/22W91DuGJQQvbBlj3vSdvWRR2ngZMnBxK4evtp/BwU4+1MqBbG/qPYHVtBZoZMOrLyxGWKOgPOHt7Xl9eK+eFcQlSqsTMOEcy6ew5RMcwzAzRe2rYOpnLWq8wQL8SNXEgacPE5VHcS/8I0KiNsWgKO3m5M8RM6xpA2BRr0lDd4EO5JS/3MEhSuS3hoP9Bo6LOowYKWqYFT6SvJ5Ixf5SzEWUOi5JujfbleM78zcXoGbORuZI3nK7aq1wq2jq+J7XNWMJGu+RLaodGC38ZWX51hfagVVHlqCzfRPEmeuJDCTwfk2YRswC/7k1O3gG6Sp+rAlBYRLkbgXoXVpS5cVdl2LfJHSqbrbndinFSs55Aov/cQdUN85eW5Q5almlzfFrPZTsj0fjOSA6/6TWwP0Kft+z/B4CVLtQ2abiTHKqZZCWgttmpreqge1mooWFxsGkOvNWNcJeEmdDdU0PppHCZTqe9QyyzMum0TzeNZeWp6LLykb4vzxjoPTKUMg7aOnqlnmAeTTEhdHWbeI5pa+A9AyjEY9Ms9/Of/vzKlY3V/XClT+FMv40Ii85XdtMvm25CqLYGlrxKSF5pqT4OFGk2nXbROfP5mOwaeH8kEmFwGUM2XEuiHsTCqt7F99+AxWUkDjPrnO38Htbrjz6Ov95+ChtIpBLvCcAGHVvv+/xfrtx0N0NjL02O0a+lhafkhUeO2Rgm/ZDltvP7h4VXuQYQQli92mMga+rjbRbZDvP5SBSqqkjb/Bgejah+ZXW9iTXX83mkblq+PbhwpUofK/f/GFs7jOn3468IIJ/jvn5B+QM3reVZ++NOH0VaMi6nYdQ3EoCrOTix+5sH9ypmog11/BfHRusEmsJZbPmojtpaefkW2L1bGI5FThpkSvGjK5lG1wDLJSvjNNPTE72hm9cCK57BA90d2JYBjKLiQ7EAG124cdMNemuptt3pgE0aKZszacMPN5OfNIsKmnsFs3AEDYpP9VKHL2RbsPZ2D264wcK8ecCnPgVs3VqgbUzqNNkSMu5ExqPmPO8dL5RxUW69Ca0iS9EBsNiWSWMYf7X++hEd6dGJNkS+xzhIE03bpXD7POPBRMAdRSMm3q9kovOU4qEX5+HdTs/43LffDqxb55BrWRxfwI94LqjmhHVey4PXG9ZCF1lcVxMgK7/aNYtwx5z5Tut7MrfKmY47pvVqxSHdlGIAJRhCEDegQyU1f2GQy0Rbbzl+9EL1JODABz7gVCPKJ1k2JMywmjN33utf0mKcQ58XWbyYfkf3sgDWubBx7RrU6b6pSThBFtPTy0WQt3OcfTcaYxoB2lQHyUwDfc+LgqSaSvYLqlNTSqRCJnFJYRwqV3MmUlNfAREZRBaR6aoAFFOYU4W7WpcDU9ggHzjKFHGWVbe3tFxV6gIwSI3diDMKZAoeUpz8NhoF/szKTnzuzsj4o4V/btvmFNHydqLOrC85tJNVivSCprAayiCyUKaPuK4GQC7Y7NYF2FQ/Y6p5ZnKO9kaSlfCGy5xWRP41SQEao+4i+Z1lNwvGL67uxL98ph9ev/NY2aVta2ME7psofl2yoRMOoy8aQk+f84xzzJTXIgtlukVku5j8/yfAAAtVKpmsTyiDAAAAAElFTkSuQmCC' EMOJI_BASE64_HAPPY_STARE = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDgzMzhCODM3NkRGMTFFQjkwODBENDUzNzk4QzVBOEMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDgzMzhCODQ3NkRGMTFFQjkwODBENDUzNzk4QzVBOEMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEODMzOEI4MTc2REYxMUVCOTA4MEQ0NTM3OThDNUE4QyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEODMzOEI4Mjc2REYxMUVCOTA4MEQ0NTM3OThDNUE4QyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrgNzd4AABMDSURBVHjaxFp5kBz1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' - ICON_BUY_ME_A_COFFEE = b'iVBORw0KGgoAAAANSUhEUgAAAIIAAAAeCAIAAABvxVGSAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAACxMAAAsTAQCanBgAAAGVaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pg0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPg0KICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPg0KICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnRpZmY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvIj4NCiAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+DQogICAgPC9yZGY6RGVzY3JpcHRpb24+DQogIDwvcmRmOlJERj4NCjwveDp4bXBtZXRhPg0KPD94cGFja2V0IGVuZD0iciI/PkPeCmYAAAvnSURBVGhD7ZkLVFVVGsf/9325XN7vhzwEARVQFLTEBE1QySeplZNl2gyKzlJrmlottXRmZTPN1HIm1/SY8jFlZWVODpVZ0zg5PjIyBJQURRHkqYD3ci/3Pd93OOBF4BKOrZgWv3UW7rPP3vvs8733VeLYmIFBfmyk4r+D/KgMqmFAMKiGAUHfucHhwJbC+npLDwpTOGzLk31CtErxfpCbpW81FDW0bZPdvnx5nnjfgcPhOH2qtPSVdevTg8WuQW4WV0FJb7ZV6swvHrs8ceKEa93Q6XQhoWFH9O5nmky1eos4Z5CbwpU37C6pf98aFxweYTKbxa5uyOVypUxy/tBHe+cMEbt6RK6E1QyHHbBDIhc7fwJIpbDTR3UgkXAQ7z+uvMFkcxjMNp3eZjbLhUvW9eJOgwGtRrvF4rSV7ngHYdUuTLgb03+JeU9jdDbv/ieApzfy30D4cBI/BWmkzsGSP3Oz/7jyhjarfWXBmafyFJrUKtIxmTL9Jd2TyiVSSIW/kjI88aL0ifGpMT5u4rTuRIzEkq2wtOFqNaQy+A3Bsd048JKw+/9fJIhNw72bsXM1KkvZy3PXI2QEtt4NqMQh3xtXVqmWS73VCrtO7e+NAB8E+iHIHyGBCA5AkB8CfEH9PqQYqyrMw+WL3X1Yh9vy8fJSvPQgTn2GkVOhEEITqVSEGv3VSvsUFyuQj9rgsIp3N8BGdMN4Z+iRTbicaDfA9hdR28OLDVNfx65APV5BaNPD7jTFQW2nt9OthLbUQ9TqIziMCNCUV4jtHnDA1AKrVamQu1zH3R8mA67W8F5p3yY9jM2w2aHxwugsURZRiYgfxw3/IRg6hhudkAM5Q24Ynw6FCtFJmLkWyZm8DzctpjyIaXm8ZuewzKVYsQPTVgkf3xUPH6TnIi0HGk8o1WKnM8mTkfc65q3nldtRa5B2F6Yswsw1CI3mHg8/2KwwGblNYVbjg2u1kHZEBe9ALHoWedsQncwfTtNz1yFvO0bP6K4JV+IjiYV5qYsr7MZWidHkdJk7Gq2SS3WSAI3WbneZl7Q+vFe1AuHxmLEaKXNx8gBoythZyFrNgqBdzPgV0h+C4xpy1iJ7FRxtwkwHC3HJixQ7hVsBnyAs2IgZ+Vj0PIalY/Y6pM7C/I0Yfy9Gz8bcx8XBY2dj4mKyEYxbCP9wYWYHJKBlr2BSHqauwdo9WPy84DdOULif9ST0DUjKxqgc7vELY4FOXY30h7lnwWZIbfAMh8UIk1C/SK3QeENXJYqUFE9bCo5n3UxZAZsBOY8gbiJkCkxd0d0LXRUtjUbL7wt1wbHDz/0pDtKeBG2HRYezloZPyptmxfmKnd0hC/X0Q/47bMLs0YBvGGRyhI3EtQb2DHdv7vn6PWhDEZKAb/eyTZEVKFUYNQ1VJdxun0iQxbUZMWo2qk/hzUcx+3FMXcmr7V7PSWhsLtRuMLWx0Z0/igN/wfKd4kQRB6Y8DJU7dq6C1h8LfoumGrZOZ8mMyYH+Kv71GobeDn0jf+eMNRyOCp5FzmPY9xvMfgr+kdB6w2yEuRlSDRRa9iqDXlwhZBiC47BnI8LiEJkKD28Mm4DDb/Cyd+YLL+siT1dq8FLJQ6Jjtr+7l6pSsasnNmzYGNuyX7zpEXcvNFfjyNuov8ACihyOrDWoLkJwLCpPwGbDkCSOPJfLWBkqN9ScE+WenAWVFpfPcJukwPUuhWszrCZyMRx8FWYLLp/E8Mk4fxzlx9jbGAp3HvCLxDfv8wotDWiuvz6dIkncHThRgKoyJGezYVZ8zU8pV1EcM9EByIqIMbh4HFfrUPQPXPwWPiGIGoP9f+T90z5bm3k/Gj+oPdDaJMrQ3Y+X0tMjgfAkWMyoOY3MZfjuIEIToXRD+VeYkodLJymdQqJwdkFXQUkhk3gbG/V6vaR3aFjj5QvBHrRoL9AY2iJ9auFHXFHUncPXBbhSheHZcPNA7Vk+Rgy7jWXUWAXPMP7CJkp65EMapC/mRvNF/puSDb9QbhAkNaMOFSfYpig6k85KPoNDAr9wWC0wG6D1Y8/LyMf4+/DFy9yZ9XN4+fHcoBg22/Ij3I4dzxmVvIpeOm4+steKSZWm66/AqMeHL0DXhKAofsWFEjRWQncF0x7lj1Jp4BnI3iwVfsvx9OJd6Sj/EXYORwollv4VMiWO7uHSlqbc9xxC4tjJtL7Ifpg9uANXaiAZe6Otrk4QSi9YrVbdxbMeSmeXvgEbf5WhRTBwgbAEtnoSDQVKijBuGsRlsE+01iM6hQfQplQKzHqMv5MgQY+ZiemPimqgWXRVHoddeCnJlAZQ4LLpEBAPQxMccjZG2n75Uex6BMX/ROQoJE2HVcilJD7aiKER/mEcKEj9JDuZg9NAJbmFIBpzG0ctxgGVEukPsBBJahYLxyXfcMhkmL8J3iE8VyFF8p2Yu4kHt7bAy5fzH3khOc2xXdi+EoZmRKTy6fXEXmzPR10FxtzF/kE+0YErNRBpgarCwm/Em5640tAQbGuUCW7RMxIzF6y+UQgdhogRmLyYjeJaPY6+yYpx92U/JbeguDdpGUcJ6py7DiveRGw6vnyNxZSRhxlrUfwpzhbygm6BbGi151k0NNhrCNp0aKlnKZA90unEIwCTHuKnVBlXFMMviPMHhZdWIXBfqeY1c57A/Vt4PF3eobhjCRRuOPWlELLVqCpCfCbiU7heenALByLKAVR3hURjaBqkchx9G++u4/IvYQpvdfaTrDlS/MwnkbcDidns5TYLx2H60rRZ3EN89T4aKhE7Dun34+hb/KoOZE9PjhKbPUGR8ojRKyNzsqPTlrtSWlraeGhP+hDPXvVARpQ2n212/AIkzYBPOIr24cPfcVxKykLyNATF4vOtbBAxt+PwLpwsgE8EGs7j4xcwJAWhCWz7X72NT18Sg7tvAFJzceLvqBeClaUVdWWoLoNMw48SMvhpSx2XxQmZnHWyVuLqZex7VgzFrVfZlsNHoroUH2zi6mXCz3gP721AU60wAqivQMIkjJ6D8EQU78eHf0DDOYydwx8SEI0jb+CLbayDtFz+kYaM7NAOVBRyiKPPpN1uW45LpUidh4gUjJ2H0Tm824AYxNyGEZMxcRGKCjhSOdHHL6wtZts9nxvvzL3HYrGYzRaTyWQ0mpRKhVqtor8KpbKspOQ+aVH2UB9xQo9oPdgx1e5cXBvb+MTQjm8QYsaj/gwunuZHKhWMBtaHrY2Vd9fjHIuIj5/jdMIxUkCuQHQiKsvEgl3sF6zEzZ1F03aNC2LyiQn3cmK8UIiiTziZX8cOuUrI81J4+iIyibVICdkZuQwaFQwmLnn5FQ6oldAGceSkT6CJFJqWv479WxA1GkHxOPkRJjyAHcvwwMs4sguH3sKo6YifCGMLij/GhVLEjEXKLH7pd/9G2X+cXYHoQw3kA9/U6DcdrHzq13ZZUDPJSiolx5CQJO312PeuxM0atSI1WKvsesL6X5EgYTzmP4PCDzBmDvZuQCllVOeNC3LpGerv9MzOMZ09PeJitd4JjMYvXsU76/iUvnAzqyFmArbew+cYUuHudRQHhGXp6oz8N9xep4/cQAE2JUTrqZQk+itHJdiS4mwjY+2Jw2yj4m0pITa1zDZ1qNet1gFhRWYeas+guIBFpOuoAq/jQmrOEqd2++UaF6v1DtUFdjsnACpM6Q10dOCUK+MDHbmaKFh+IDTaueH2On2ogSBNaJQyQ2O3E38rSmqkw3x7/0XvpvENgX8EB9CosWgzcFy+OUn9oBgbWAEBURgxCWYTqo/DzRP+ARiaipZaofDtB99DDUCkl/pCZVebcsCug9SuVlO5dstRebDyfUKRupCPUQZKGAMP2tXFQv5lgiqCU5/jLBW7EizdwdV5yQHhdNYP+qiU2rl0zVR8udXhq79Ui0s1wlWNim9x+DvPhYlBXfVzKzA2c4lCZ2M6bXzwTEcqHmhIcL4QEhvXSAd3wqDDpRNcyx3+G8qFwro/9P1/0USt3rz3dKPkhhRgR4K/JiPKW7y9tUgl/AOc/mrXCmcA0m6E7TGz0yD7HUK/lxoG+aH5ASL7IP1nUA0DgkE1DACA/wLdLG/w2vOeEgAAAABJRU5ErkJggg==' EMOJI_BASE64_HAPPY_RELIEF = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDBFNzI5NUU3NkRGMTFFQkI0RUZFM0E0MERFOUExQUEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDBFNzI5NUY3NkRGMTFFQkI0RUZFM0E0MERFOUExQUEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MEU3Mjk1Qzc2REYxMUVCQjRFRkUzQTQwREU5QTFBQSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MEU3Mjk1RDc2REYxMUVCQjRFRkUzQTQwREU5QTFBQSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsnMYvAAABTwSURBVHjatFoJdFzV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' - EMOJI_BASE64_HAPPY_BIG_SMILE = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NEMyMDNFQTY3OTk2MTFFQjg3NzRCNjNENENFODAxNDYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NEMyMDNFQTc3OTk2MTFFQjg3NzRCNjNENENFODAxNDYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0QzIwM0VBNDc5OTYxMUVCODc3NEI2M0Q0Q0U4MDE0NiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0QzIwM0VBNTc5OTYxMUVCODc3NEI2M0Q0Q0U4MDE0NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrjncAkAABMkSURBVHja3FppcFzV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' EMOJI_BASE64_HAPPY_CONTENT = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QjA0RDRDODM3OTk2MTFFQjk3QzQ5NjQxMjRDQTk0MEMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjA0RDRDODQ3OTk2MTFFQjk3QzQ5NjQxMjRDQTk0MEMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCMDRENEM4MTc5OTYxMUVCOTdDNDk2NDEyNENBOTQwQyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCMDRENEM4Mjc5OTYxMUVCOTdDNDk2NDEyNENBOTQwQyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrB9/b8AABLJSURBVHja3Fp5dB3V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' @@ -19651,26 +19729,27 @@ EMOJI_BASE64_HAPPY_THUMBS_UP = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAA EMOJI_BASE64_HAPPY_WINK = b'iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OTFDMjA3MTk3OTk2MTFFQjg3QzdFQTc4QzI5RjM3OTMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OTFDMjA3MUE3OTk2MTFFQjg3QzdFQTc4QzI5RjM3OTMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5MUMyMDcxNzc5OTYxMUVCODdDN0VBNzhDMjlGMzc5MyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5MUMyMDcxODc5OTYxMUVCODdDN0VBNzhDMjlGMzc5MyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PhbG1A0AABOISURBVHja3FoJcFz1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' -EMOJI_BASE64_HAPPY_LIST= [EMOJI_BASE64_HAPPY_STARE, EMOJI_BASE64_HAPPY_LAUGH, EMOJI_BASE64_HAPPY_JOY, EMOJI_BASE64_HAPPY_IDEA, EMOJI_BASE64_HAPPY_GASP, EMOJI_BASE64_HAPPY_RELIEF, EMOJI_BASE64_HAPPY_WINK, EMOJI_BASE64_HAPPY_THUMBS_UP, EMOJI_BASE64_HAPPY_HEARTS, EMOJI_BASE64_HAPPY_CONTENT, EMOJI_BASE64_HAPPY_BIG_SMILE] +EMOJI_BASE64_HAPPY_LIST = [EMOJI_BASE64_HAPPY_STARE, EMOJI_BASE64_HAPPY_LAUGH, EMOJI_BASE64_HAPPY_JOY, EMOJI_BASE64_HAPPY_IDEA, EMOJI_BASE64_HAPPY_GASP, + EMOJI_BASE64_HAPPY_RELIEF, EMOJI_BASE64_HAPPY_WINK, EMOJI_BASE64_HAPPY_THUMBS_UP, EMOJI_BASE64_HAPPY_HEARTS, + EMOJI_BASE64_HAPPY_CONTENT, EMOJI_BASE64_HAPPY_BIG_SMILE] -EMOJI_BASE64_SAD_LIST = [EMOJI_BASE64_YIKES, EMOJI_BASE64_WEARY, EMOJI_BASE64_DREAMING, EMOJI_BASE64_THINK, EMOJI_BASE64_SKEPTICAL, EMOJI_BASE64_FACEPALM, EMOJI_BASE64_FRUSTRATED, EMOJI_BASE64_PONDER, EMOJI_BASE64_NOTUNDERSTANDING] +EMOJI_BASE64_SAD_LIST = [EMOJI_BASE64_YIKES, EMOJI_BASE64_WEARY, EMOJI_BASE64_DREAMING, EMOJI_BASE64_THINK, EMOJI_BASE64_SKEPTICAL, EMOJI_BASE64_FACEPALM, + EMOJI_BASE64_FRUSTRATED, EMOJI_BASE64_PONDER, EMOJI_BASE64_NOTUNDERSTANDING] EMOJI_BASE64_LIST = EMOJI_BASE64_HAPPY_LIST + EMOJI_BASE64_SAD_LIST - def _random_error_emoji(): - c = random.choice(EMOJI_BASE64_SAD_LIST) + c = random.choice(EMOJI_BASE64_SAD_LIST) return c def _random_happy_emoji(): - c = random.choice(EMOJI_BASE64_HAPPY_LIST) + c = random.choice(EMOJI_BASE64_HAPPY_LIST) return c - -#==========================================================================# +# ==========================================================================# # MP""""""`MM dP dP .8888b # M mmmmm..M 88 88 88 " @@ -19704,9 +19783,7 @@ def _random_happy_emoji(): # MM MMMMMMMM `88888P' dP dP dP dP `88888P' # MMMMMMMMMMMM -#==========================================================================# - - +# ==========================================================================# # M"""""`'"""`YM oo @@ -19824,9 +19901,6 @@ These items may solve your problem. Please check those you've done by changing - return body + body2 - - - def _github_issue_post_make_github_link(title, body): pysimplegui_url = "https://github.com/PySimpleGUI/PySimpleGUI" pysimplegui_issues = "{}/issues/new?".format(pysimplegui_url) @@ -19867,7 +19941,7 @@ def _github_issue_post_validate(values, checklist, issue_types): popup_error('Must fill in an OS Version') return False - checkboxes = any([ values[('-CB-', i)] for i in range(len(checklist))]) + checkboxes = any([values[('-CB-', i)] for i in range(len(checklist))]) if not checkboxes: popup_error('None of the checkboxes were checked.... you need to have tried something...anything...') return False @@ -19876,7 +19950,7 @@ def _github_issue_post_validate(values, checklist, issue_types): if len(title) == 0: popup_error("Title can't be blank") return False - elif title[1:len(title)-1] == issue_type: + elif title[1:len(title) - 1] == issue_type: popup_error("Title can't be blank (only the type of issue isn't enough)") return False @@ -19887,8 +19961,6 @@ def _github_issue_post_validate(values, checklist, issue_types): return True - - def _github_issue_help(): heading_font = '_ 12 bold underline' text_font = '_ 10' @@ -19956,7 +20028,6 @@ If you've been programming for a month, the person answering your question can a # [HelpText(help_steps)], # [B('Close')]] - t_goals = Tab('Goals', [[HelpText(help_goals)]]) t_why = Tab('Why', [[HelpText(help_why)]]) t_faq = Tab('FAQ', [[HelpText(help_explain)]]) @@ -19964,69 +20035,72 @@ If you've been programming for a month, the person answering your question can a t_steps = Tab('Steps', [[HelpText(help_steps)]]) layout = [[TabGroup([[t_goals, t_why, t_faq, t_exp, t_steps]])], - [B('Close')]] + [B('Close')]] Window('GitHub Issue GUI Help', layout, keep_on_top=True).read(close=True) return + def main_open_github_issue(): font_frame = '_ 14' issue_types = ('Question', 'Bug', 'Enhancement', 'Error Message') - frame_type = [[Radio(t, 1, size=(10,1), enable_events=True, k=t)] for t in issue_types] + frame_type = [[Radio(t, 1, size=(10, 1), enable_events=True, k=t)] for t in issue_types] - v_size = (15,1) - frame_versions = [[T('Python', size=v_size), In(sys.version, size=(20,1), k='-VER PYTHON-')], - [T('PySimpleGUI', size=v_size), In(ver, size=(20,1), k='-VER PSG-')], - [T('tkinter', size=v_size), In(tclversion_detailed, size=(20,1), k='-VER TK-')]] - - frame_platforms = [ [T('OS '), T('Details')], - [Radio('Windows', 2, running_windows(), size=(8,1), k='-OS WIN-'), In(size=(8,1),k='-OS WIN VER-')], - [Radio('Linux', 2,running_linux(), size=(8,1), k='-OS LINUX-'), In(size=(8,1),k='-OS LINUX VER-')], - [Radio('Mac', 2, running_mac(), size=(8,1), k='-OS MAC-'), In(size=(8,1),k='-OS MAC VER-')], - [Radio('Other', 2, size=(8,1), k='-OS OTHER-'), In(size=(8,1),k='-OS OTHER VER-')]] + v_size = (15, 1) + frame_versions = [[T('Python', size=v_size), In(sys.version, size=(20, 1), k='-VER PYTHON-')], + [T('PySimpleGUI', size=v_size), In(ver, size=(20, 1), k='-VER PSG-')], + [T('tkinter', size=v_size), In(tclversion_detailed, size=(20, 1), k='-VER TK-')]] + frame_platforms = [[T('OS '), T('Details')], + [Radio('Windows', 2, running_windows(), size=(8, 1), k='-OS WIN-'), In(size=(8, 1), k='-OS WIN VER-')], + [Radio('Linux', 2, running_linux(), size=(8, 1), k='-OS LINUX-'), In(size=(8, 1), k='-OS LINUX VER-')], + [Radio('Mac', 2, running_mac(), size=(8, 1), k='-OS MAC-'), In(size=(8, 1), k='-OS MAC VER-')], + [Radio('Other', 2, size=(8, 1), k='-OS OTHER-'), In(size=(8, 1), k='-OS OTHER VER-')]] col_experience = [[T('Optional Experience Info')], - [In(size=(4,1), k='-EXP PROG-'), T('Years Programming')], - [In(size=(4,1), k='-EXP PYTHON-'), T('Years Writing Python')], - [CB('Previously programmed a GUI', k='-CB PRIOR GUI-')], - [T('Share more if you want....')], - [In(size=(25,1), k='-EXP NOTES-')]] + [In(size=(4, 1), k='-EXP PROG-'), T('Years Programming')], + [In(size=(4, 1), k='-EXP PYTHON-'), T('Years Writing Python')], + [CB('Previously programmed a GUI', k='-CB PRIOR GUI-')], + [T('Share more if you want....')], + [In(size=(25, 1), k='-EXP NOTES-')]] - checklist = ( ('Searched main docs for your problem', 'www.PySimpleGUI.org'), - ('Looked for Demo Programs that are similar to your goal ', 'http://Demos.PySimpleGUI.org'), - ('If not tkinter - looked for Demo Programs for specific port', ''), - ('For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)', ''), - ('Run your program outside of your debugger (from a command line)', ''), - ('Searched through Issues (open and closed) to see if already reported', 'http://Issues.PySimpleGUI.org'), - ('Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed vut not released.', '')) + checklist = (('Searched main docs for your problem', 'www.PySimpleGUI.org'), + ('Looked for Demo Programs that are similar to your goal ', 'http://Demos.PySimpleGUI.org'), + ('If not tkinter - looked for Demo Programs for specific port', ''), + ('For non tkinter - Looked at readme for your specific port if not PySimpleGUI (Qt, WX, Remi)', ''), + ('Run your program outside of your debugger (from a command line)', ''), + ('Searched through Issues (open and closed) to see if already reported', 'http://Issues.PySimpleGUI.org'), + ('Tried using the PySimpleGUI.py file on GitHub. Your problem may have already been fixed vut not released.', '')) - checklist_col1 = Col([[CB(c, k=('-CB-', i)), T(t, k='-T{}-'.format(i), enable_events=True)] for i, (c, t) in enumerate(checklist[:4])],k='-C FRAME CBs1-') - checklist_col2 = Col([[CB(c, k=('-CB-', i+4)), T(t, k='-T{}-'.format(i+4), enable_events=True)] for i, (c, t) in enumerate(checklist[4:])], pad=(0,0),k='-C FRAME CBs2-') - checklist_tabgropup = TabGroup([[Tab('Checklist 1 *', [[checklist_col1]]), Tab('Checklist 2 *', [[checklist_col2]]),Tab('Experience', col_experience,k='-Tab Exp-', pad=(0,0))]]) + checklist_col1 = Col([[CB(c, k=('-CB-', i)), T(t, k='-T{}-'.format(i), enable_events=True)] for i, (c, t) in enumerate(checklist[:4])], k='-C FRAME CBs1-') + checklist_col2 = Col([[CB(c, k=('-CB-', i + 4)), T(t, k='-T{}-'.format(i + 4), enable_events=True)] for i, (c, t) in enumerate(checklist[4:])], pad=(0, 0), + k='-C FRAME CBs2-') + checklist_tabgropup = TabGroup( + [[Tab('Checklist 1 *', [[checklist_col1]]), Tab('Checklist 2 *', [[checklist_col2]]), Tab('Experience', col_experience, k='-Tab Exp-', pad=(0, 0))]]) - frame_details = [[Multiline(size=(65,10), font='Courier 10', k='-ML DETAILS-')]] - frame_code = [[Multiline(size=(80,10), font='Courier 8', k='-ML CODE-')]] - frame_markdown = [[Multiline(size=(80,10), font='Courier 8', k='-ML MARKDOWN-')]] + frame_details = [[Multiline(size=(65, 10), font='Courier 10', k='-ML DETAILS-')]] + frame_code = [[Multiline(size=(80, 10), font='Courier 8', k='-ML CODE-')]] + frame_markdown = [[Multiline(size=(80, 10), font='Courier 8', k='-ML MARKDOWN-')]] - top_layout = [ [Col([[Text('Open A GitHub Issue (* = Required Info)', font='_ 15')]], expand_x=True), - Col([[B('Help')]]) - ], - [Frame('Title *', [[Input(k='-TITLE-', size=(50,1), font='_ 14', focus=True)]], font=font_frame)], - # Image(data=EMOJI_BASE64_WEARY)], - vtop([ - Frame('Platform *',frame_platforms, font=font_frame), - Frame('Type of Issue *',frame_type, font=font_frame), - Frame('Versions *',frame_versions, font=font_frame), - ])] + top_layout = [[Col([[Text('Open A GitHub Issue (* = Required Info)', font='_ 15')]], expand_x=True), + Col([[B('Help')]]) + ], + [Frame('Title *', [[Input(k='-TITLE-', size=(50, 1), font='_ 14', focus=True)]], font=font_frame)], + # Image(data=EMOJI_BASE64_WEARY)], + vtop([ + Frame('Platform *', frame_platforms, font=font_frame), + Frame('Type of Issue *', frame_type, font=font_frame), + Frame('Versions *', frame_versions, font=font_frame), + ])] middle_layout = [ - [Frame('Checklist * (note that you can click the links)',[[checklist_tabgropup]], font=font_frame, k='-CLIST FRAME-')], - [HorizontalSeparator()], - [T(SYMBOL_DOWN + ' If you need more room for details grab the dot and drag to expand', background_color='red', text_color='white')]] + [Frame('Checklist * (note that you can click the links)', [[checklist_tabgropup]], font=font_frame, k='-CLIST FRAME-')], + [HorizontalSeparator()], + [T(SYMBOL_DOWN + ' If you need more room for details grab the dot and drag to expand', background_color='red', text_color='white')]] - bottom_layout = [[TabGroup([[Tab('Details *', frame_details, pad=(0,0)), Tab('SHORT Code to duplicate Program *', frame_code, pad=(0,0)), Tab('Markdown Output', frame_markdown, pad=(0,0))]], k='-TABGROUP-'), + bottom_layout = [[TabGroup([[Tab('Details *', frame_details, pad=(0, 0)), Tab('SHORT Code to duplicate Program *', frame_code, pad=(0, 0)), + Tab('Markdown Output', frame_markdown, pad=(0, 0))]], k='-TABGROUP-'), ]] layout_pane = Pane([Col(middle_layout), Col(bottom_layout)], key='-PANE-') @@ -20034,9 +20108,9 @@ def main_open_github_issue(): layout = [ [pin(B(SYMBOL_DOWN, pad=(0, 0), k='-HIDE CLIST-', tooltip='Hide/show upper sections of window')), pin(Col(top_layout, k='-TOP COL-'))], [layout_pane], - [Col([[B('Post Issue'), B('Create Markdown Only'), B('Quit')]], expand_x=False, expand_y=False)]] + [Col([[B('Post Issue'), B('Create Markdown Only'), B('Quit')]], expand_x=False, expand_y=False)]] - window = Window('Open A GitHub Issue', layout, finalize=True, resizable=True, enable_close_attempted_event=True, margins=(0,0)) + window = Window('Open A GitHub Issue', layout, finalize=True, resizable=True, enable_close_attempted_event=True, margins=(0, 0)) for i in range(len(checklist)): window['-T{}-'.format(i)].set_cursor('hand1') @@ -20046,19 +20120,19 @@ def main_open_github_issue(): window['-ML MARKDOWN-'].expand(True, True, True) window['-PANE-'].expand(True, True, True) window.bring_to_front() - while True: # Event Loop + while True: # Event Loop event, values = window.read() # print(event, values) if event in (WINDOW_CLOSE_ATTEMPTED_EVENT, 'Quit'): - if popup_yes_no( 'Do you really want to exit?', - 'If you have not clicked Post Issue button and then clicked "Submit New Issue" button ' - 'then your issue will not have been submitted to GitHub.\n' - 'If you are having trouble with PySimpleGUI opening your browser, consider generating ' - 'the markdown, copying it to a text file, and then using it later to manually paste into a new issue ' - '\n' - 'Are you sure you want to quit?', - image=EMOJI_BASE64_PONDER, - ) == 'Yes': + if popup_yes_no('Do you really want to exit?', + 'If you have not clicked Post Issue button and then clicked "Submit New Issue" button ' + 'then your issue will not have been submitted to GitHub.\n' + 'If you are having trouble with PySimpleGUI opening your browser, consider generating ' + 'the markdown, copying it to a text file, and then using it later to manually paste into a new issue ' + '\n' + 'Are you sure you want to quit?', + image=EMOJI_BASE64_PONDER, + ) == 'Yes': break if event == WIN_CLOSED: break @@ -20068,7 +20142,7 @@ def main_open_github_issue(): title = str(values['-TITLE-']) if len(title) != 0: if title[0] == '[' and title.find(']'): - title = title[title.find(']')+1:] + title = title[title.find(']') + 1:] title = title.strip() window['-TITLE-'].update('[{}] {}'.format(event, title)) if event == '-HIDE CLIST-': @@ -20105,10 +20179,14 @@ def main_open_github_issue(): if not _github_issue_post_validate(values, checklist, issue_types): continue - cb_dict = {'cb_docs':checkboxes[0], 'cb_demos':checkboxes[1], 'cb_demo_port':checkboxes[2], 'cb_readme_other':checkboxes[3], 'cb_command_line':checkboxes[4], 'cb_issues':checkboxes[5], 'cb_github':checkboxes[6], 'detailed_desc':values['-ML DETAILS-'], 'code': values['-ML CODE-']} + cb_dict = {'cb_docs': checkboxes[0], 'cb_demos': checkboxes[1], 'cb_demo_port': checkboxes[2], 'cb_readme_other': checkboxes[3], + 'cb_command_line': checkboxes[4], 'cb_issues': checkboxes[5], 'cb_github': checkboxes[6], 'detailed_desc': values['-ML DETAILS-'], + 'code': values['-ML CODE-']} - markdown = _github_issue_post_make_markdown(issue_type, operating_system, os_ver, 'tkinter', values['-VER PSG-'], values['-VER TK-'], values['-VER PYTHON-'], - values['-EXP PROG-'], values['-EXP PYTHON-'], 'Yes' if values['-CB PRIOR GUI-'] else 'No', values['-EXP NOTES-'], + markdown = _github_issue_post_make_markdown(issue_type, operating_system, os_ver, 'tkinter', values['-VER PSG-'], values['-VER TK-'], + values['-VER PYTHON-'], + values['-EXP PROG-'], values['-EXP PYTHON-'], 'Yes' if values['-CB PRIOR GUI-'] else 'No', + values['-EXP NOTES-'], **cb_dict) window['-ML MARKDOWN-'].update(markdown) link = _github_issue_post_make_github_link(values['-TITLE-'], window['-ML MARKDOWN-'].get()) @@ -20120,8 +20198,6 @@ def main_open_github_issue(): window.close() - - def _copy_files_from_github(files, github_url=None): """ install one file package from GitHub or current directory @@ -20171,7 +20247,6 @@ def _copy_files_from_github(files, github_url=None): retval = tail or os.path.basename(head) return os.path.splitext(retval)[0] - info = _ReturnInfo() info.src = files[0] info.package = path_stem(files[0]) @@ -20289,6 +20364,7 @@ def _copy_files_from_github(files, github_url=None): return info + def _upgrade_from_github(): info = _copy_files_from_github( files="PySimpleGUI.py !init.py".split(), github_url="https://raw.githubusercontent.com/PySimpleGUI/PySimpleGUI/master/" @@ -20296,8 +20372,8 @@ def _upgrade_from_github(): # print(info.package + " " + info.version + " successfully installed in " + info.path) # print("files copied: ", ", ".join(info.files_copied)) - - popup("*** SUCCESS ***", info.package, info.version, "successfully installed in ", info.path, "files copied: ", info.files_copied, keep_on_top=True, background_color='red', text_color='white') + popup("*** SUCCESS ***", info.package, info.version, "successfully installed in ", info.path, "files copied: ", info.files_copied, keep_on_top=True, + background_color='red', text_color='white') def _upgrade_gui(): @@ -20351,16 +20427,15 @@ def _upgrade_gui(): # MMMMMMMMMMM - def main_get_debug_data(suppress_popup=False): """ Collect up and display the data needed to file GitHub issues. This function will place the information on the clipboard. You MUST paste the information from the clipboard prior to existing your application (except on Windows). :param suppress_popup: If True no popup window will be shown. The string will be only returned, not displayed - :type suppress_popup: (bool) - :returns: String containing the information to place into the GitHub Issue - :rtype: (str) + :type suppress_popup: (bool) + :returns: String containing the information to place into the GitHub Issue + :rtype: (str) """ message = \ """Python version: {} @@ -20380,10 +20455,11 @@ def main_get_debug_data(suppress_popup=False): if not suppress_popup: popup_scrolled('*** Version information copied to your clipboard. Paste into your GitHub Issue. ***\n', - message, title='Select and copy this info to your GitHub Issue', keep_on_top=True, size=(100,10)) + message, title='Select and copy this info to your GitHub Issue', keep_on_top=True, size=(100, 10)) return message + # ..######...##........#######..########.....###....##......... # .##....##..##.......##.....##.##.....##...##.##...##......... # .##........##.......##.....##.##.....##..##...##..##......... @@ -20411,69 +20487,68 @@ def main_global_pysimplegui_settings_erase(): print('The file being deleted is:', pysimplegui_user_settings.full_filename) - def main_global_pysimplegui_settings(): """ Window to set settings that will be used across all PySimpleGUI programs that choose to use them. Use set_options to set the path to the folder for all PySimpleGUI settings. :return: True if settings were changed - :rtype: (bool) + :rtype: (bool) """ settings = pysimplegui_user_settings.read() editor_format_dict = { - 'pycharm':' --line ', - 'notepad++':' -n ', - 'sublime':' :', - 'vim':' + ', - 'wing':' :', - 'visual studio':' /command "edit.goto "', - 'atom':' :', - 'spyder':' ', - 'thonny':' ', - 'pydev':' :', - 'idle':' '} + 'pycharm': ' --line ', + 'notepad++': ' -n ', + 'sublime': ' :', + 'vim': ' + ', + 'wing': ' :', + 'visual studio': ' /command "edit.goto "', + 'atom': ' :', + 'spyder': ' ', + 'thonny': ' ', + 'pydev': ' :', + 'idle': ' '} tooltip = 'Format strings for some popular editors/IDEs:\n' + \ 'PyCharm - --line \n' + \ 'Notepad++ - -n \n' + \ 'Sublime - :\n' + \ 'vim - + \n' + \ - 'wing - :\n' +\ + 'wing - :\n' + \ 'Visual Studio - /command "edit.goto "\n' + \ - 'Atom - :\n' +\ - 'Spyder - \n' +\ - 'Thonny - \n' +\ - 'PyDev - :\n' +\ + 'Atom - :\n' + \ + 'Spyder - \n' + \ + 'Thonny - \n' + \ + 'PyDev - :\n' + \ 'IDLE - \n' tooltip_file_explorer = 'This is the program you normally use to "Browse" for files\n' + \ 'For Windows this is normally "explorer". On Linux "nemo" is sometimes used.' tooltip_theme = 'The normal default theme for PySimpleGUI is "Dark Blue 13\n' + \ - 'If you do not call theme("theme name") by your program to change the theme, then the default is used.\n' + \ - 'This setting allows you to set the theme that PySimpleGUI will use for ALL of your programs that\n' + \ - 'do not set a theme specifically.' - - + 'If you do not call theme("theme name") by your program to change the theme, then the default is used.\n' + \ + 'This setting allows you to set the theme that PySimpleGUI will use for ALL of your programs that\n' + \ + 'do not set a theme specifically.' layout = [[T('Global PySimpleGUI Settings', font='DEFAIULT 18')], - [T('Python Interpreter (normally leave blank)', font='_ 16')], - [T('Command to run a python program:'), In(settings.get('-python command-', ''),k='-PYTHON COMMAND-', enable_events=True), FileBrowse()], - [T('Editor Settings', font='_ 16')], - [T('Command to invoke your editor:'), In(settings.get('-editor program-', ''),k='-EDITOR PROGRAM-', enable_events=True), FileBrowse()], - [T('String to launch your editor to edit at a particular line #.')], - [T('Use tags to specify the string')], - [T('that will be executed to edit python files using your editor')], - [T('Edit Format String (hover for tooltip)',tooltip=tooltip), In(settings.get('-editor format string-', ' '),k='-EDITOR FORMAT-', tooltip=tooltip)], - [T('File Explorer Program', font='_ 16', tooltip=tooltip_file_explorer)], - [In(settings.get('-explorer program-', ''),k='-EXPLORER PROGRAM-', tooltip=tooltip_file_explorer)], - [T('Theme', font='_ 16')], - [T('Leave blank for "official" PySimpleGUI default theme: {}'.format(OFFICIAL_PYSIMPLEGUI_THEME))], - [T('Default Theme For All Programs:'), Combo([''] + theme_list(), settings.get('-theme-', None), readonly=True, k='-THEME-', tooltip=tooltip_theme)], + [T('Python Interpreter (normally leave blank)', font='_ 16')], + [T('Command to run a python program:'), In(settings.get('-python command-', ''), k='-PYTHON COMMAND-', enable_events=True), FileBrowse()], + [T('Editor Settings', font='_ 16')], + [T('Command to invoke your editor:'), In(settings.get('-editor program-', ''), k='-EDITOR PROGRAM-', enable_events=True), FileBrowse()], + [T('String to launch your editor to edit at a particular line #.')], + [T('Use tags to specify the string')], + [T('that will be executed to edit python files using your editor')], + [T('Edit Format String (hover for tooltip)', tooltip=tooltip), + In(settings.get('-editor format string-', ' '), k='-EDITOR FORMAT-', tooltip=tooltip)], + [T('File Explorer Program', font='_ 16', tooltip=tooltip_file_explorer)], + [In(settings.get('-explorer program-', ''), k='-EXPLORER PROGRAM-', tooltip=tooltip_file_explorer)], + [T('Theme', font='_ 16')], + [T('Leave blank for "official" PySimpleGUI default theme: {}'.format(OFFICIAL_PYSIMPLEGUI_THEME))], + [T('Default Theme For All Programs:'), + Combo([''] + theme_list(), settings.get('-theme-', None), readonly=True, k='-THEME-', tooltip=tooltip_theme)], # [T('Buttons (Leave Unchecked To Use Default) NOT YET IMPLEMENTED!', font='_ 16')], # [Checkbox('Always use TTK buttons'), CBox('Always use TK Buttons')], [B('Ok', bind_return_key=True), B('Cancel')], @@ -20501,6 +20576,7 @@ def main_global_pysimplegui_settings(): window.close() return False + # ..######..########..##....##....##.....##.########.##.......########. # .##....##.##.....##.##...##.....##.....##.##.......##.......##.....## # .##.......##.....##.##..##......##.....##.##.......##.......##.....## @@ -20510,45 +20586,44 @@ def main_global_pysimplegui_settings(): # ..######..########..##....##....##.....##.########.########.##....... - def main_sdk_help(): """ Display a window that will display the docstrings for each PySimpleGUI Element and the Window object """ online_help_links = { - 'Button': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#button-element', - 'ButtonMenu': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#buttonmenu-element', - 'Canvas': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#canvas-element', - 'Checkbox': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#checkbox-element', - 'Column': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#column-element', - 'Combo': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#combo-element', - 'Frame': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#frame-element', - 'Graph': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#graph-element', - 'HorizontalSeparator': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#horizontalseparator-element', - 'Image': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#image-element', - 'Input': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#input-element', - 'Listbox': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#listbox-element', - 'Menu': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#menu-element', - 'MenubarCustom': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#menubarcustom-element', - 'Multiline': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#multiline-element', - 'OptionMenu': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#optionmenu-element', - 'Output': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#output-element', - 'Pane': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#pane-element', - 'ProgressBar': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#progressbar-element', - 'Radio': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#radio-element', - 'Slider': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#slider-element', - 'Spin': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#spin-element', - 'StatusBar': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#statusbar-element', - 'Tab': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#tab-element', - 'TabGroup': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#tabgroup-element', - 'Table': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#table-element', - 'Text': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#text-element', - 'Titlebar' : r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#titlebar-element', - 'Tree': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#tree-element', - 'VerticalSeparator': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#verticalseparator-element', - 'Window': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#window', - } + 'Button': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#button-element', + 'ButtonMenu': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#buttonmenu-element', + 'Canvas': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#canvas-element', + 'Checkbox': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#checkbox-element', + 'Column': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#column-element', + 'Combo': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#combo-element', + 'Frame': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#frame-element', + 'Graph': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#graph-element', + 'HorizontalSeparator': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#horizontalseparator-element', + 'Image': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#image-element', + 'Input': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#input-element', + 'Listbox': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#listbox-element', + 'Menu': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#menu-element', + 'MenubarCustom': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#menubarcustom-element', + 'Multiline': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#multiline-element', + 'OptionMenu': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#optionmenu-element', + 'Output': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#output-element', + 'Pane': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#pane-element', + 'ProgressBar': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#progressbar-element', + 'Radio': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#radio-element', + 'Slider': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#slider-element', + 'Spin': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#spin-element', + 'StatusBar': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#statusbar-element', + 'Tab': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#tab-element', + 'TabGroup': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#tabgroup-element', + 'Table': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#table-element', + 'Text': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#text-element', + 'Titlebar': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#titlebar-element', + 'Tree': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#tree-element', + 'VerticalSeparator': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#verticalseparator-element', + 'Window': r'https://pysimplegui.readthedocs.io/en/latest/call%20reference/#window', + } element_classes = Element.__subclasses__() element_names = {element.__name__: element for element in element_classes} @@ -20571,7 +20646,7 @@ def main_sdk_help(): # print(defaults) if len(args) != len(defaults): diff = len(args) - len(defaults) - defaults = ('NO DEFAULT',)*diff + defaults + defaults = ('NO DEFAULT',) * diff + defaults args_defaults = [] for i, a in enumerate(args): args_defaults.append((a, defaults[i])) @@ -20582,15 +20657,15 @@ def main_sdk_help(): args = inspect.getargspec(element.update).args[1:] defaults = inspect.getargspec(element.update).defaults if args is None or defaults is None: - element_arg_default_dict_update[element.__name__] = (('',''),) + element_arg_default_dict_update[element.__name__] = (('', ''),) continue if len(args) != len(defaults): diff = len(args) - len(defaults) - defaults = ('NO DEFAULT',)*diff + defaults + defaults = ('NO DEFAULT',) * diff + defaults args_defaults = [] for i, a in enumerate(args): args_defaults.append((a, defaults[i])) - element_arg_default_dict_update[element.__name__] = args_defaults if len(args_defaults) else (('',''),) + element_arg_default_dict_update[element.__name__] = args_defaults if len(args_defaults) else (('', ''),) except Exception as e: pass @@ -20602,9 +20677,9 @@ def main_sdk_help(): buttons += [[B('Func Search', pad=(0, 0), size=(22, 1), font='Courier 10')]] button_col = Col(buttons) mline_col = Column([[Multiline(size=(100, 46), key='-ML-', write_only=True, reroute_stdout=True, font='Courier 10')], - [T(size=(80,1), font='Courier 10 underline', k='-DOC LINK-', enable_events=True)]], pad=(0,0)) + [T(size=(80, 1), font='Courier 10 underline', k='-DOC LINK-', enable_events=True)]], pad=(0, 0)) layout = [vtop([button_col, mline_col])] - layout += [[CBox('Summary Only', enable_events=True, k='-SUMMARY-'),CBox('Display Only PEP8 Functions',default=True, k='-PEP8-') ]] + layout += [[CBox('Summary Only', enable_events=True, k='-SUMMARY-'), CBox('Display Only PEP8 Functions', default=True, k='-PEP8-')]] # layout += [[Button('Exit', size=(15, 1))]] window = Window('SDK API Call Reference', layout, use_default_focus=False, keep_on_top=True, icon=EMOJI_BASE64_THINK, finalize=True) @@ -20625,7 +20700,7 @@ def main_sdk_help(): if event in element_names.keys(): current_element = event window['-ML-'].update('') - online_help_link = online_help_links.get(event,'') + online_help_link = online_help_links.get(event, '') window['-DOC LINK-'].update(online_help_link) if not values['-SUMMARY-']: elem = element_names[event] @@ -20658,34 +20733,33 @@ def main_sdk_help(): elem_text_name = event for parm, default in element_arg_default_dict[elem_text_name]: ml.print('{:18}'.format(parm), end=' = ') - ml.print(default, end = ',\n') + ml.print(default, end=',\n') if elem_text_name in element_arg_default_dict_update: ml.print('========== Update Parms ==========', background_color='#FFFF00', text_color='black') for parm, default in element_arg_default_dict_update[elem_text_name]: ml.print('{:18}'.format(parm), end=' = ') - ml.print(default, end = ',\n') - ml.set_vscroll_position(0) # scroll to top of multoline + ml.print(default, end=',\n') + ml.set_vscroll_position(0) # scroll to top of multoline elif event == 'Func Search': search_string = popup_get_text('Search for this in function list:', keep_on_top=True) if search_string is not None: - online_help_link = '' - window['-DOC LINK-'].update('') - ml.update('') - for f_entry in functions_names: - f = f_entry[0] - if search_string in f.lower() and not f.startswith('_'): - if (values['-PEP8-'] and not f[0].isupper()) or not values['-PEP8-']: - if values['-SUMMARY-']: - ml.print(f) - else: - ml.print('=========== ' + f +'===========' , background_color='#FFFF00', text_color='black') - ml.print(help(f_entry[1])) - ml.set_vscroll_position(0) # scroll to top of multoline + online_help_link = '' + window['-DOC LINK-'].update('') + ml.update('') + for f_entry in functions_names: + f = f_entry[0] + if search_string in f.lower() and not f.startswith('_'): + if (values['-PEP8-'] and not f[0].isupper()) or not values['-PEP8-']: + if values['-SUMMARY-']: + ml.print(f) + else: + ml.print('=========== ' + f + '===========', background_color='#FFFF00', text_color='black') + ml.print(help(f_entry[1])) + ml.set_vscroll_position(0) # scroll to top of multoline window.close() - # oo # # 88d8b.d8b. .d8888b. dP 88d888b. @@ -20711,8 +20785,6 @@ def main_sdk_help(): # MMMMMMMMMMM - - def _main_switch_theme(): layout = [ [Text('Click a look and feel color to see demo window')], @@ -20734,7 +20806,7 @@ def _create_main_window(): Creates the main test harness window. :return: The test window - :rtype: Window + :rtype: Window """ # theme('dark blue 3') @@ -20756,7 +20828,7 @@ def _create_main_window(): print('PySimpleGUI.py location', __file__) # ------ Menu Definition ------ # menu_def = [['&File', ['!&Open', '&Save::savekey', '---', '&Properties', 'E&xit']], - ['&Edit', ['&Paste', ['Special', 'Normal', '!Disabled' ], 'Undo'], ], + ['&Edit', ['&Paste', ['Special', 'Normal', '!Disabled'], 'Undo'], ], ['&Debugger', ['Popout', 'Launch Debugger']], ['!&Disabled', ['Popout', 'Launch Debugger']], ['&Toolbar', ['Command &1', 'Command &2', 'Command &3', 'Command &4']], @@ -20811,7 +20883,7 @@ def _create_main_window(): col_widths=[5, 5, 5, 5], size=(400, 200), ), T(' '), Tree(data=treedata, headings=['col1', 'col2', 'col3'], change_submits=True, auto_size_columns=True, - num_rows=10, col0_width=10, key='_TREE_', show_expanded=True,)]] + num_rows=10, col0_width=10, key='_TREE_', show_expanded=True, )]] frame7 = [[T('ONE thing.... you had one thing to NOT do. "Do NOT click"')], [Image(data=_random_error_emoji())], [T("""Well, now what?\nYou could take moment and help this project out by sponsoring. PySimpleGUI is costly to simply exist. If you work for a company and are receiving financial benefits in the way of cost @@ -20819,9 +20891,12 @@ savings or are selling a product, I hope that you will consider sharing a small If you don't want to sponsor / contribute, that's OK too. At the moment PySimpleGUI is still free of charge to use. You have no financial responsibility. I hope you are enjoying using PySimpleGUI whether you sponsor the product or not.""")], - [T('Click here to help --->>>'), T('YES - I want to support PySimpleGUI!', enable_events=True, text_color='red', background_color='yellow', k='-SPONSOR-')],] + [T('Click here to help --->>>'), + T('YES - I want to support PySimpleGUI!', enable_events=True, text_color='red', background_color='yellow', k='-SPONSOR-')], ] - pop_test_tab_layout = [[T('Popup Tests --->'), B('Popup', k='P '), B('No Titlebar', k='P NoTitle'), B('Not Modal', k='P NoModal'), B('Non Blocking', k='P NoBlock'), B('Auto Close', k='P AutoClose')]] + pop_test_tab_layout = [ + [T('Popup Tests --->'), B('Popup', k='P '), B('No Titlebar', k='P NoTitle'), B('Not Modal', k='P NoModal'), B('Non Blocking', k='P NoBlock'), + B('Auto Close', k='P AutoClose')]] graph_elem = Graph((600, 250), (0, 0), (800, 300), key='+GRAPH+') @@ -20829,20 +20904,19 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not global_settings_tab_layout = [[T('Global Settings:', font='_ 15')], [T('Settings Filename:'), T(pysimplegui_user_settings.full_filename)], - [T('Settings Dictionary:'), T(pysimplegui_user_settings.get_dict(), size=(60,5))], + [T('Settings Dictionary:'), T(pysimplegui_user_settings.get_dict(), size=(60, 5))], [], [], ] - - themes_tab_layout = [[T('You can see a preview of the themes, the color swatches, or switch themes for this window')], [T('If you want to change the default theme for PySimpleGUI, use the Global Settings')], [B('Themes'), B('Theme Swatches'), B('Switch Themes')]] tab1 = Tab('Graph\n', frame6, tooltip='Graph is in here', title_color='red') - 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('Binary Choice Group', frame3, title_color='#FFFFFF', tooltip='Binary Choice', vertical_alignment='t'), ]], pad=(0,0)) + 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('Binary Choice Group', frame3, title_color='#FFFFFF', tooltip='Binary Choice', vertical_alignment='t'), ]], pad=(0, 0)) # 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-') tab4 = Tab('Sliders\n', [[Frame('Variable Choice Group', frame4, title_color='blue')]], tooltip='tab 4', title_color='red', k='-TAB VAR-') @@ -20852,8 +20926,7 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not tab8 = Tab('Themes\n', themes_tab_layout, k='-TAB THEMES-') tab9 = Tab('Global\nSettings', global_settings_tab_layout, k='-TAB GlOBAL SETTINGS-') - - def VerLine(version, description, justification='r', size=(40,1)): + def VerLine(version, description, justification='r', size=(40, 1)): return [T(version, justification=justification, font='Any 12', text_color='yellow', size=size), vtop(T(description, font='Any 12'))] layout_top = Column([ @@ -20862,31 +20935,32 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not Text('PySimpleGUI Test Harness\nYou are running PySimpleGUI.py file instead of importing', font='ANY 15', tooltip='My tooltip', key='_TEXT1_')], VerLine(ver, 'PySimpleGUI Version'), - VerLine('{}/{}'.format(tkversion,tclversion),'TK/TCL Versions'), + VerLine('{}/{}'.format(tkversion, tclversion), 'TK/TCL Versions'), VerLine(tclversion_detailed, 'detailed tkinter version'), - VerLine(os.path.dirname(os.path.abspath(__file__)), 'PySimpleGUI Location', size=(40,2)), - VerLine(sys.version, 'Python Version', size=(40, 2))], pad=(0,0)) - + VerLine(os.path.dirname(os.path.abspath(__file__)), 'PySimpleGUI Location', size=(40, 2)), + VerLine(sys.version, 'Python Version', size=(40, 2))], pad=(0, 0)) layout_bottom = [ - [B(SYMBOL_DOWN, pad=(0,0), k='-HIDE TABS-'),pin(Col([[TabGroup([[tab1, tab2, tab3, tab6, tab4, tab5, tab7, tab8, tab9]], key='_TAB_GROUP_')]],k='-TAB GROUP-'))], - [Button('Button', highlight_colors=('yellow','red')), B('Hide Stuff', metadata='my metadata'), + [B(SYMBOL_DOWN, pad=(0, 0), k='-HIDE TABS-'), + pin(Col([[TabGroup([[tab1, tab2, tab3, tab6, tab4, tab5, tab7, tab8, tab9]], key='_TAB_GROUP_')]], k='-TAB GROUP-'))], + [Button('Button', highlight_colors=('yellow', 'red')), B('Hide Stuff', metadata='my metadata'), Button('ttk Button', use_ttk_buttons=True, tooltip='This is a TTK Button'), Button('See-through Mode', tooltip='Make the background transparent'), Button('Upgrade PySimpleGUI from GitHub', button_color='white on red', key='-INSTALL-'), Button('Global Settings', tooltip='Settings across all PySimpleGUI programs'), Button('Exit', tooltip='Exit button')], - [ B(image_data=ICON_BUY_ME_A_COFFEE, key='-COFFEE-'), - B('SDK Reference'), B('Open GitHub Issue'), B('Versions for GitHub'), - ButtonMenu('ButtonMenu', button_menu_def, key='-BMENU-', tearoff=True) - ]] + [B(image_data=ICON_BUY_ME_A_COFFEE, key='-COFFEE-'), + B('SDK Reference'), B('Open GitHub Issue'), B('Versions for GitHub'), + ButtonMenu('ButtonMenu', button_menu_def, key='-BMENU-', tearoff=True) + ]] layout = [[]] if not USE_CUSTOM_TITLEBAR: layout += [[Menu(menu_def, key='_MENU_', font='Courier 15', background_color='red', text_color='white', disabled_text_color='yellow', tearoff=True)]] else: - layout += [[MenubarCustom(menu_def, key='_MENU_', font='Courier 15', bar_background_color=theme_background_color(), bar_text_color=theme_text_color(), background_color='red', text_color='white', disabled_text_color='yellow')]] + layout += [[MenubarCustom(menu_def, key='_MENU_', font='Courier 15', bar_background_color=theme_background_color(), bar_text_color=theme_text_color(), + background_color='red', text_color='white', disabled_text_color='yellow')]] layout += [[layout_top] + [ProgressBar(max_value=800, size=(30, 25), orientation='v', key='+PROGRESS+')]] layout += layout_bottom @@ -20898,7 +20972,7 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not # transparent_color= '#9FB8AD', resizable=True, keep_on_top=True, - element_justification='left', # justify contents to the left + element_justification='left', # justify contents to the left metadata='My window metadata', finalize=True, grab_anywhere=True, @@ -20910,6 +20984,7 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not window._see_through = False return window + # M"""""`'"""`YM oo # M mm. mm. M # M MMM MMM M .d8888b. dP 88d888b. @@ -20919,7 +20994,6 @@ I hope you are enjoying using PySimpleGUI whether you sponsor the product or not # MMMMMMMMMMMMMM - def main(): """ The PySimpleGUI "Test Harness". This is meant to be a super-quick test of the Elements. @@ -20957,7 +21031,8 @@ def main(): elif event == 'Launch Debugger': show_debugger_window() elif event == 'About...': - popup('About this program...', 'You are looking at the test harness for the PySimpleGUI program', version,keep_on_top=True, image=DEFAULT_BASE64_ICON) + popup('About this program...', 'You are looking at the test harness for the PySimpleGUI program', version, keep_on_top=True, + image=DEFAULT_BASE64_ICON) elif event.startswith('See'): window._see_through = not window._see_through window.set_transparent_color(theme_background_color() if window._see_through else '') @@ -21001,11 +21076,11 @@ def main(): popup_no_titlebar('No titlebar', keep_on_top=True) elif event == 'P NoModal': popup('Normal Popup - Not Modal', 'You can interact with main window menubar ', - 'but will have no effect immediately', 'button clicks will happen after you close this popup',modal=False, keep_on_top=True) + 'but will have no effect immediately', 'button clicks will happen after you close this popup', modal=False, keep_on_top=True) elif event == 'P NoBlock': popup_non_blocking('Non-blocking', 'The background window should still be running', keep_on_top=True) elif event == 'P AutoClose': - popup_auto_close('Will autoclose in 3 seconds', auto_close_duration=3 ,keep_on_top=True) + popup_auto_close('Will autoclose in 3 seconds', auto_close_duration=3, keep_on_top=True) elif event == 'Versions for GitHub': main_get_debug_data() elif event == 'Open GitHub Issue': @@ -21074,7 +21149,7 @@ test = main sdk_help = main_sdk_help pysimplegui_user_settings = UserSettings(filename=DEFAULT_USER_SETTINGS_PYSIMPLEGUI_FILENAME, path=DEFAULT_USER_SETTINGS_PYSIMPLEGUI_PATH) -#------------------------ Set the "Official PySimpleGUI Theme Colors" ------------------------ +# ------------------------ Set the "Official PySimpleGUI Theme Colors" ------------------------ theme(theme_global())