Merge pull request #1675 from PySimpleGUI/Dev-latest
More docstrings, renamed functions
This commit is contained in:
commit
69342202b2
295
PySimpleGUI.py
295
PySimpleGUI.py
|
@ -35,7 +35,7 @@ OK, let's get the bullshit out of the way
|
||||||
|
|
||||||
This software is available for your use under a MODIFIED LGPL3+ license
|
This software is available for your use under a MODIFIED LGPL3+ license
|
||||||
|
|
||||||
This notice, these first 83 lines of code shall remain unchanged
|
This notice, these first 100 lines of code shall remain unchanged
|
||||||
|
|
||||||
# #
|
# #
|
||||||
## ## #### ##### # ###### # ###### #####
|
## ## #### ##### # ###### # ###### #####
|
||||||
|
@ -60,12 +60,13 @@ And just what the fuck is that? Well, it's LPGL3+ and these FOUR simple stipula
|
||||||
1. These and all comments are to remain in this document
|
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:
|
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
|
A. Unless you have made 10 lines of changes
|
||||||
|
B. A notice is posted with the code that it is not the original code but instead derived from an original
|
||||||
3. Forking is OK and does NOT require any changes as long as it is obvious forked and stated on the page
|
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
|
where your software is being hosted. For example, GitHub does a fantastic job of indicating if a repository
|
||||||
is the result of a fork.
|
is the result of a fork.
|
||||||
4. The "Official" version of PySimpleGUI and the associated documentation lives on two (and only two) places:
|
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:
|
1. GitHub - (http://www.PySimpleGUI.com) currently pointing at:
|
||||||
# https://github.com/PySimpleGUI/PySimpleGUI
|
https://github.com/PySimpleGUI/PySimpleGUI
|
||||||
2. Read the Docs (via http://www.PySimpleGUI.org). Currently is pointed at:
|
2. Read the Docs (via http://www.PySimpleGUI.org). Currently is pointed at:
|
||||||
https://pysimplegui.readthedocs.io/en/latest/
|
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.
|
If you've obtained this software in any other way, then those listed here, then SUPPORT WILL NOT BE PROVIDED.
|
||||||
|
@ -73,7 +74,7 @@ And just what the fuck is that? Well, it's LPGL3+ and these FOUR simple stipula
|
||||||
|
|
||||||
-----------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
I absolutely hate having to include that nonsense, but every word is there for solid reasons.
|
I absolutely hate having to include this kind of nonsense, but every word is here for solid reasons.
|
||||||
|
|
||||||
How about having FUN with this package?? Terrible note to begin this journey of actually having fun making
|
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.
|
GUI based applications so I'll try to make it up to you.
|
||||||
|
@ -96,6 +97,7 @@ The User Manual and the Cookbook are both designed to paint some nice looking GU
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# do the Python 2 or 3 check so the right tkinter stuff can get pulled in
|
# do the Python 2 or 3 check so the right tkinter stuff can get pulled in
|
||||||
import sys
|
import sys
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
|
@ -119,7 +121,7 @@ import pickle
|
||||||
import calendar
|
import calendar
|
||||||
import textwrap
|
import textwrap
|
||||||
import inspect
|
import inspect
|
||||||
from typing import List, Any, Union, Tuple, Dict
|
from typing import List, Any, Union, Tuple, Dict # because this code has to run on 2.7 can't use real type hints. Must do typing only in comments
|
||||||
from random import randint
|
from random import randint
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -1713,12 +1715,12 @@ class StatusBar(Element):
|
||||||
key=None, tooltip=None, visible=True):
|
key=None, tooltip=None, visible=True):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param text: Text that is to be displayed in the widget
|
:param text: (str) Text that is to be displayed in the widget
|
||||||
:param size: (w,h) w=characters-wide, h=rows-high
|
:param size: Tuple[(int), (int)] (w,h) w=characters-wide, h=rows-high
|
||||||
:param auto_size_text: True if size should fit the text length
|
:param auto_size_text: (bool) True if size should fit the text length
|
||||||
:param click_submits: (bool) DO NOT USE. Only listed for backwards compat - Use enable_events instead
|
: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 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 relief: (enum) 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 font: Union[str, tuple] specifies the font family, size, etc
|
||||||
:param text_color: (str) color of the text
|
:param text_color: (str) color of the text
|
||||||
:param background_color: (str) color of background
|
:param background_color: (str) color of background
|
||||||
|
@ -1748,7 +1750,6 @@ class StatusBar(Element):
|
||||||
def Update(self, value=None, background_color=None, text_color=None, font=None, visible=None):
|
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
|
Changes some of the settings for the Status Bar Element. Must call `Window.Read` or `Window.Finalize` prior
|
||||||
|
|
||||||
:param value: (str) new text to show
|
:param value: (str) new text to show
|
||||||
:param background_color: (str) color of background
|
:param background_color: (str) color of background
|
||||||
:param text_color: (str) color of the text
|
:param text_color: (str) color of the text
|
||||||
|
@ -1871,7 +1872,9 @@ class TKProgressBar():
|
||||||
# Scroll bar will span the length of the frame #
|
# Scroll bar will span the length of the frame #
|
||||||
# ---------------------------------------------------------------------- #
|
# ---------------------------------------------------------------------- #
|
||||||
class TKOutput(tk.Frame):
|
class TKOutput(tk.Frame):
|
||||||
""" """
|
"""
|
||||||
|
tkinter style class. Inherits Frame class from tkinter. Adds a tk.Text and a scrollbar together
|
||||||
|
"""
|
||||||
def __init__(self, parent, width, height, bd, background_color=None, text_color=None, font=None, pad=None):
|
def __init__(self, parent, width, height, bd, background_color=None, text_color=None, font=None, pad=None):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -1938,25 +1941,24 @@ class TKOutput(tk.Frame):
|
||||||
# Routes stdout, stderr to a scrolled window #
|
# Routes stdout, stderr to a scrolled window #
|
||||||
# ---------------------------------------------------------------------- #
|
# ---------------------------------------------------------------------- #
|
||||||
class Output(Element):
|
class Output(Element):
|
||||||
""" """
|
"""
|
||||||
|
Output Element - a multi-lined text area where stdout and stderr are re-routed to.
|
||||||
|
"""
|
||||||
def __init__(self, size=(None, None), background_color=None, text_color=None, pad=None, font=None, tooltip=None,
|
def __init__(self, size=(None, None), background_color=None, text_color=None, pad=None, font=None, tooltip=None,
|
||||||
key=None, right_click_menu=None, visible=True):
|
key=None, right_click_menu=None, visible=True):
|
||||||
"""
|
"""
|
||||||
|
:param size: Tuple[(int), (int)] (w,h) w=characters-wide, h=rows-high
|
||||||
:param size: (w,h) w=characters-wide, h=rows-high
|
:param background_color: (str) color of background
|
||||||
:param background_color: color of background
|
:param text_color: (str) color of the text
|
||||||
:param text_color: color of the text
|
: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 pad: Amount of padding to put around element
|
:param font: Union[str, tuple] specifies the font family, size, etc
|
||||||
:param font: specifies the font family, size, etc
|
|
||||||
:param tooltip: (str) text, that will appear when mouse hovers over the element
|
:param tooltip: (str) text, that will appear when mouse hovers over the element
|
||||||
:param key: Used with window.FindElement and with return values to uniquely identify this element to uniquely identify this element
|
:param key: (Any) Used with window.FindElement and with return values to uniquely identify this element to uniquely identify this element
|
||||||
:param right_click_menu: List[List[str]] see "Right Click Menus" for format
|
:param right_click_menu: List[List[str]] see "Right Click Menus"
|
||||||
:param visible: set visibility state of the element (Default = True)
|
:param visible: (bool) set visibility state of the element
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._TKOut = None
|
self._TKOut = self.Widget = None # type: TKOutput
|
||||||
bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR
|
bg = background_color if background_color else DEFAULT_INPUT_ELEMENTS_COLOR
|
||||||
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
|
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
|
||||||
self.RightClickMenu = right_click_menu
|
self.RightClickMenu = right_click_menu
|
||||||
|
@ -1976,7 +1978,7 @@ class Output(Element):
|
||||||
"""
|
"""
|
||||||
Changes some of the settings for the Output Element. Must call `Window.Read` or `Window.Finalize` prior
|
Changes some of the settings for the Output Element. Must call `Window.Read` or `Window.Finalize` prior
|
||||||
|
|
||||||
:param value:
|
:param value: (str) string that will replace current contents of the output area
|
||||||
:param visible: (bool) control visibility of element
|
:param visible: (bool) control visibility of element
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -4809,19 +4811,27 @@ class Window:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def GetAContainerNumber(cls):
|
def GetAContainerNumber(cls):
|
||||||
""" """
|
"""
|
||||||
|
Not user callable!
|
||||||
|
:return: A simple counter that makes each container element unique
|
||||||
|
"""
|
||||||
cls.container_element_counter += 1
|
cls.container_element_counter += 1
|
||||||
return cls.container_element_counter
|
return cls.container_element_counter
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def IncrementOpenCount(self):
|
def IncrementOpenCount(self):
|
||||||
""" """
|
"""
|
||||||
|
Not user callable! Increments the number of open windows
|
||||||
|
Note - there is a bug where this count easily gets out of sync. Issue has been opened already. No ill effects
|
||||||
|
"""
|
||||||
self.NumOpenWindows += 1
|
self.NumOpenWindows += 1
|
||||||
# print('+++++ INCREMENTING Num Open Windows = {} ---'.format(Window.NumOpenWindows))
|
# print('+++++ INCREMENTING Num Open Windows = {} ---'.format(Window.NumOpenWindows))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def DecrementOpenCount(self):
|
def DecrementOpenCount(self):
|
||||||
""" """
|
"""
|
||||||
|
Not user callable! Decrements the number of open windows
|
||||||
|
"""
|
||||||
self.NumOpenWindows -= 1 * (self.NumOpenWindows != 0) # decrement if not 0
|
self.NumOpenWindows -= 1 * (self.NumOpenWindows != 0) # decrement if not 0
|
||||||
# print('----- DECREMENTING Num Open Windows = {} ---'.format(Window.NumOpenWindows))
|
# print('----- DECREMENTING Num Open Windows = {} ---'.format(Window.NumOpenWindows))
|
||||||
|
|
||||||
|
@ -4867,7 +4877,9 @@ class Window:
|
||||||
# ------------------------- Add Multiple Rows to Form ------------------------- #
|
# ------------------------- Add Multiple Rows to Form ------------------------- #
|
||||||
def AddRows(self, rows):
|
def AddRows(self, rows):
|
||||||
"""
|
"""
|
||||||
Loops through a list of lists of elements and adds each row, list, to the layout
|
Loops through a list of lists of elements and adds each row, list, to the layout.
|
||||||
|
This is NOT the best way to go about creating a window. Sending the entire layout at one time and passing
|
||||||
|
it as a parameter to the Window call is better.
|
||||||
|
|
||||||
:param rows: List[List[Elements]] A list of a list of elements
|
:param rows: List[List[Elements]] A list of a list of elements
|
||||||
|
|
||||||
|
@ -4878,22 +4890,24 @@ class Window:
|
||||||
def Layout(self, rows):
|
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
|
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
|
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
|
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.
|
from history and replace with sending as a parameter to Window.
|
||||||
|
|
||||||
:param rows: List[List[Elements]] Your entire layout
|
:param rows: List[List[Elements]] Your entire layout
|
||||||
|
:return: (Window} self so that you can chain method calls
|
||||||
"""
|
"""
|
||||||
self.AddRows(rows)
|
self.AddRows(rows)
|
||||||
self.BuildKeyDict()
|
self._BuildKeyDict()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def LayoutAndRead(self, rows, non_blocking=False):
|
def LayoutAndRead(self, rows, non_blocking=False):
|
||||||
"""
|
"""
|
||||||
Deprecated. Now you layout your window's rows (layout) and then separately call Read.
|
Deprecated!! Now your layout your window's rows (layout) and then separately call Read.
|
||||||
:param rows:
|
|
||||||
:param non_blocking: (Default = False)
|
|
||||||
|
|
||||||
|
:param rows: (List[List[Element]]) The layout of the window
|
||||||
|
:param non_blocking: (bool) if True the Read call will not block
|
||||||
"""
|
"""
|
||||||
raise DeprecationWarning(
|
raise DeprecationWarning(
|
||||||
'LayoutAndRead is no longer supported... change your call window.Layout(layout).Read()\nor window(title, layout).Read()')
|
'LayoutAndRead is no longer supported... change your call window.Layout(layout).Read()\nor window(title, layout).Read()')
|
||||||
|
@ -4913,9 +4927,10 @@ class Window:
|
||||||
def _Show(self, non_blocking=False):
|
def _Show(self, non_blocking=False):
|
||||||
"""
|
"""
|
||||||
NOT TO BE CALLED BY USERS. INTERNAL ONLY!
|
NOT TO BE CALLED BY USERS. INTERNAL ONLY!
|
||||||
It's this
|
It's this method that first shows the window to the user, collects results
|
||||||
|
|
||||||
:param non_blocking: (bool) if True, this is a non-blocking call
|
:param non_blocking: (bool) if True, this is a non-blocking call
|
||||||
|
:return: Tuple[Any, Dict] The event, values turple that is returned from Read calls
|
||||||
"""
|
"""
|
||||||
self.Shown = True
|
self.Shown = True
|
||||||
# Compute num rows & num cols (it'll come in handy debugging)
|
# Compute num rows & num cols (it'll come in handy debugging)
|
||||||
|
@ -4947,7 +4962,7 @@ class Window:
|
||||||
StartupTK(self)
|
StartupTK(self)
|
||||||
# If a button or keyboard event happened but no results have been built, build the results
|
# If a button or keyboard event happened but no results have been built, build the results
|
||||||
if self.LastKeyboardEvent is not None or self.LastButtonClicked is not None:
|
if self.LastKeyboardEvent is not None or self.LastButtonClicked is not None:
|
||||||
return BuildResults(self, False, self)
|
return _BuildResults(self, False, self)
|
||||||
return self.ReturnValues
|
return self.ReturnValues
|
||||||
|
|
||||||
# ------------------------- SetIcon - set the window's fav icon ------------------------- #
|
# ------------------------- SetIcon - set the window's fav icon ------------------------- #
|
||||||
|
@ -4960,7 +4975,6 @@ class Window:
|
||||||
|
|
||||||
:param icon: (str) Filename or bytes object
|
:param icon: (str) Filename or bytes object
|
||||||
:param pngbase64: (str) Base64 encoded GIF or PNG file
|
:param pngbase64: (str) Base64 encoded GIF or PNG file
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if type(icon) is bytes:
|
if type(icon) is bytes:
|
||||||
wicon = tkinter.PhotoImage(data=icon)
|
wicon = tkinter.PhotoImage(data=icon)
|
||||||
|
@ -4984,6 +4998,7 @@ class Window:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _GetElementAtLocation(self, location):
|
def _GetElementAtLocation(self, location):
|
||||||
"""
|
"""
|
||||||
Given a (row, col) location in a layout, return the element located at that position
|
Given a (row, col) location in a layout, return the element located at that position
|
||||||
|
@ -5010,7 +5025,6 @@ class Window:
|
||||||
"""
|
"""
|
||||||
Function that's called by tkinter when autoclode timer expires. Closes the window
|
Function that's called by tkinter when autoclode timer expires. Closes the window
|
||||||
|
|
||||||
:return: None
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
window = self
|
window = self
|
||||||
|
@ -5027,8 +5041,6 @@ class Window:
|
||||||
def _TimeoutAlarmCallback(self):
|
def _TimeoutAlarmCallback(self):
|
||||||
"""
|
"""
|
||||||
Read Timeout Alarm callback. Will kick a mainloop call out of the tkinter event loop and cause it to return
|
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
|
# first, get the results table built
|
||||||
# modify the Results table in the parent FlexForm object
|
# modify the Results table in the parent FlexForm object
|
||||||
|
@ -5040,7 +5052,9 @@ class Window:
|
||||||
self.FormRemainedOpen = True
|
self.FormRemainedOpen = True
|
||||||
self.TKroot.quit() # kick the users out of the mainloop
|
self.TKroot.quit() # kick the users out of the mainloop
|
||||||
|
|
||||||
|
|
||||||
def Read(self, timeout=None, timeout_key=TIMEOUT_KEY):
|
def Read(self, timeout=None, timeout_key=TIMEOUT_KEY):
|
||||||
|
# type: (int, Any) -> Tuple[Any, Union[Dict, List]]
|
||||||
"""
|
"""
|
||||||
THE biggest deal method in the Window class! This is how you get all of your data from your Window.
|
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
|
Pass in a timeout (in milliseconds) to wait for a maximum of timeout milliseconds. Will return timeout_key
|
||||||
|
@ -5074,7 +5088,7 @@ class Window:
|
||||||
# if already have a button waiting, the return previously built results
|
# if already have a button waiting, the return previously built results
|
||||||
if self.LastButtonClicked is not None and not self.LastButtonClickedWasRealtime:
|
if self.LastButtonClicked is not None and not self.LastButtonClickedWasRealtime:
|
||||||
# print(f'*** Found previous clicked saved {self.LastButtonClicked}')
|
# print(f'*** Found previous clicked saved {self.LastButtonClicked}')
|
||||||
results = BuildResults(self, False, self)
|
results = _BuildResults(self, False, self)
|
||||||
self.LastButtonClicked = None
|
self.LastButtonClicked = None
|
||||||
return results
|
return results
|
||||||
InitializeResults(self)
|
InitializeResults(self)
|
||||||
|
@ -5091,7 +5105,7 @@ class Window:
|
||||||
Window.DecrementOpenCount()
|
Window.DecrementOpenCount()
|
||||||
# _my_windows.Decrement()
|
# _my_windows.Decrement()
|
||||||
# print('ROOT Destroyed')
|
# print('ROOT Destroyed')
|
||||||
results = BuildResults(self, False, self)
|
results = _BuildResults(self, False, self)
|
||||||
if results[0] != None and results[0] != timeout_key:
|
if results[0] != None and results[0] != timeout_key:
|
||||||
return results
|
return results
|
||||||
else:
|
else:
|
||||||
|
@ -5145,7 +5159,7 @@ class Window:
|
||||||
# _my_windows.Decrement()
|
# _my_windows.Decrement()
|
||||||
# Determine return values
|
# Determine return values
|
||||||
if self.LastKeyboardEvent is not None or self.LastButtonClicked is not None:
|
if self.LastKeyboardEvent is not None or self.LastButtonClicked is not None:
|
||||||
results = BuildResults(self, False, self)
|
results = _BuildResults(self, False, self)
|
||||||
if not self.LastButtonClickedWasRealtime:
|
if not self.LastButtonClickedWasRealtime:
|
||||||
self.LastButtonClicked = None
|
self.LastButtonClicked = None
|
||||||
return results
|
return results
|
||||||
|
@ -5159,9 +5173,10 @@ class Window:
|
||||||
self.ReturnValues = self.TimeoutKey, self.ReturnValues[1] # fake a timeout
|
self.ReturnValues = self.TimeoutKey, self.ReturnValues[1] # fake a timeout
|
||||||
return self.ReturnValues
|
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
|
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)
|
: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
|
(event or timeout_key or None, Dictionary of values or List of values from all elements in the Window
|
||||||
|
@ -5192,7 +5207,8 @@ class Window:
|
||||||
self.Values = None
|
self.Values = None
|
||||||
self.LastButtonClicked = None
|
self.LastButtonClicked = None
|
||||||
return None, None
|
return None, None
|
||||||
return BuildResults(self, False, self)
|
return _BuildResults(self, False, self)
|
||||||
|
|
||||||
|
|
||||||
def Finalize(self):
|
def Finalize(self):
|
||||||
"""
|
"""
|
||||||
|
@ -5223,8 +5239,7 @@ class Window:
|
||||||
Use this call when you want something to appear in your Window immediately (as soon as this function is called).
|
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
|
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)
|
:return: (Window) `self` so that method calls can be easily "chained"
|
||||||
(event or timeout_key or None, Dictionary of values or List of values from all elements in the Window
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.TKrootDestroyed:
|
if self.TKrootDestroyed:
|
||||||
|
@ -5235,23 +5250,34 @@ class Window:
|
||||||
pass
|
pass
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def Fill(self, values_dict):
|
def Fill(self, values_dict):
|
||||||
"""
|
"""
|
||||||
|
Fill in elements that are input fields with data based on a 'values dictionary'
|
||||||
|
|
||||||
:param values_dict: ?????????????????
|
:param values_dict: (Dict[Any:Any]) {Element key : value} pairs
|
||||||
|
:return: (Window) returns self so can be chained with other methods
|
||||||
"""
|
"""
|
||||||
|
|
||||||
FillFormWithValues(self, values_dict)
|
FillFormWithValues(self, values_dict)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def FindElement(self, key, silent_on_error=False):
|
def FindElement(self, key, silent_on_error=False):
|
||||||
"""
|
"""
|
||||||
Find element object associated with the provided key
|
Find element object associated with the provided key. This call can be abbreviated to any of these:
|
||||||
:returns Found element object, an Error Element, or None
|
FindElement == Element == Find
|
||||||
|
So take your pick as to how much typing you want to do.
|
||||||
|
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.FindElement and with return values to uniquely identify this element
|
:param key: (Any) Used with window.FindElement and with return values to uniquely identify this element
|
||||||
:param silent_on_error: (Default = False)
|
:param silent_on_error: (bool) If True do not display popup nor print warning of key errors
|
||||||
|
|
||||||
|
:return: Union[Element, Error Element, None] 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
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
element = self.AllKeysDict[key]
|
element = self.AllKeysDict[key]
|
||||||
|
@ -5270,24 +5296,33 @@ class Window:
|
||||||
Element = FindElement # Shortcut function
|
Element = FindElement # Shortcut function
|
||||||
Find = FindElement
|
Find = FindElement
|
||||||
|
|
||||||
|
|
||||||
def FindElementWithFocus(self):
|
def FindElementWithFocus(self):
|
||||||
""" """
|
"""
|
||||||
|
Returns the Element that currently has focus as reported by tkinter. If no element is found None is returned!
|
||||||
|
:return: Union[Element, None] An Element if one has been found with focus or None if no element found
|
||||||
|
"""
|
||||||
element = _FindElementWithFocusInSubForm(self)
|
element = _FindElementWithFocusInSubForm(self)
|
||||||
return element
|
return element
|
||||||
|
|
||||||
def BuildKeyDict(self):
|
def _BuildKeyDict(self):
|
||||||
""" """
|
"""
|
||||||
|
Used internally only! Not user callable
|
||||||
|
Builds a dictionary containing all elements with keys for this window.
|
||||||
|
"""
|
||||||
dict = {}
|
dict = {}
|
||||||
self.AllKeysDict = self._BuildKeyDictForWindow(self, self, dict)
|
self.AllKeysDict = self._BuildKeyDictForWindow(self, self, dict)
|
||||||
# print(f'keys built = {self.AllKeysDict}')
|
# print(f'keys built = {self.AllKeysDict}')
|
||||||
|
|
||||||
def _BuildKeyDictForWindow(self, top_window, window, key_dict):
|
def _BuildKeyDictForWindow(self, top_window, window, key_dict):
|
||||||
"""
|
"""
|
||||||
|
Loop through all Rows and all Container Elements for this window and create the keys for all of them.
|
||||||
|
Note that the calls are recursive as all pathes must be walked
|
||||||
|
|
||||||
:param top_window:
|
:param top_window: (Window) The highest level of the window
|
||||||
:param window:
|
:param window: Union[Column, Frame, TabGroup, Pane, Tab] The "sub-window" (container element) to be searched
|
||||||
:param key_dict:
|
: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 row_num, row in enumerate(window.Rows):
|
||||||
for col_num, element in enumerate(row):
|
for col_num, element in enumerate(row):
|
||||||
|
@ -5324,12 +5359,13 @@ class Window:
|
||||||
|
|
||||||
def SaveToDisk(self, filename):
|
def SaveToDisk(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
|
||||||
:param filename: ?????????????????
|
:param filename: ?????????????????
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
results = BuildResults(self, False, self)
|
results = _BuildResults(self, False, self)
|
||||||
with open(filename, 'wb') as sf:
|
with open(filename, 'wb') as sf:
|
||||||
pickle.dump(results[1], sf)
|
pickle.dump(results[1], sf)
|
||||||
except:
|
except:
|
||||||
|
@ -5442,7 +5478,7 @@ class Window:
|
||||||
else:
|
else:
|
||||||
self.LastKeyboardEvent = str(event.keysym) + ':' + str(event.keycode)
|
self.LastKeyboardEvent = str(event.keysym) + ':' + str(event.keycode)
|
||||||
if not self.NonBlocking:
|
if not self.NonBlocking:
|
||||||
BuildResults(self, False, self)
|
_BuildResults(self, False, self)
|
||||||
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
||||||
self.TKroot.quit()
|
self.TKroot.quit()
|
||||||
|
|
||||||
|
@ -5456,7 +5492,7 @@ class Window:
|
||||||
self.FormRemainedOpen = True
|
self.FormRemainedOpen = True
|
||||||
self.LastKeyboardEvent = 'MouseWheel:Down' if event.delta < 0 else 'MouseWheel:Up'
|
self.LastKeyboardEvent = 'MouseWheel:Down' if event.delta < 0 else 'MouseWheel:Up'
|
||||||
if not self.NonBlocking:
|
if not self.NonBlocking:
|
||||||
BuildResults(self, False, self)
|
_BuildResults(self, False, self)
|
||||||
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
if self.CurrentlyRunningMainloop: # quit if this is the current mainloop, otherwise don't quit!
|
||||||
self.TKroot.quit()
|
self.TKroot.quit()
|
||||||
|
|
||||||
|
@ -5467,7 +5503,7 @@ class Window:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if not self.NonBlocking:
|
if not self.NonBlocking:
|
||||||
BuildResults(self, False, self)
|
_BuildResults(self, False, self)
|
||||||
if self.TKrootDestroyed:
|
if self.TKrootDestroyed:
|
||||||
return None
|
return None
|
||||||
self.TKrootDestroyed = True
|
self.TKrootDestroyed = True
|
||||||
|
@ -6395,7 +6431,7 @@ def InitializeResults(form):
|
||||||
:param form:
|
:param form:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
BuildResults(form, True, form)
|
_BuildResults(form, True, form)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -6428,7 +6464,7 @@ def EncodeRadioRowCol(container, row, col):
|
||||||
# ------- FUNCTION BuildResults. Form exiting so build the results to pass back ------- #
|
# ------- FUNCTION BuildResults. Form exiting so build the results to pass back ------- #
|
||||||
# format of return values is
|
# format of return values is
|
||||||
# (Button Pressed, input_values)
|
# (Button Pressed, input_values)
|
||||||
def BuildResults(form, initialize_only, top_level_form):
|
def _BuildResults(form, initialize_only, top_level_form):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param form:
|
:param form:
|
||||||
|
@ -6445,13 +6481,13 @@ def BuildResults(form, initialize_only, top_level_form):
|
||||||
form.DictionaryKeyCounter = 0
|
form.DictionaryKeyCounter = 0
|
||||||
form.ReturnValuesDictionary = {}
|
form.ReturnValuesDictionary = {}
|
||||||
form.ReturnValuesList = []
|
form.ReturnValuesList = []
|
||||||
BuildResultsForSubform(form, initialize_only, top_level_form)
|
_BuildResultsForSubform(form, initialize_only, top_level_form)
|
||||||
if not top_level_form.LastButtonClickedWasRealtime:
|
if not top_level_form.LastButtonClickedWasRealtime:
|
||||||
top_level_form.LastButtonClicked = None
|
top_level_form.LastButtonClicked = None
|
||||||
return form.ReturnValues
|
return form.ReturnValues
|
||||||
|
|
||||||
|
|
||||||
def BuildResultsForSubform(form, initialize_only, top_level_form):
|
def _BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param form:
|
:param form:
|
||||||
|
@ -6469,7 +6505,7 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
element.ReturnValuesList = []
|
element.ReturnValuesList = []
|
||||||
element.ReturnValuesDictionary = {}
|
element.ReturnValuesDictionary = {}
|
||||||
BuildResultsForSubform(element, initialize_only, top_level_form)
|
_BuildResultsForSubform(element, initialize_only, top_level_form)
|
||||||
for item in element.ReturnValuesList:
|
for item in element.ReturnValuesList:
|
||||||
AddToReturnList(top_level_form, item)
|
AddToReturnList(top_level_form, item)
|
||||||
if element.UseDictionary:
|
if element.UseDictionary:
|
||||||
|
@ -6481,7 +6517,7 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
element.ReturnValuesList = []
|
element.ReturnValuesList = []
|
||||||
element.ReturnValuesDictionary = {}
|
element.ReturnValuesDictionary = {}
|
||||||
BuildResultsForSubform(element, initialize_only, top_level_form)
|
_BuildResultsForSubform(element, initialize_only, top_level_form)
|
||||||
for item in element.ReturnValuesList:
|
for item in element.ReturnValuesList:
|
||||||
AddToReturnList(top_level_form, item)
|
AddToReturnList(top_level_form, item)
|
||||||
if element.UseDictionary:
|
if element.UseDictionary:
|
||||||
|
@ -6493,7 +6529,7 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
element.ReturnValuesList = []
|
element.ReturnValuesList = []
|
||||||
element.ReturnValuesDictionary = {}
|
element.ReturnValuesDictionary = {}
|
||||||
BuildResultsForSubform(element, initialize_only, top_level_form)
|
_BuildResultsForSubform(element, initialize_only, top_level_form)
|
||||||
for item in element.ReturnValuesList:
|
for item in element.ReturnValuesList:
|
||||||
AddToReturnList(top_level_form, item)
|
AddToReturnList(top_level_form, item)
|
||||||
if element.UseDictionary:
|
if element.UseDictionary:
|
||||||
|
@ -6505,7 +6541,7 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
element.ReturnValuesList = []
|
element.ReturnValuesList = []
|
||||||
element.ReturnValuesDictionary = {}
|
element.ReturnValuesDictionary = {}
|
||||||
BuildResultsForSubform(element, initialize_only, top_level_form)
|
_BuildResultsForSubform(element, initialize_only, top_level_form)
|
||||||
for item in element.ReturnValuesList:
|
for item in element.ReturnValuesList:
|
||||||
AddToReturnList(top_level_form, item)
|
AddToReturnList(top_level_form, item)
|
||||||
if element.UseDictionary:
|
if element.UseDictionary:
|
||||||
|
@ -6517,7 +6553,7 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
element.DictionaryKeyCounter = top_level_form.DictionaryKeyCounter
|
||||||
element.ReturnValuesList = []
|
element.ReturnValuesList = []
|
||||||
element.ReturnValuesDictionary = {}
|
element.ReturnValuesDictionary = {}
|
||||||
BuildResultsForSubform(element, initialize_only, top_level_form)
|
_BuildResultsForSubform(element, initialize_only, top_level_form)
|
||||||
for item in element.ReturnValuesList:
|
for item in element.ReturnValuesList:
|
||||||
AddToReturnList(top_level_form, item)
|
AddToReturnList(top_level_form, item)
|
||||||
if element.UseDictionary:
|
if element.UseDictionary:
|
||||||
|
@ -6670,99 +6706,27 @@ def BuildResultsForSubform(form, initialize_only, top_level_form):
|
||||||
return form.ReturnValues
|
return form.ReturnValues
|
||||||
|
|
||||||
|
|
||||||
def FillFormWithValues(form, values_dict):
|
def FillFormWithValues(window, values_dict):
|
||||||
|
"""
|
||||||
|
Fills a window with values provided in a values dictionary { element_key : new_value }
|
||||||
|
|
||||||
|
:param window: (Window) The window object to fill
|
||||||
|
:param values_dict: (Dict[Any:Any]) A dictionary with element keys as key and value is values parm for Update call
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param form:
|
for element_key in values_dict:
|
||||||
:param values_dict:
|
try:
|
||||||
|
window.AllKeysDict[element_key].Update(values_dict[element_key])
|
||||||
"""
|
except Exception as e:
|
||||||
FillSubformWithValues(form, values_dict)
|
print('Problem filling form. Perhaps bad key? This is a suspected bad key: {}'.format(element_key))
|
||||||
|
|
||||||
|
|
||||||
def FillSubformWithValues(form, values_dict):
|
|
||||||
"""
|
|
||||||
|
|
||||||
:param form:
|
|
||||||
:param values_dict:
|
|
||||||
|
|
||||||
"""
|
|
||||||
for row_num, row in enumerate(form.Rows):
|
|
||||||
for col_num, element in enumerate(row):
|
|
||||||
value = None
|
|
||||||
if element.Type == ELEM_TYPE_COLUMN:
|
|
||||||
FillSubformWithValues(element, values_dict)
|
|
||||||
if element.Type == ELEM_TYPE_FRAME:
|
|
||||||
FillSubformWithValues(element, values_dict)
|
|
||||||
if element.Type == ELEM_TYPE_TAB_GROUP:
|
|
||||||
FillSubformWithValues(element, values_dict)
|
|
||||||
if element.Type == ELEM_TYPE_TAB:
|
|
||||||
FillSubformWithValues(element, values_dict)
|
|
||||||
try:
|
|
||||||
value = values_dict[element.Key]
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
if element.Type == ELEM_TYPE_INPUT_TEXT:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_CHECKBOX:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_RADIO:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_COMBO:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_OPTION_MENU:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_LISTBOX:
|
|
||||||
element.SetValue(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_SLIDER:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_MULTILINE:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_INPUT_SPIN:
|
|
||||||
element.Update(value)
|
|
||||||
elif element.Type == ELEM_TYPE_BUTTON:
|
|
||||||
element.Update(value)
|
|
||||||
|
|
||||||
|
|
||||||
def _FindElementFromKeyInSubForm(form, key):
|
|
||||||
"""
|
|
||||||
|
|
||||||
:param form:
|
|
||||||
:param key: Used with window.FindElement and with return values to uniquely identify this element
|
|
||||||
|
|
||||||
"""
|
|
||||||
for row_num, row in enumerate(form.Rows):
|
|
||||||
for col_num, element in enumerate(row):
|
|
||||||
if element.Type == ELEM_TYPE_COLUMN:
|
|
||||||
matching_elem = _FindElementFromKeyInSubForm(element, key)
|
|
||||||
if matching_elem is not None:
|
|
||||||
return matching_elem
|
|
||||||
if element.Type == ELEM_TYPE_FRAME:
|
|
||||||
matching_elem = _FindElementFromKeyInSubForm(element, key)
|
|
||||||
if matching_elem is not None:
|
|
||||||
return matching_elem
|
|
||||||
if element.Type == ELEM_TYPE_TAB_GROUP:
|
|
||||||
matching_elem = _FindElementFromKeyInSubForm(element, key)
|
|
||||||
if matching_elem is not None:
|
|
||||||
return matching_elem
|
|
||||||
if element.Type == ELEM_TYPE_PANE:
|
|
||||||
matching_elem = _FindElementFromKeyInSubForm(element, key)
|
|
||||||
if matching_elem is not None:
|
|
||||||
return matching_elem
|
|
||||||
if element.Type == ELEM_TYPE_TAB:
|
|
||||||
matching_elem = _FindElementFromKeyInSubForm(element, key)
|
|
||||||
if matching_elem is not None:
|
|
||||||
return matching_elem
|
|
||||||
if element.Key == key:
|
|
||||||
return element
|
|
||||||
|
|
||||||
|
|
||||||
def _FindElementWithFocusInSubForm(form):
|
def _FindElementWithFocusInSubForm(form):
|
||||||
# type: (...) -> Element or None
|
|
||||||
"""
|
"""
|
||||||
Searches through a "sub-form" (can be a window or container) for the current element with focus
|
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)
|
|
||||||
|
|
||||||
|
:param form: a Window, Column, Frame, or TabGroup (container elements)
|
||||||
|
:return: Union[Element, None]
|
||||||
"""
|
"""
|
||||||
for row_num, row in enumerate(form.Rows):
|
for row_num, row in enumerate(form.Rows):
|
||||||
for col_num, element in enumerate(row):
|
for col_num, element in enumerate(row):
|
||||||
|
@ -6799,7 +6763,7 @@ def _FindElementWithFocusInSubForm(form):
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False):
|
def AddMenuItem(top_menu, sub_menu_info, element, is_sub_menu=False, skip=False):
|
||||||
"""
|
"""
|
||||||
|
Only to be used internally. Not user callable
|
||||||
:param top_menu:
|
:param top_menu:
|
||||||
:param sub_menu_info:
|
:param sub_menu_info:
|
||||||
:param element:
|
:param element:
|
||||||
|
@ -10736,7 +10700,7 @@ def main():
|
||||||
frame2 = [
|
frame2 = [
|
||||||
[Listbox(['Listbox 1', 'Listbox 2', 'Listbox 3'], select_mode=SELECT_MODE_EXTENDED, size=(20, 5))],
|
[Listbox(['Listbox 1', 'Listbox 2', 'Listbox 3'], select_mode=SELECT_MODE_EXTENDED, size=(20, 5))],
|
||||||
[Combo(['Combo item 1',2,3,4 ], size=(20, 3),readonly=True, text_color='red', background_color='red', key='_COMBO1_')],
|
[Combo(['Combo item 1',2,3,4 ], size=(20, 3),readonly=True, text_color='red', background_color='red', key='_COMBO1_')],
|
||||||
[Combo(['Combo item 1', 2,3,4], size=(20, 3), readonly=False, text_color='red', background_color='red', key='_COMBO2_')],
|
# [Combo(['Combo item 1', 2,3,4], size=(20, 3), readonly=False, text_color='red', background_color='red', key='_COMBO2_')],
|
||||||
[Spin([1, 2, 3, 'a','b','c'], size=(4, 3))],
|
[Spin([1, 2, 3, 'a','b','c'], size=(4, 3))],
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -10767,8 +10731,8 @@ def main():
|
||||||
[graph_elem],
|
[graph_elem],
|
||||||
]
|
]
|
||||||
|
|
||||||
tab1 = Tab('Graph Number 1', frame6, tooltip='tab 1')
|
tab1 = Tab('Graph Number 1', frame6, tooltip='tab 1', )
|
||||||
tab2 = Tab('Graph Number 2', [[]])
|
tab2 = Tab('Graph Number 2', [[]],)
|
||||||
|
|
||||||
layout1 = [
|
layout1 = [
|
||||||
[Image(data=DEFAULT_BASE64_ICON)],
|
[Image(data=DEFAULT_BASE64_ICON)],
|
||||||
|
@ -10783,7 +10747,7 @@ def main():
|
||||||
Frame('Variable Choice Group', frame4, title_color='blue')],
|
Frame('Variable Choice Group', frame4, title_color='blue')],
|
||||||
[Frame('Structured Data Group', frame5, title_color='red'), ],
|
[Frame('Structured Data Group', frame5, title_color='red'), ],
|
||||||
# [Frame('Graphing Group', frame6)],
|
# [Frame('Graphing Group', frame6)],
|
||||||
[TabGroup([[tab1, tab2]])],
|
[TabGroup([[tab1, tab2]], )],
|
||||||
[ProgressBar(max_value=800, size=(60, 25), key='+PROGRESS+'), Button('Button'), B('Normal'),
|
[ProgressBar(max_value=800, size=(60, 25), key='+PROGRESS+'), Button('Button'), B('Normal'),
|
||||||
Button('Exit', tooltip='Exit button')],
|
Button('Exit', tooltip='Exit button')],
|
||||||
]
|
]
|
||||||
|
@ -10796,6 +10760,7 @@ def main():
|
||||||
right_click_menu=['&Right', ['Right', '!&Click', '&Menu', 'E&xit', 'Properties']],
|
right_click_menu=['&Right', ['Right', '!&Click', '&Menu', 'E&xit', 'Properties']],
|
||||||
# transparent_color= '#9FB8AD',
|
# transparent_color= '#9FB8AD',
|
||||||
resizable=True,
|
resizable=True,
|
||||||
|
debugger_enabled=False,
|
||||||
# icon=r'X:\VMWare Virtual Machines\SHARED FOLDER\kingb.ico'
|
# icon=r'X:\VMWare Virtual Machines\SHARED FOLDER\kingb.ico'
|
||||||
).Finalize()
|
).Finalize()
|
||||||
graph_elem.DrawCircle((200, 200), 50, 'blue')
|
graph_elem.DrawCircle((200, 200), 50, 'blue')
|
||||||
|
|
Loading…
Reference in New Issue