LOTS of new doc strings. Renamed some functions to begin with _. Window.Show, ReadNonBlocking, Added giant licensing info
This commit is contained in:
parent
9adb0e3691
commit
dab3f1f1f3
357
PySimpleGUI.py
357
PySimpleGUI.py
|
@ -1,8 +1,103 @@
|
|||
#!/usr/bin/python3
|
||||
version = __version__ = "4.1.0.5 Unreleased"
|
||||
version = __version__ = "4.1.0.8 Unreleased"
|
||||
|
||||
|
||||
# 888888ba .d88888b oo dP .88888. dP dP dP
|
||||
# 88 `8b 88. "' 88 d8' `88 88 88 88
|
||||
# a88aaaa8P' dP dP `Y88888b. dP 88d8b.d8b. 88d888b. 88 .d8888b. 88 88 88 88
|
||||
# 88 88 88 `8b 88 88'`88'`88 88' `88 88 88ooood8 88 YP88 88 88 88
|
||||
# 88 88. .88 d8' .8P 88 88 88 88 88. .88 88 88. ... Y8. .88 Y8. .8P 88
|
||||
# dP `8888P88 Y88888P dP dP dP dP 88Y888P' dP `88888P' `88888' `Y88888P' dP
|
||||
# .88 88
|
||||
# d8888P dP
|
||||
|
||||
|
||||
|
||||
|
||||
# __ __
|
||||
# / | / |
|
||||
# $$ | ______ ______ ______ $$ |
|
||||
# $$ | / \ / \ / \ $$ |
|
||||
# $$ | /$$$$$$ |/$$$$$$ | $$$$$$ |$$ |
|
||||
# $$ | $$ $$ |$$ | $$ | / $$ |$$ |
|
||||
# $$ |_____ $$$$$$$$/ $$ \__$$ |/$$$$$$$ |$$ |
|
||||
# $$ |$$ |$$ $$ |$$ $$ |$$ |
|
||||
# $$$$$$$$/ $$$$$$$/ $$$$$$$ | $$$$$$$/ $$/
|
||||
# / \__$$ |
|
||||
# $$ $$/
|
||||
# $$$$$$/
|
||||
|
||||
|
||||
"""
|
||||
Copyright 2018, 2019 PySimpleGUI.org
|
||||
|
||||
OK, let's get the bullshit out of the way
|
||||
|
||||
This software is available for your use under a MODIFIED LGPL3+ license
|
||||
|
||||
This notice, these first 83 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
|
||||
888 888 888 d88P 888 8888" 888
|
||||
888 888 88888 8888888P" 888 "Y8b. 8888888
|
||||
888 888 888 888 888 888 888 888
|
||||
888 Y88b d88P 888 888 Y88b d88P
|
||||
88888888 "Y8888P88 888 88888888 "Y8888P"
|
||||
|
||||
|
||||
And just what the fuck is that? Well, it's LPGL3+ and these FOUR simple stipulations.
|
||||
1. These and all comments are to remain in this document
|
||||
2. You will not post this software in a repository or a location for others to download from:
|
||||
A. Unless you have made 10 lines of changes
|
||||
3. Forking is OK and does NOT require any changes as long as it is obvious forked and stated on the page
|
||||
where your software is being hosted. For example, GitHub does a fantastic job of indicating if a repository
|
||||
is the result of a fork.
|
||||
4. 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. 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.
|
||||
Please don't waste anyone's time by filing an Issue unless you have a genuine copy of the software.
|
||||
|
||||
-----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
I absolutely hate having to include that nonsense, but every word is there for solid reasons.
|
||||
|
||||
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. And nearly 200
|
||||
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! 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://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.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
# do the Python 2 or 3 check so the right tkinter stuff can get pulled in
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] >= 3:
|
||||
import tkinter as tk
|
||||
from tkinter import filedialog
|
||||
|
@ -10,7 +105,7 @@ if sys.version_info[0] >= 3:
|
|||
from tkinter import ttk
|
||||
import tkinter.scrolledtext as tkst
|
||||
import tkinter.font
|
||||
else:
|
||||
else: # Do NOT remove any of these regardless of what your IDE or lint says. They are transformed in the 3 to 2 process
|
||||
import Tkinter as tk
|
||||
import tkFileDialog
|
||||
import ttk
|
||||
|
@ -24,19 +119,10 @@ import pickle
|
|||
import calendar
|
||||
import textwrap
|
||||
import inspect
|
||||
from typing import List, Any, Union
|
||||
from typing import List, Any, Union, Tuple, Dict
|
||||
from random import randint
|
||||
import warnings
|
||||
|
||||
# 888888ba .d88888b oo dP .88888. dP dP dP
|
||||
# 88 `8b 88. "' 88 d8' `88 88 88 88
|
||||
# a88aaaa8P' dP dP `Y88888b. dP 88d8b.d8b. 88d888b. 88 .d8888b. 88 88 88 88
|
||||
# 88 88 88 `8b 88 88'`88'`88 88' `88 88 88ooood8 88 YP88 88 88 88
|
||||
# 88 88. .88 d8' .8P 88 88 88 88 88. .88 88 88. ... Y8. .88 Y8. .8P 88
|
||||
# dP `8888P88 Y88888P dP dP dP dP 88Y888P' dP `88888P' `88888' `Y88888P' dP
|
||||
# .88 88
|
||||
# d8888P dP
|
||||
|
||||
|
||||
|
||||
g_time_start = 0
|
||||
|
@ -1315,7 +1401,7 @@ class Spin(Element):
|
|||
"""
|
||||
|
||||
:param values: List[Any] List of valid values
|
||||
:param initial_value: [Any] Initial item to show in window. Choose from list of values supplied
|
||||
:param initial_value: (Any) Initial item to show in window. Choose from list of values supplied
|
||||
:param disabled: (bool) set disable state
|
||||
:param change_submits: (bool) DO NOT USE. Only listed for backwards compat - Use enable_events instead
|
||||
:param enable_events: (bool) Turns on the element specific events. Spin events happen when an item changes
|
||||
|
@ -1411,7 +1497,9 @@ class Spin(Element):
|
|||
# ---------------------------------------------------------------------- #
|
||||
class Multiline(Element):
|
||||
"""
|
||||
Multiline Element - Display and read multiple lines of text. This is both an input and output element.
|
||||
Multiline Element - Display and/or read multiple lines of text. This is both an input and output element.
|
||||
Other PySimpleGUI ports have a separate MultilineInput and MultilineOutput elements. May want to split this
|
||||
one up in the future too.
|
||||
"""
|
||||
|
||||
def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, border_width=None,
|
||||
|
@ -1452,8 +1540,7 @@ class Multiline(Element):
|
|||
self.ChangeSubmits = change_submits or enable_events
|
||||
self.RightClickMenu = right_click_menu
|
||||
self.BorderWidth = border_width if border_width is not None else DEFAULT_BORDER_WIDTH
|
||||
self.TKText = self.Widget = None # type: tk.scrolledtext.ScrolledText
|
||||
|
||||
self.TKText = self.Widget = None # type: tkst.ScrolledText
|
||||
super().__init__(ELEM_TYPE_INPUT_MULTILINE, size=size, auto_size_text=auto_size_text, background_color=bg,
|
||||
text_color=fg, key=key, pad=pad, tooltip=tooltip, font=font or DEFAULT_FONT, visible=visible)
|
||||
return
|
||||
|
@ -1508,14 +1595,14 @@ class Multiline(Element):
|
|||
"""
|
||||
Return current contents of the Multiline Element
|
||||
|
||||
:return: (str) current contents of the Multiline Input element
|
||||
:return: (str) current contents of the Multiline Element (used as an input type of Multiline
|
||||
"""
|
||||
|
||||
return self.TKText.get(1.0, tk.END)
|
||||
|
||||
def SetFocus(self, force=False):
|
||||
"""
|
||||
Moves the focus to this Multiline
|
||||
Moves the focus (that little blinking cursor) to this Multiline Element
|
||||
|
||||
:param force: (bool). If True, will call focus_force instead of focus_set
|
||||
"""
|
||||
|
@ -1537,8 +1624,7 @@ class Multiline(Element):
|
|||
# ---------------------------------------------------------------------- #
|
||||
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.
|
||||
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), auto_size_text=None, click_submits=False, enable_events=False,
|
||||
|
@ -1619,28 +1705,28 @@ T = Text
|
|||
# StatusBar #
|
||||
# ---------------------------------------------------------------------- #
|
||||
class StatusBar(Element):
|
||||
""" """
|
||||
|
||||
"""
|
||||
A StatusBar Element creates the sunken text-filled strip at the bottom. Many Windows programs have this line
|
||||
"""
|
||||
def __init__(self, text, size=(None, None), auto_size_text=None, click_submits=None, enable_events=False,
|
||||
relief=RELIEF_SUNKEN, font=None, text_color=None, background_color=None, justification=None, pad=None,
|
||||
key=None, tooltip=None, visible=True):
|
||||
"""
|
||||
|
||||
:param text: (required) text that is to be displayed in the widget
|
||||
:param text: Text that is to be displayed in the widget
|
||||
:param size: (w,h) w=characters-wide, h=rows-high
|
||||
:param auto_size_text: True if size should fit the text length
|
||||
:param click_submits: ????????????????????
|
||||
:param enable_events: Turns on the element specific events.(Default = False)
|
||||
: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 = RELIEF_SUNKEN)
|
||||
:param font: specifies the font family, size, etc
|
||||
:param text_color: color of the text
|
||||
:param background_color: color of background
|
||||
:param justification: justification for data display
|
||||
:param pad: Amount of padding to put around element
|
||||
:param key: Used with window.FindElement and with return values to uniquely identify this element to uniquely identify this element
|
||||
:param click_submits: (bool) DO NOT USE. Only listed for backwards compat - Use enable_events instead
|
||||
:param enable_events: (bool) Turns on the element specific events. StatusBar events occur when the bar is clicked
|
||||
: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`
|
||||
:param font: Union[str, tuple] specifies the font family, size, etc
|
||||
:param text_color: (str) color of the text
|
||||
:param background_color: (str) color of background
|
||||
:param justification: (str) how string should be aligned within space provided by size. Valid choices = `left`, `right`, `center`
|
||||
:param pad: (int, int) or ((int, int),(int,int)) Amount of padding to put around element (left/right, top/bottom) or ((left, right), (top, bottom))
|
||||
:param key: (Any) Used with window.FindElement and with return values to uniquely identify this element to uniquely identify this element
|
||||
:param tooltip: (str) text, that will appear when mouse hovers over the element
|
||||
:param visible: set visibility state of the element (Default = True)
|
||||
|
||||
:param visible: (bool) set visibility state of the element
|
||||
"""
|
||||
|
||||
self.DisplayText = text
|
||||
|
@ -1663,11 +1749,11 @@ class StatusBar(Element):
|
|||
"""
|
||||
Changes some of the settings for the Status Bar Element. Must call `Window.Read` or `Window.Finalize` prior
|
||||
|
||||
:param value: ??????????????????????????
|
||||
:param background_color: color of background
|
||||
:param text_color: color of the text
|
||||
:param font: specifies the font family, size, etc
|
||||
:param visible: (bool) control visibility of element
|
||||
:param value: (str) new text to show
|
||||
:param background_color: (str) color of background
|
||||
:param text_color: (str) color of the text
|
||||
:param font: Union[str, tuple] specifies the font family, size, etc
|
||||
:param visible: (bool) set visibility state of the element
|
||||
"""
|
||||
|
||||
if value is not None:
|
||||
|
@ -4625,39 +4711,38 @@ class Window:
|
|||
disable_minimize=False, right_click_menu=None, transparent_color=None, debugger_enabled=True):
|
||||
"""
|
||||
|
||||
:param title:
|
||||
:param layout:
|
||||
:param default_element_size: (Default value = DEFAULT_ELEMENT_SIZE)
|
||||
:param default_button_element_size:
|
||||
:param auto_size_text: True if size should fit the text length
|
||||
:param auto_size_buttons:
|
||||
:param location: (Default = (None))
|
||||
:param size: (w,h) w=characters-wide, h=rows-high (Default = (None))
|
||||
:param element_padding:
|
||||
:param margins: (Default = (None))
|
||||
:param button_color: button color (foreground, background)
|
||||
:param font: specifies the font family, size, etc
|
||||
:param progress_bar_color: (Default = (None))
|
||||
:param background_color: color of background
|
||||
:param border_depth:
|
||||
:param auto_close: (Default = False)
|
||||
:param auto_close_duration: (Default value = DEFAULT_AUTOCLOSE_TIME)
|
||||
:param icon: Icon to display. Filled in with default icon in init (Default value = None)
|
||||
:param force_toplevel: (Default = False)
|
||||
:param alpha_channel: (Default value = 1)
|
||||
:param return_keyboard_events: (Default = False)
|
||||
:param use_default_focus: (Default = True)
|
||||
:param text_justification:
|
||||
:param no_titlebar: (Default = False)
|
||||
:param grab_anywhere: If True can grab anywhere to move the window (Default = False)
|
||||
:param location: Location on screen to display
|
||||
:param resizable: (Default = False)
|
||||
:param disable_close: (Default = False)
|
||||
:param disable_minimize: (Default = False)
|
||||
:param title: (str) The title that will be displayed in the Titlebar and on the Taskbar
|
||||
:param layout: List[List[Elements]] The layout for the window. Can also be specified in the Layout method
|
||||
:param default_element_size: Tuple[int, int] (width, height) size in characters (wide) and rows (high) for all elements in this window
|
||||
:param default_button_element_size: Tuple[int, int] (width, height) size in characters (wide) and rows (high) for all Button elements in this window
|
||||
:param auto_size_text: (bool) True if Elements in Window should be sized to exactly fir the length of text
|
||||
:param auto_size_buttons: (bool) True if Buttons in this Window should be sized to exactly fit the text on this.
|
||||
:param location: Tuple[int, int] (x,y) location, in pixels, to locate the upper left corner of the window on the screen. Default is to center on screen.
|
||||
:param size: Tuple[int, int] (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
|
||||
:param element_padding: Tuple[int, int] or ((int, int),(int,int)) Default amount of padding to put around elements in window (left/right, top/bottom) or ((left, right), (top, bottom))
|
||||
:param margins: Tuple[int, int] (left/right, top/bottom) Amount of pixels to leave inside the window's frame around the edges before your elements are shown.
|
||||
:param button_color: Tuple[str, str] (text color, button color) Default button colors for all buttons in the window
|
||||
:param font: Union[str, tuple] specifies the font family, size. Uses one of two font specifications formats
|
||||
:param progress_bar_color: Tuple[str, str] (bar color, background color) Sets the default colors for all progress bars in the window
|
||||
:param background_color: (str) color of background
|
||||
:param border_depth: (int) Default border depth (width) for all elements in the window
|
||||
:param auto_close: (bool) If True, the window will automatically close itself
|
||||
:param auto_close_duration: (int) Number of seconds to wait before closing the window
|
||||
:param icon: Union[str, str] Can be either a filename or Base64 value.
|
||||
:param force_toplevel: (bool) If True will cause this window to skip the normal use of a hidden master window
|
||||
:param alpha_channel: (float) 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.
|
||||
:param return_keyboard_events: (bool) if True key presses on the keyboard will be returned as Events from Read calls
|
||||
:param use_default_focus: (bool) If True will use the default focus algorithm to set the focus to the "Correct" element
|
||||
:param text_justification: (str) Union ['left', 'right', 'center'] Default text justification for all Text Elements in window
|
||||
:param no_titlebar: (bool) 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
|
||||
:param grab_anywhere: (bool) 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
|
||||
:param keep_on_top: (bool) 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
|
||||
:param resizable: (bool) If True, allows the user to resize the window. Note the not all Elements will change size or location when resizing.
|
||||
:param disable_close: (bool) 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
|
||||
:param disable_minimize: (bool) if True the user won't be able to minimize window. Good for taking over entire screen and staying that way.
|
||||
:param right_click_menu: List[List[str]] see "Right Click Menus" for format
|
||||
:param transparent_color:
|
||||
:param debugger_enabled: (Default = True)
|
||||
|
||||
:param transparent_color: (str) 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.
|
||||
:param debugger_enabled: (bool) If True then the internal debugger will be enabled
|
||||
"""
|
||||
|
||||
self.AutoSizeText = auto_size_text if auto_size_text is not None else DEFAULT_AUTOSIZE_TEXT
|
||||
|
@ -4742,10 +4827,12 @@ class Window:
|
|||
|
||||
# ------------------------- Add ONE Row to Form ------------------------- #
|
||||
def AddRow(self, *args):
|
||||
"""Parms are a variable number of Elements
|
||||
|
||||
:param *args:
|
||||
"""
|
||||
Adds a single row of elements to a window's self.Rows variables.
|
||||
Generally speaking this is NOT how users should be building Window layouts.
|
||||
Users, create a single layout (a list of lists) and pass as a parameter to Window object, or call Window.Layout(layout)
|
||||
|
||||
:param *args: List[Elements]
|
||||
"""
|
||||
NumRows = len(self.Rows) # number of existing rows is our row number
|
||||
CurrentRowNumber = NumRows # this row's number
|
||||
|
@ -4780,8 +4867,9 @@ class Window:
|
|||
# ------------------------- Add Multiple Rows to Form ------------------------- #
|
||||
def AddRows(self, rows):
|
||||
"""
|
||||
Loops through a list of lists of elements and adds each row, list, to the layout
|
||||
|
||||
:param rows:
|
||||
:param rows: List[List[Elements]] A list of a list of elements
|
||||
|
||||
"""
|
||||
for row in rows:
|
||||
|
@ -4789,9 +4877,12 @@ class Window:
|
|||
|
||||
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
|
||||
a parameter to Window object. The parameter method is the currently preferred method. This call to Layout
|
||||
has been removed from examples contained in documents and in the Demo Programs. Trying to remove this call
|
||||
from history and replace with sending as a parameter to Window.
|
||||
|
||||
:param rows:
|
||||
|
||||
:param rows: List[List[Elements]] Your entire layout
|
||||
"""
|
||||
self.AddRows(rows)
|
||||
self.BuildKeyDict()
|
||||
|
@ -4799,31 +4890,32 @@ class Window:
|
|||
|
||||
def LayoutAndRead(self, rows, non_blocking=False):
|
||||
"""
|
||||
|
||||
Deprecated. Now you layout your window's rows (layout) and then separately call Read.
|
||||
:param rows:
|
||||
:param non_blocking: (Default = False)
|
||||
|
||||
"""
|
||||
raise DeprecationWarning(
|
||||
'LayoutAndRead is no longer supported... change your call window.Layout(layout).Read()')
|
||||
'LayoutAndRead is no longer supported... change your call window.Layout(layout).Read()\nor window(title, layout).Read()')
|
||||
# self.AddRows(rows)
|
||||
# self.Show(non_blocking=non_blocking)
|
||||
# self._Show(non_blocking=non_blocking)
|
||||
# return self.ReturnValues
|
||||
|
||||
def LayoutAndShow(self, rows):
|
||||
"""
|
||||
|
||||
Deprecated - do not use any longer. Layout your window and then call Read. Or can add a Finalize call before the Read
|
||||
:param rows:
|
||||
|
||||
"""
|
||||
raise DeprecationWarning('LayoutAndShow is no longer supported... ')
|
||||
|
||||
# ------------------------- ShowForm THIS IS IT! ------------------------- #
|
||||
def Show(self, non_blocking=False):
|
||||
|
||||
def _Show(self, non_blocking=False):
|
||||
"""
|
||||
NOT TO BE CALLED BY USERS. INTERNAL ONLY!
|
||||
It's this
|
||||
|
||||
:param non_blocking: (Default = False)
|
||||
|
||||
:param non_blocking: (bool) if True, this is a non-blocking call
|
||||
"""
|
||||
self.Shown = True
|
||||
# Compute num rows & num cols (it'll come in handy debugging)
|
||||
|
@ -4861,9 +4953,13 @@ class Window:
|
|||
# ------------------------- SetIcon - set the window's fav icon ------------------------- #
|
||||
def SetIcon(self, icon=None, pngbase64=None):
|
||||
"""
|
||||
Sets the icon that is shown on the title bar and on the task bar. Can pass in:
|
||||
* a filename which must be a .ICO icon file.
|
||||
* a bytes object
|
||||
* a BASE64 encoded file held in a variable
|
||||
|
||||
:param icon:
|
||||
:param pngbase64:
|
||||
:param icon: (str) Filename or bytes object
|
||||
:param pngbase64: (str) Base64 encoded GIF or PNG file
|
||||
|
||||
"""
|
||||
if type(icon) is bytes:
|
||||
|
@ -4890,21 +4986,32 @@ class Window:
|
|||
|
||||
def _GetElementAtLocation(self, location):
|
||||
"""
|
||||
Given a (row, col) location in a layout, return the element located at that position
|
||||
|
||||
:param location:
|
||||
|
||||
:param location: Tuple[int, int] Return the element located at (row, col) in layout
|
||||
:return: (Element) The Element located at that position in this window
|
||||
"""
|
||||
|
||||
(row_num, col_num) = location
|
||||
row = self.Rows[row_num]
|
||||
element = row[col_num]
|
||||
return element
|
||||
|
||||
def _GetDefaultElementSize(self):
|
||||
""" """
|
||||
"""
|
||||
Returns the default elementSize
|
||||
|
||||
:return: Tuple[int, int] (width, height) of the default element size
|
||||
"""
|
||||
|
||||
return self.DefaultElementSize
|
||||
|
||||
def _AutoCloseAlarmCallback(self):
|
||||
""" """
|
||||
"""
|
||||
Function that's called by tkinter when autoclode timer expires. Closes the window
|
||||
|
||||
:return: None
|
||||
"""
|
||||
try:
|
||||
window = self
|
||||
if window:
|
||||
|
@ -4918,7 +5025,11 @@ class Window:
|
|||
pass
|
||||
|
||||
def _TimeoutAlarmCallback(self):
|
||||
""" """
|
||||
"""
|
||||
Read Timeout Alarm callback. Will kick a mainloop call out of the tkinter event loop and cause it to return
|
||||
|
||||
:return: None
|
||||
"""
|
||||
# first, get the results table built
|
||||
# modify the Results table in the parent FlexForm object
|
||||
# print('TIMEOUT CALLBACK')
|
||||
|
@ -4931,17 +5042,21 @@ class Window:
|
|||
|
||||
def Read(self, timeout=None, timeout_key=TIMEOUT_KEY):
|
||||
"""
|
||||
THE biggest deal method in the Window class! This is how you get all of your data from your Window.
|
||||
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: timeout to wait, till Read will execute itself
|
||||
:param timeout_key: (Default value = TIMEOUT_KEY)
|
||||
|
||||
:param timeout: (int) Milliseconds to wait until the Read will return IF no other GUI events happen first
|
||||
:param timeout_key: (Any) The value that will be returned from the call if the timer expired
|
||||
:return: Tuple[(Any), Union[Dict[Any:Any], List[Any], None] (event, values)
|
||||
(event or timeout_key or None, Dictionary of values or List of values from all elements in the Window
|
||||
"""
|
||||
# ensure called only 1 time through a single read cycle
|
||||
if not Window.read_call_from_debugger:
|
||||
_refresh_debugger()
|
||||
timeout = int(timeout) if timeout is not None else None
|
||||
if timeout == 0: # timeout of zero runs the old readnonblocking
|
||||
event, values = self.ReadNonBlocking()
|
||||
event, values = self._ReadNonBlocking()
|
||||
if event is None:
|
||||
event = timeout_key
|
||||
if values is None:
|
||||
|
@ -4954,7 +5069,7 @@ class Window:
|
|||
if self.TKrootDestroyed:
|
||||
return None, None
|
||||
if not self.Shown:
|
||||
self.Show()
|
||||
self._Show()
|
||||
else:
|
||||
# if already have a button waiting, the return previously built results
|
||||
if self.LastButtonClicked is not None and not self.LastButtonClickedWasRealtime:
|
||||
|
@ -5044,8 +5159,13 @@ class Window:
|
|||
self.ReturnValues = self.TimeoutKey, self.ReturnValues[1] # fake a timeout
|
||||
return self.ReturnValues
|
||||
|
||||
def ReadNonBlocking(self):
|
||||
""" """
|
||||
def _ReadNonBlocking(self):
|
||||
"""
|
||||
Should be never called directly by the user. The user can call Window.Read(timeout=0) to get same effect
|
||||
|
||||
:return: Tuple[(Any), Union[Dict[Any:Any], List[Any], None] (event, values)
|
||||
(event or timeout_key or None, Dictionary of values or List of values from all elements in the Window
|
||||
"""
|
||||
if self.TKrootDestroyed:
|
||||
try:
|
||||
self.TKroot.quit()
|
||||
|
@ -5055,7 +5175,7 @@ class Window:
|
|||
# print('DESTROY FAILED')
|
||||
return None, None
|
||||
if not self.Shown:
|
||||
self.Show(non_blocking=True)
|
||||
self._Show(non_blocking=True)
|
||||
try:
|
||||
rc = self.TKroot.update()
|
||||
except:
|
||||
|
@ -5075,11 +5195,18 @@ class Window:
|
|||
return BuildResults(self, False, self)
|
||||
|
||||
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: (Window) Returns 'self' so that method "Chaining" can happen (read up about it as it's very cool!)
|
||||
"""
|
||||
|
||||
if self.TKrootDestroyed:
|
||||
return self
|
||||
if not self.Shown:
|
||||
self.Show(non_blocking=True)
|
||||
self._Show(non_blocking=True)
|
||||
try:
|
||||
rc = self.TKroot.update()
|
||||
except:
|
||||
|
@ -5089,8 +5216,17 @@ class Window:
|
|||
# return None, None
|
||||
return self
|
||||
|
||||
|
||||
def Refresh(self):
|
||||
""" """
|
||||
"""
|
||||
Refreshes the window by calling tkroot.update(). Can sometimes get away with a refresh instead of a Read.
|
||||
Use this call when you want something to appear in your Window immediately (as soon as this function is called).
|
||||
Without this call your changes to a Window will not be visible to the user until the next Read call
|
||||
|
||||
:return: Tuple[(Any), Union[Dict[Any:Any], List[Any], None] (event, values)
|
||||
(event or timeout_key or None, Dictionary of values or List of values from all elements in the Window
|
||||
"""
|
||||
|
||||
if self.TKrootDestroyed:
|
||||
return self
|
||||
try:
|
||||
|
@ -5350,6 +5486,7 @@ class Window:
|
|||
pass
|
||||
# if down to 1 window, try and destroy the hidden window, if there is one
|
||||
if Window.NumOpenWindows == 1:
|
||||
# print('Trying to destroy hidden')
|
||||
try:
|
||||
Window.hidden_master_root.destroy()
|
||||
Window.NumOpenWindows = 0 # if no hidden window, then this won't execute
|
||||
|
@ -8122,7 +8259,6 @@ def StartupTK(my_flex_form: Window):
|
|||
# print('Starting TK open Windows = {}'.format(ow))
|
||||
if ENABLE_TK_WINDOWS:
|
||||
root = tk.Tk()
|
||||
Window.IncrementOpenCount()
|
||||
elif not ow and not my_flex_form.ForceTopLevel:
|
||||
# if first window being created, make a throwaway, hidden master root. This stops one user
|
||||
# window from becoming the child of another user window. All windows are children of this
|
||||
|
@ -10127,10 +10263,13 @@ class _Debugger():
|
|||
try:
|
||||
result = eval('{}'.format(cmd), myglobals, mylocals)
|
||||
except Exception as e:
|
||||
try:
|
||||
result = exec('{}'.format(cmd), myglobals, mylocals)
|
||||
except Exception as e:
|
||||
result = 'Exception {}\n'.format(e)
|
||||
if sys.version_info[0] < 3:
|
||||
result = 'Not available in Python 2'
|
||||
else:
|
||||
try:
|
||||
result = exec('{}'.format(cmd), myglobals, mylocals)
|
||||
except Exception as e:
|
||||
result = 'Exception {}\n'.format(e)
|
||||
|
||||
self.watcher_window.Element('_OUTPUT_').Update('{}\n'.format(result), append=True, autoscroll=True)
|
||||
# BUTTON - DETAIL
|
||||
|
|
Loading…
Reference in New Issue