From fdbd8d700a6e3fa6f762a8046f639c634b35fb10 Mon Sep 17 00:00:00 2001 From: PySimpleGUI Date: Sat, 6 Jun 2020 16:46:09 -0400 Subject: [PATCH] Release 4.20.0 --- PySimpleGUI.py | 8 +- docs/call reference.md | 1200 +++++++++++++++++++++++++++++++++++++++- docs/cookbook.md | 12 +- docs/index.md | 56 +- readme.md | 56 +- 5 files changed, 1290 insertions(+), 42 deletions(-) diff --git a/PySimpleGUI.py b/PySimpleGUI.py index 3ad8a73b..0cd3e662 100644 --- a/PySimpleGUI.py +++ b/PySimpleGUI.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -version = __version__ = "4.19.0.12 Unreleased \n - Window.set_title added, removed resetting stdout when flush happens, fixed MenuBar tearoff not working, fixed get folder for Macs, fixed multiline color problem, option to set tooltip font, make typing module import optional, docstring, combobox drop-down portion font change, ability to have multiple progress bar themes at one time, setting radio button to False will clear entire group, added changing title to Tab update, ButtonMenu - font for menu set to same as button, fix for Menu.update losing font setting, display detailed tkinter version, fix table/tree padding" +version = __version__ = "4.20.0 Released 6-Jun-2020" port = 'PySimpleGUI' @@ -13516,7 +13516,6 @@ def Popup(*args, title=None, button_color=None, background_color=None, text_colo message = str(message) if message.count('\n'): message_wrapped = message - # message_wrapped = textwrap.fill(message, local_line_width) else: message_wrapped = textwrap.fill(message, local_line_width) message_wrapped_lines = message_wrapped.count('\n') + 1 @@ -15622,10 +15621,7 @@ def main(): # theme('dark brown 2') # theme('dark red') # theme('Light Green 6') - try: - ver = version[:version.index('\n')] - except: - ver = version + ver = version.split('\n')[0] tkversion = tkinter.TkVersion tclversion = tkinter.TclVersion diff --git a/docs/call reference.md b/docs/call reference.md index 4bb606f3..ccd201d1 100644 --- a/docs/call reference.md +++ b/docs/call reference.md @@ -6103,13 +6103,16 @@ Parameter Descriptions: Changes some of the settings for the Tab Element. Must call `Window.Read` or `Window.Finalize` prior ``` -Update(disabled=None, visible=None) +Update(title=None, + disabled=None, + visible=None) ``` Parameter Descriptions: |Type|Name|Meaning| |--|--|--| +| str | title | tab title | | bool | disabled | disable or enable state of the element | | bool | visible | control visibility of element | @@ -6254,13 +6257,16 @@ unhide_row() Changes some of the settings for the Tab Element. Must call `Window.Read` or `Window.Finalize` prior ``` -update(disabled=None, visible=None) +update(title=None, + disabled=None, + visible=None) ``` Parameter Descriptions: |Type|Name|Meaning| |--|--|--| +| str | title | tab title | | bool | disabled | disable or enable state of the element | | bool | visible | control visibility of element | @@ -8637,6 +8643,1194 @@ Parameter Descriptions: | str | icon | Filename or bytes object | | str | pngbase64 | Base64 encoded image | +### set_title + +Change the title of the window + +``` +set_title(title) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | title | The string to set the title to | + +### set_transparent_color + +Set the color that will be transparent in your window. Areas with this color will be SEE THROUGH. + +``` +set_transparent_color(color) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | color | Color string that defines the transparent color | + +### size + +#### property: size + +Return the current size of the window in pixels + +|Type|Name|Meaning| +|---|---|---| +|| **return** | (width, height) of the window | + +### un_hide + +Used to bring back a window that was previously hidden using the Hide method + +```python +un_hide() +``` + +### visibility_changed + +This is a completely dummy method that does nothing. It is here so that PySimpleGUIQt programs can make this +call and then have that same source run on plain PySimpleGUI. + +`visibility_changed()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | | + +## Window + + Represents a single Window + +``` +Window(title, + layout=None, + default_element_size=(45, 1), + default_button_element_size=(None, None), + auto_size_text=None, + auto_size_buttons=None, + location=(None, None), + size=(None, None), + element_padding=None, + margins=(None, None), + button_color=None, + font=None, + progress_bar_color=(None, None), + background_color=None, + border_depth=None, + auto_close=False, + auto_close_duration=3, + icon=None, + force_toplevel=False, + 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, + finalize=False, + element_justification="left", + ttk_theme=None, + use_ttk_buttons=None, + metadata=None) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | title | The title that will be displayed in the Titlebar and on the Taskbar | +| List[List[Elements]] | layout | The layout for the window. Can also be specified in the Layout method | +| Tuple[int, int] | default_element_size | (width, height) size in characters (wide) and rows (high) for all elements in this window | +| Tuple[int, int] | default_button_element_size | (width, height) size in characters (wide) and rows (high) for all Button elements in this window | +| bool | auto_size_text | True if Elements in Window should be sized to exactly fir the length of text | +| bool | auto_size_buttons | True if Buttons in this Window should be sized to exactly fit the text on this. | +| Tuple[int, int] | location | (x,y) location, in pixels, to locate the upper left corner of the window on the screen. Default is to center on screen. | +| Tuple[int, int] | 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 | +| Tuple[int, int] or ((int, int),(int,int)) | element_padding | Default amount of padding to put around elements in window (left/right, top/bottom) or ((left, right), (top, bottom)) | +| Tuple[int, int] | margins | (left/right, top/bottom) Amount of pixels to leave inside the window's frame around the edges before your elements are shown. | +| Tuple[str, str] | button_color | (text color, button color) Default button colors for all buttons in the window | +| Union[str, Tuple[str, int]] | font | specifies the font family, size, etc | +| Tuple[str, str] | progress_bar_color | (bar color, background color) Sets the default colors for all progress bars in the window | +| str | background_color | color of background | +| int | border_depth | Default border depth (width) for all elements in the window | +| bool | auto_close | If True, the window will automatically close itself | +| int | auto_close_duration | Number of seconds to wait before closing the window | +| Union[str, str] | icon | Can be either a filename or Base64 value. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO | +| bool | force_toplevel | If True will cause this window to skip the normal use of a hidden master window | +| float | 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. | +| bool | return_keyboard_events | if True key presses on the keyboard will be returned as Events from Read calls | +| bool | use_default_focus | If True will use the default focus algorithm to set the focus to the "Correct" element | +| str | text_justification | Union ['left', 'right', 'center'] Default text justification for all Text Elements in window | +| bool | 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 | +| bool | 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 | +| bool | 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 | +| bool | resizable | If True, allows the user to resize the window. Note the not all Elements will change size or location when resizing. | +| bool | 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 | +| bool | disable_minimize | if True the user won't be able to minimize window. Good for taking over entire screen and staying that way. | +| List[List[Union[List[str],str]]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. | +| str | 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. | +| bool | debugger_enabled | If True then the internal debugger will be enabled | +| bool | finalize | If True then the Finalize method will be called. Use this rather than chaining .Finalize for cleaner code | +| str | element_justification | All elements in the Window itself will have this justification 'left', 'right', 'center' are valid values | +| str | ttk_theme | Set the tkinter ttk "theme" of the window. Default = DEFAULT_TTK_THEME. Sets all ttk widgets to this theme as their default | +| bool | 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 | +| Any | metadata | User metadata that can be set to ANYTHING | + +### AddRow + +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) + +``` +AddRow(args=*<1 or N object>) +``` + +### AddRows + +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. + +``` +AddRows(rows) +``` + +### AlphaChannel + +#### property: AlphaChannel + +A property that changes the current alpha channel value (internal value) + +|Type|Name|Meaning| +|---|---|---| +|| **return** | (float) the current alpha channel setting according to self, not read directly from tkinter | + +### BringToFront + +Brings this window to the top of all other windows (perhaps may not be brought before a window made to "stay + on top") + +```python +BringToFront() +``` + +### Close + +Closes window. Users can safely call even if window has been destroyed. Should always call when done with + a window so that resources are properly freed up within your thread. + +```python +Close() +``` + +### CurrentLocation + +Get the current location of the window's top left corner + +`CurrentLocation()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | The x and y location in tuple form (x,y) | + +### Disable + +Disables window from taking any input from the user + +```python +Disable() +``` + +### DisableDebugger + +Disable the internal debugger. By default the debugger is ENABLED + +```python +DisableDebugger() +``` + +### Disappear + +Causes a window to "disappear" from the screen, but remain on the taskbar. It does this by turning the alpha + channel to 0. NOTE that on some platforms alpha is not supported. The window will remain showing on these + platforms. The Raspberry Pi for example does not have an alpha setting + +```python +Disappear() +``` + +### Elem + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +Elem(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### Element + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +Element(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### Enable + +Re-enables window to take user input after having it be Disabled previously + +```python +Enable() +``` + +### EnableDebugger + +Enables the internal debugger. By default, the debugger IS enabled + +```python +EnableDebugger() +``` + +### Fill + +Fill in elements that are input fields with data based on a 'values dictionary' + +``` +Fill(values_dict) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| (Dict[Any:Any]) | values_dict | {Element key : value} pairs | +| (Window) | **RETURN** | returns self so can be chained with other methods + +### Finalize + +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! + +`Finalize()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | Returns 'self' so that method "Chaining" can happen (read up about it as it's very cool!) | + +### Find + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +Find(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### FindElement + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +FindElement(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### FindElementWithFocus + +Returns the Element that currently has focus as reported by tkinter. If no element is found None is returned! + +`FindElementWithFocus()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | An Element if one has been found with focus or None if no element found | + +### GetScreenDimensions + +Get the screen dimensions. NOTE - you must have a window already open for this to work (blame tkinter not me) + +`GetScreenDimensions()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | Tuple containing width and height of screen in pixels | + +### GrabAnyWhereOff + +Turns off Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet + been Finalized or Read. + +```python +GrabAnyWhereOff() +``` + +### GrabAnyWhereOn + +Turns on Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet + been Finalized or Read. + +```python +GrabAnyWhereOn() +``` + +### Hide + +Hides the window from the screen and the task bar + +```python +Hide() +``` + +### Layout + +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. + +``` +Layout(rows) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| List[List[Elements]] | rows | Your entire layout | +| (Window) | **RETURN** | self so that you can chain method calls + +### LoadFromDisk + +Restore values from a previous call to SaveToDisk which saves the returned values dictionary in Pickle format + +``` +LoadFromDisk(filename) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | filename | Pickle Filename to load | + +### Maximize + +Maximize the window. This is done differently on a windows system versus a linux or mac one. For non-Windows + the root attribute '-fullscreen' is set to True. For Windows the "root" state is changed to "zoomed" + The reason for the difference is the title bar is removed in some cases when using fullscreen option + +```python +Maximize() +``` + +### Minimize + +Minimize this window to the task bar + +```python +Minimize() +``` + +### Move + +Move the upper left corner of this window to the x,y coordinates provided + +``` +Move(x, y) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| int | x | x coordinate in pixels | +| int | y | y coordinate in pixels | + +### Normal + +Restore a window to a non-maximized state. Does different things depending on platform. See Maximize for more. + +```python +Normal() +``` + +### Read + +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. + +``` +Read(timeout=None, + timeout_key="__TIMEOUT__", + close=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| int | timeout | Milliseconds to wait until the Read will return IF no other GUI events happen first | +| Any | timeout_key | The value that will be returned from the call if the timer expired | +| bool | close | if True the window will be closed prior to returning | +| Tuple[(Any), Union[Dict[Any:Any]], List[Any], None] | **RETURN** | (event, values) + +### Reappear + +Causes a window previously made to "Disappear" (using that method). Does this by restoring the alpha channel + +```python +Reappear() +``` + +### Refresh + +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 + +`Refresh()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | `self` so that method calls can be easily "chained" | + +### SaveToDisk + +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. + +``` +SaveToDisk(filename) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | filename | Filename to save the values to in pickled form | + +### SendToBack + +Pushes this window to the bottom of the stack of windows. It is the opposite of BringToFront + +```python +SendToBack() +``` + +### SetAlpha + +Sets the Alpha Channel for a window. Values are between 0 and 1 where 0 is completely transparent + +``` +SetAlpha(alpha) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| float | alpha | 0 to 1. 0 is completely transparent. 1 is completely visible and solid (can't see through) | + +### SetIcon + +Changes the icon that is shown on the title bar and on the task bar. +NOTE - The file type is IMPORTANT and depends on the OS! +Can pass in: +* filename which must be a .ICO icon file for windows, PNG file for Linux +* bytes object +* BASE64 encoded file held in a variable + +``` +SetIcon(icon=None, pngbase64=None) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | icon | Filename or bytes object | +| str | pngbase64 | Base64 encoded image | + +### SetTransparentColor + +Set the color that will be transparent in your window. Areas with this color will be SEE THROUGH. + +``` +SetTransparentColor(color) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | color | Color string that defines the transparent color | + +### Size + +#### property: Size + +Return the current size of the window in pixels + +|Type|Name|Meaning| +|---|---|---| +|| **return** | (width, height) of the window | + +### UnHide + +Used to bring back a window that was previously hidden using the Hide method + +```python +UnHide() +``` + +### VisibilityChanged + +This is a completely dummy method that does nothing. It is here so that PySimpleGUIQt programs can make this +call and then have that same source run on plain PySimpleGUI. + +`VisibilityChanged()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | | + +### add_row + +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) + +``` +add_row(args=*<1 or N object>) +``` + +### add_rows + +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. + +``` +add_rows(rows) +``` + +### alpha_channel + +#### property: alpha_channel + +A property that changes the current alpha channel value (internal value) + +|Type|Name|Meaning| +|---|---|---| +|| **return** | (float) the current alpha channel setting according to self, not read directly from tkinter | + +### bind + +Used to add tkinter events to a Window. +The tkinter specific data is in the Window's member variable user_bind_event + +``` +bind(bind_string, key) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | bind_string | The string tkinter expected in its bind function | +| Any | key | The event that will be generated when the tkinter event occurs | + +### bring_to_front + +Brings this window to the top of all other windows (perhaps may not be brought before a window made to "stay + on top") + +```python +bring_to_front() +``` + +### close + +Closes window. Users can safely call even if window has been destroyed. Should always call when done with + a window so that resources are properly freed up within your thread. + +```python +close() +``` + +### current_location + +Get the current location of the window's top left corner + +`current_location()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | The x and y location in tuple form (x,y) | + +### disable + +Disables window from taking any input from the user + +```python +disable() +``` + +### disable_debugger + +Disable the internal debugger. By default the debugger is ENABLED + +```python +disable_debugger() +``` + +### disappear + +Causes a window to "disappear" from the screen, but remain on the taskbar. It does this by turning the alpha + channel to 0. NOTE that on some platforms alpha is not supported. The window will remain showing on these + platforms. The Raspberry Pi for example does not have an alpha setting + +```python +disappear() +``` + +### elem + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +elem(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### element + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +element(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### element_list + +Returns a list of all elements in the window + +`element_list()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | List of all elements in the window and container elements in the window | + +### enable + +Re-enables window to take user input after having it be Disabled previously + +```python +enable() +``` + +### enable_debugger + +Enables the internal debugger. By default, the debugger IS enabled + +```python +enable_debugger() +``` + +### extend_layout + +Adds new rows to an existing container element inside of this window + +``` +extend_layout(container, rows) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| (Union[Frame, Column, Tab]) | container | (Union[Frame, Column, Tab]) - The container Element the layout will be placed inside of | +| (List[List[Element]]) | rows | (List[List[Element]]) - The layout to be added | +| (Window) | **RETURN** | (Window) self so could be chained + +### fill + +Fill in elements that are input fields with data based on a 'values dictionary' + +``` +fill(values_dict) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| (Dict[Any:Any]) | values_dict | {Element key : value} pairs | +| (Window) | **RETURN** | returns self so can be chained with other methods + +### finalize + +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! + +`finalize()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | Returns 'self' so that method "Chaining" can happen (read up about it as it's very cool!) | + +### find + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +find(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### find_element + +Find element object associated with the provided key. +THIS METHOD IS NO LONGER NEEDED to be called by the user + +You can perform the same operation by writing this statement: +element = window[key] + +You can drop the entire "FindElement" function name and use [ ] instead. + +Typically used in combination with a call to element's Update method (or any other element method!): +window[key].Update(new_value) + +Versus the "old way" +window.FindElement(key).Update(new_value) + +This call can be abbreviated to any of these: +FindElement == Element == Find +Rememeber that this call will return None if no match is found which may cause your code to crash if not +checked for. + +``` +find_element(key, silent_on_error=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| Any | key | Used with window.FindElement and with return values to uniquely identify this element | +| bool | silent_on_error | If True do not display popup nor print warning of key errors | +| Union[Element, Error Element, None] | **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; + +### find_element_with_focus + +Returns the Element that currently has focus as reported by tkinter. If no element is found None is returned! + +`find_element_with_focus()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | An Element if one has been found with focus or None if no element found | + +### get_screen_dimensions + +Get the screen dimensions. NOTE - you must have a window already open for this to work (blame tkinter not me) + +`get_screen_dimensions()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | Tuple containing width and height of screen in pixels | + +### get_screen_size + +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. + +``` +get_screen_size() -> Tuple[int, int] - Size of the screen in pixels as determined by tkinter +``` + +### grab_any_where_off + +Turns off Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet + been Finalized or Read. + +```python +grab_any_where_off() +``` + +### grab_any_where_on + +Turns on Grab Anywhere functionality AFTER a window has been created. Don't try on a window that's not yet + been Finalized or Read. + +```python +grab_any_where_on() +``` + +### hide + +Hides the window from the screen and the task bar + +```python +hide() +``` + +### layout + +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. + +``` +layout(rows) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| List[List[Elements]] | rows | Your entire layout | +| (Window) | **RETURN** | self so that you can chain method calls + +### load_from_disk + +Restore values from a previous call to SaveToDisk which saves the returned values dictionary in Pickle format + +``` +load_from_disk(filename) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | filename | Pickle Filename to load | + +### maximize + +Maximize the window. This is done differently on a windows system versus a linux or mac one. For non-Windows + the root attribute '-fullscreen' is set to True. For Windows the "root" state is changed to "zoomed" + The reason for the difference is the title bar is removed in some cases when using fullscreen option + +```python +maximize() +``` + +### minimize + +Minimize this window to the task bar + +```python +minimize() +``` + +### move + +Move the upper left corner of this window to the x,y coordinates provided + +``` +move(x, y) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| int | x | x coordinate in pixels | +| int | y | y coordinate in pixels | + +### normal + +Restore a window to a non-maximized state. Does different things depending on platform. See Maximize for more. + +```python +normal() +``` + +### read + +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. + +``` +read(timeout=None, + timeout_key="__TIMEOUT__", + close=False) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| int | timeout | Milliseconds to wait until the Read will return IF no other GUI events happen first | +| Any | timeout_key | The value that will be returned from the call if the timer expired | +| bool | close | if True the window will be closed prior to returning | +| Tuple[(Any), Union[Dict[Any:Any]], List[Any], None] | **RETURN** | (event, values) + +### reappear + +Causes a window previously made to "Disappear" (using that method). Does this by restoring the alpha channel + +```python +reappear() +``` + +### refresh + +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 + +`refresh()` + +|Type|Name|Meaning| +|---|---|---| +|| **return** | `self` so that method calls can be easily "chained" | + +### save_to_disk + +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. + +``` +save_to_disk(filename) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | filename | Filename to save the values to in pickled form | + +### send_to_back + +Pushes this window to the bottom of the stack of windows. It is the opposite of BringToFront + +```python +send_to_back() +``` + +### set_alpha + +Sets the Alpha Channel for a window. Values are between 0 and 1 where 0 is completely transparent + +``` +set_alpha(alpha) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| float | alpha | 0 to 1. 0 is completely transparent. 1 is completely visible and solid (can't see through) | + +### set_icon + +Changes the icon that is shown on the title bar and on the task bar. +NOTE - The file type is IMPORTANT and depends on the OS! +Can pass in: +* filename which must be a .ICO icon file for windows, PNG file for Linux +* bytes object +* BASE64 encoded file held in a variable + +``` +set_icon(icon=None, pngbase64=None) +``` + +Parameter Descriptions: + +|Type|Name|Meaning| +|--|--|--| +| str | icon | Filename or bytes object | +| str | pngbase64 | Base64 encoded image | + ### set_transparent_color Set the color that will be transparent in your window. Areas with this color will be SEE THROUGH. @@ -10034,6 +11228,7 @@ Parameter Descriptions: | str | transparent_color | This color will be completely see-through in your window. Can even click through | | str | title | Title that will be shown on the window | | str | 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 | +| None | **RETURN** | No return value Display a Popup without a titlebar. Enables grab anywhere so you can move it @@ -10934,6 +12129,7 @@ Parameter Descriptions: | str | transparent_color | This color will be completely see-through in your window. Can even click through | | str | title | Title that will be shown on the window | | str | 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 | +| None | **RETURN** | No return value Display a Popup without a titlebar. Enables grab anywhere so you can move it diff --git a/docs/cookbook.md b/docs/cookbook.md index af2c24a7..82edeaa4 100644 --- a/docs/cookbook.md +++ b/docs/cookbook.md @@ -7,10 +7,10 @@ It's been a little while getting back around to the Cookbook. As a result, some of the information was using older design patterns and some better examples need to be included. There have been about 1/3 of the changes made so far that need to get made, so be patient. # The PySimpleGUI Cookbook -Welcome to the PySimpleGUI Cookbook! It's provided as but one component of a larger documentation effort for the PySimpleGUI package. It's purpose is to give you a jump start. +Welcome to the PySimpleGUI Cookbook! It's provided as but one component of a larger documentation effort for the PySimpleGUI package. Its purpose is to give you a jump start. You'll find that starting with a Recipe will give you a big jump-start on creating your custom GUI. Copy and paste one of these Recipes and modify it to match your requirements. Study them to get an idea of some design patterns to follow. -This document is not a replacement for the main documentation at http://www.PySimpleGUI.org. If you're looking for answers, they're most likely there in the detailed explanations and call defintions. That document is updated much more frequently than this one. +This document is not a replacement for the main documentation at http://www.PySimpleGUI.org. If you're looking for answers, they're most likely there in the detailed explanations and call definitions. That document is updated much more frequently than this one. See the main doc on installation. Typically it's `pip install pysimplegui` to install. @@ -97,7 +97,7 @@ This will be the most common pattern you'll follow if you are not using an "even When you "read" a window, you are returned a tuple consisting of an `event` and a dictionary of `values`. -The`event` is what caused the read to return. It could be a button press, some text clicked, a list item chosen, etc, or `None` if the user closes the window using the X. +The `event` is what caused the read to return. It could be a button press, some text clicked, a list item chosen, etc, or `None` if the user closes the window using the X. The `values` is a dictionary of values of all the input-style elements. Dictionaries use keys to define entries. If your elements do not specificy a key, one is provided for you. These auto-numbered keys are ints starting at zero. @@ -240,7 +240,7 @@ window = sg.Window('Pattern 2B', layout) while True: # Event Loop event, values = window.read() print(event, values) - if event in (None, 'Exit'): + if event == sg.WIN_CLOSED or event == 'Exit': break if event == 'Show': # Update the "output" text element to be the value of "input" element @@ -257,9 +257,9 @@ The way we're achieving output here is by changing a Text Element with this stat window['-OUTPUT-'].update(values['-IN-']) ``` -`window['-OUTPUT-']` returns the element that has the key `'-OUTPUT-'`. Then the `update` method for that element is called so that the value of the Text Element is modified. +`window['-OUTPUT-']` returns the element that has the key `'-OUTPUT-'`. Then the `update` method for that element is called so that the value of the Text Element is modified. Be sure you have supplied a `size` that is large enough to display your output. If the size is too small, the output will be truncated. -Note - if you need to interact with elements prior to calling `window.read()` you will need to "finalize" your window first. +If you need to interact with elements prior to calling `window.read()` you will need to "finalize" your window first using the `finalize` parameter when you create your `Window`. "Interacting" means calling that element's methods such as `update`, `draw_line`, etc. ------------ diff --git a/docs/index.md b/docs/index.md index 0daef748..14b5092e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,6 +16,7 @@ ![GitHub issues](https://img.shields.io/github/issues-raw/PySimpleGUI/PySimpleGUI?color=blue) ![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/PySimpleGUI/PySimpleGUI?color=blue) [![Commit activity](https://img.shields.io/github/commit-activity/m/PySimpleGUI/PySimpleGUI.svg?style=for-the-badge)](../../commits/master) [![Last commit](https://img.shields.io/github/last-commit/PySimpleGUI/PySimpleGUI.svg?style=for-the-badge)](../../commits/master) +![CodeFactor](https://www.codefactor.io/repository/github/PySimpleGUI/PySimpleGUI/badge) # PySimpleGUI User's Manual @@ -52,7 +53,7 @@ window = sg.Window('Window Title', layout) # Event Loop to process "events" and get the "values" of the inputs while True: event, values = window.read() - if event in (None, 'Cancel'): # if user closes window or clicks cancel + if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel break print('You entered ', values[0]) @@ -107,8 +108,6 @@ and returns the value input as well as the button clicked. * 170+ Demo Programs teach you how to integrate with many popular packages like OpenCV, Matplotlib, PyGame, etc. * 200 pages of documentation, a Cookbook, built-in help using docstrings, in short it's heavily documented -#### July-2019 Note - This readme is being generated from the PySimpleGUI.py file located on GitHub. As a result, some of the calls or parameters may not match the PySimpleGUI that you pip installed. - ## GUI Development does not have to be difficult nor painful. It can be (and is) FUN #### What users are saying about PySimpleGUI @@ -296,7 +295,7 @@ window = sg.Window('Window Title', layout) # Event Loop to process "events" while True: event, values = window.read() - if event in (None, 'Cancel'): + if event in (sg.WIN_CLOSED, 'Cancel'): break window.close() @@ -431,7 +430,7 @@ import tkinter import cv2, PySimpleGUI as sg USE_CAMERA = 0 # change to 1 for front facing camera window, cap = sg.Window('Demo Application - OpenCV Integration', [[sg.Image(filename='', key='image')], ], location=(0, 0), grab_anywhere=True), cv2.VideoCapture(USE_CAMERA) -while window(timeout=20)[0] is not None: +while window(timeout=20)[0] != sg.WIN_CLOSED: window['image'](data=cv2.imencode('.png', cap.read()[1])[1].tobytes()) ``` @@ -1340,7 +1339,7 @@ You can, and will be able to for some time, use both names. However, at some po The help system will work with both names as will your IDE's docstring viewing. However, the result found will show the CamelCase names. For example `help(sg.Window.read)` will show the CamelCase name of the method/function. This is what will be returned: -`Read(self, timeout=None, timeout_key='__TIMEOUT__')` +`Read(self, timeout=None, timeout_key='__TIMEOUT__', close=False)` ## The Renaming Convention @@ -1844,6 +1843,7 @@ Parameter Descriptions: | str | transparent_color | This color will be completely see-through in your window. Can even click through | | str | title | Title that will be shown on the window | | str | 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 | +| None | **RETURN** | No return value ***To close animated popups***, call PopupAnimated with `image_source=None`. This will close all of the currently open PopupAnimated windows. @@ -2328,7 +2328,7 @@ The button value from a Read call will be one of 2 values: If a button has a key set when it was created, then that key will be returned, regardless of what text is shown on the button. If no key is set, then the button text is returned. If no button was clicked, but the window returned anyway, the event value is the key that caused the event to be generated. For example, if `enable_events` is set on an `Input` Element and someone types a character into that `Input` box, then the event will be the key of the input box. -### **None is returned when the user clicks the X to close a window.** +### **WIN_CLOSED (None) is returned when the user clicks the X to close a window.** If your window has an event loop where it is read over and over, remember to give your user an "out". You should ***always check for a None value*** and it's a good practice to provide an Exit button of some kind. Thus design patterns often resemble this Event Loop: @@ -2551,7 +2551,7 @@ Clicking the Submit button caused the window call to return. The call to Popup ![image](https://user-images.githubusercontent.com/13696193/62234737-47f33480-b399-11e9-8a2c-087cc49868cd.png) -**`Note, event values can be None`**. The value for `event` will be the text that is displayed on the button element when it was created or the key for the button. If the user closed the window using the "X" in the upper right corner of the window, then `event` will be `None`. It is ***vitally*** ***important*** that your code contain the proper checks for None. +**`Note, event values can be None`**. The value for `event` will be the text that is displayed on the button element when it was created or the key for the button. If the user closed the window using the "X" in the upper right corner of the window, then `event` will be `sg.WIN_CLOSED` which is equal to `None`. It is ***vitally*** ***important*** that your code contain the proper checks for `sg.WIN_CLOSED`. For "persistent windows", **always give your users a way out of the window**. Otherwise you'll end up with windows that never properly close. It's literally 2 lines of code that you'll find in every Demo Program. While you're at it, make sure a `window.close()` call is after your event loop so that your window closes for sure. @@ -2851,7 +2851,7 @@ Call to force a window to go through the final stages of initialization. This w If you want to call an element's `Update` method or call a `Graph` element's drawing primitives, you ***must*** either call `Read` or `Finalize` prior to making those calls. -#### read(timeout=None, timeout_key=TIMEOUT_KEY) +#### read(timeout=None, timeout_key=TIMEOUT_KEY, close=False) Read the Window's input values and button clicks in a blocking-fashion @@ -3980,7 +3980,7 @@ while (True): # This is the code that reads and updates your window event, values = window.read(timeout=50) print(event) - if event in ('Quit', None): + if event in ('Quit', sg.WIN_CLOSED): break window.close() # Don't forget to close your window! @@ -5276,7 +5276,7 @@ win2_active = False while True: ev1, vals1 = win1.read(timeout=100) win1['-OUTPUT-'].update(vals1[0]) - if ev1 is None or ev1 == 'Exit': + if ev1 == sg.WIN_CLOSED or ev1 == 'Exit': break if not win2_active and ev1 == 'Launch 2': @@ -5288,7 +5288,7 @@ while True: if win2_active: ev2, vals2 = win2.read(timeout=100) - if ev2 is None or ev2 == 'Exit': + if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': win2_active = False win2.close() ``` @@ -5309,7 +5309,7 @@ win1 = sg.Window('Window 1', layout) win2_active=False while True: ev1, vals1 = win1.read(timeout=100) - if ev1 is None: + if ev1 == sg.WIN_CLOSED: break win1.FindElement('-OUTPUT-').update(vals1[0]) @@ -5322,7 +5322,7 @@ while True: win2 = sg.Window('Window 2', layout2) while True: ev2, vals2 = win2.read() - if ev2 is None or ev2 == 'Exit': + if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': win2.close() win2_active = False win1.UnHide() @@ -7215,6 +7215,34 @@ Long list of stuff! * Some changes in test harness that tested recent changes (may still need shortening for trinket or others) * Changed the misleading TRANSPARENT_BUTTON constant with an attempt using themes calls +## 4.20.0 PySimpleGUI 6-Jun-2020 + +Fixes and new features... broad range + +* Fix for Typing import for Pi (3.4) users. Now "tries" to import typing +* Tooltip fonts - can change the font for tooltips +* Fixed tearoff for Menus. Had stoppped working +* Radio - If element is updated to False, the entire group of radio buttons will be set to false tooltips +* Multiline - fix for colors. Only set tags for output that has specific colors +* Multiline - keeping track of disabled with Disabled mumber variable +* Progress bar + * Added class variable "uniqueness counter" so that every bar will have its own settings + * Needed in case the same key is used in another window +* Fix for stdout being reset if someone sets flush on their call to print +* Mac special case added to tkfiledialog.askdirectory just like on askopenfilename +* Tab - can "update" the title +* Menu update - was not applying font when updating the menu +* Window.set_title - allows you to change the title for a window +* Added searching through Panes when looking for element with focus +* Removed Python 2 Add Menu Item code +* Added font to buttonmenu. +* Added font to the combobox drop-down list (wow what a pain) +* Table now uses the element's padding rather than 0,0 +* Tree now uses the element's padding rather than 0,0 +* set_options - added ability to set the tooltip font +* Fixed a couple of docstrings +* Reworked main() test harness to dispay DETAILED tkinter info and use bettter colors + ### Upcoming There will always be overlapping work as the ports will never actually be "complete" as there's always something new that can be built. However there's a definition for the base functionality for PySimpleGUI. This is what is being strived for with the currnt ports that are underway. diff --git a/readme.md b/readme.md index 0daef748..14b5092e 100644 --- a/readme.md +++ b/readme.md @@ -16,6 +16,7 @@ ![GitHub issues](https://img.shields.io/github/issues-raw/PySimpleGUI/PySimpleGUI?color=blue) ![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/PySimpleGUI/PySimpleGUI?color=blue) [![Commit activity](https://img.shields.io/github/commit-activity/m/PySimpleGUI/PySimpleGUI.svg?style=for-the-badge)](../../commits/master) [![Last commit](https://img.shields.io/github/last-commit/PySimpleGUI/PySimpleGUI.svg?style=for-the-badge)](../../commits/master) +![CodeFactor](https://www.codefactor.io/repository/github/PySimpleGUI/PySimpleGUI/badge) # PySimpleGUI User's Manual @@ -52,7 +53,7 @@ window = sg.Window('Window Title', layout) # Event Loop to process "events" and get the "values" of the inputs while True: event, values = window.read() - if event in (None, 'Cancel'): # if user closes window or clicks cancel + if event == sg.WIN_CLOSED or event == 'Cancel': # if user closes window or clicks cancel break print('You entered ', values[0]) @@ -107,8 +108,6 @@ and returns the value input as well as the button clicked. * 170+ Demo Programs teach you how to integrate with many popular packages like OpenCV, Matplotlib, PyGame, etc. * 200 pages of documentation, a Cookbook, built-in help using docstrings, in short it's heavily documented -#### July-2019 Note - This readme is being generated from the PySimpleGUI.py file located on GitHub. As a result, some of the calls or parameters may not match the PySimpleGUI that you pip installed. - ## GUI Development does not have to be difficult nor painful. It can be (and is) FUN #### What users are saying about PySimpleGUI @@ -296,7 +295,7 @@ window = sg.Window('Window Title', layout) # Event Loop to process "events" while True: event, values = window.read() - if event in (None, 'Cancel'): + if event in (sg.WIN_CLOSED, 'Cancel'): break window.close() @@ -431,7 +430,7 @@ import tkinter import cv2, PySimpleGUI as sg USE_CAMERA = 0 # change to 1 for front facing camera window, cap = sg.Window('Demo Application - OpenCV Integration', [[sg.Image(filename='', key='image')], ], location=(0, 0), grab_anywhere=True), cv2.VideoCapture(USE_CAMERA) -while window(timeout=20)[0] is not None: +while window(timeout=20)[0] != sg.WIN_CLOSED: window['image'](data=cv2.imencode('.png', cap.read()[1])[1].tobytes()) ``` @@ -1340,7 +1339,7 @@ You can, and will be able to for some time, use both names. However, at some po The help system will work with both names as will your IDE's docstring viewing. However, the result found will show the CamelCase names. For example `help(sg.Window.read)` will show the CamelCase name of the method/function. This is what will be returned: -`Read(self, timeout=None, timeout_key='__TIMEOUT__')` +`Read(self, timeout=None, timeout_key='__TIMEOUT__', close=False)` ## The Renaming Convention @@ -1844,6 +1843,7 @@ Parameter Descriptions: | str | transparent_color | This color will be completely see-through in your window. Can even click through | | str | title | Title that will be shown on the window | | str | 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 | +| None | **RETURN** | No return value ***To close animated popups***, call PopupAnimated with `image_source=None`. This will close all of the currently open PopupAnimated windows. @@ -2328,7 +2328,7 @@ The button value from a Read call will be one of 2 values: If a button has a key set when it was created, then that key will be returned, regardless of what text is shown on the button. If no key is set, then the button text is returned. If no button was clicked, but the window returned anyway, the event value is the key that caused the event to be generated. For example, if `enable_events` is set on an `Input` Element and someone types a character into that `Input` box, then the event will be the key of the input box. -### **None is returned when the user clicks the X to close a window.** +### **WIN_CLOSED (None) is returned when the user clicks the X to close a window.** If your window has an event loop where it is read over and over, remember to give your user an "out". You should ***always check for a None value*** and it's a good practice to provide an Exit button of some kind. Thus design patterns often resemble this Event Loop: @@ -2551,7 +2551,7 @@ Clicking the Submit button caused the window call to return. The call to Popup ![image](https://user-images.githubusercontent.com/13696193/62234737-47f33480-b399-11e9-8a2c-087cc49868cd.png) -**`Note, event values can be None`**. The value for `event` will be the text that is displayed on the button element when it was created or the key for the button. If the user closed the window using the "X" in the upper right corner of the window, then `event` will be `None`. It is ***vitally*** ***important*** that your code contain the proper checks for None. +**`Note, event values can be None`**. The value for `event` will be the text that is displayed on the button element when it was created or the key for the button. If the user closed the window using the "X" in the upper right corner of the window, then `event` will be `sg.WIN_CLOSED` which is equal to `None`. It is ***vitally*** ***important*** that your code contain the proper checks for `sg.WIN_CLOSED`. For "persistent windows", **always give your users a way out of the window**. Otherwise you'll end up with windows that never properly close. It's literally 2 lines of code that you'll find in every Demo Program. While you're at it, make sure a `window.close()` call is after your event loop so that your window closes for sure. @@ -2851,7 +2851,7 @@ Call to force a window to go through the final stages of initialization. This w If you want to call an element's `Update` method or call a `Graph` element's drawing primitives, you ***must*** either call `Read` or `Finalize` prior to making those calls. -#### read(timeout=None, timeout_key=TIMEOUT_KEY) +#### read(timeout=None, timeout_key=TIMEOUT_KEY, close=False) Read the Window's input values and button clicks in a blocking-fashion @@ -3980,7 +3980,7 @@ while (True): # This is the code that reads and updates your window event, values = window.read(timeout=50) print(event) - if event in ('Quit', None): + if event in ('Quit', sg.WIN_CLOSED): break window.close() # Don't forget to close your window! @@ -5276,7 +5276,7 @@ win2_active = False while True: ev1, vals1 = win1.read(timeout=100) win1['-OUTPUT-'].update(vals1[0]) - if ev1 is None or ev1 == 'Exit': + if ev1 == sg.WIN_CLOSED or ev1 == 'Exit': break if not win2_active and ev1 == 'Launch 2': @@ -5288,7 +5288,7 @@ while True: if win2_active: ev2, vals2 = win2.read(timeout=100) - if ev2 is None or ev2 == 'Exit': + if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': win2_active = False win2.close() ``` @@ -5309,7 +5309,7 @@ win1 = sg.Window('Window 1', layout) win2_active=False while True: ev1, vals1 = win1.read(timeout=100) - if ev1 is None: + if ev1 == sg.WIN_CLOSED: break win1.FindElement('-OUTPUT-').update(vals1[0]) @@ -5322,7 +5322,7 @@ while True: win2 = sg.Window('Window 2', layout2) while True: ev2, vals2 = win2.read() - if ev2 is None or ev2 == 'Exit': + if ev2 == sg.WIN_CLOSED or ev2 == 'Exit': win2.close() win2_active = False win1.UnHide() @@ -7215,6 +7215,34 @@ Long list of stuff! * Some changes in test harness that tested recent changes (may still need shortening for trinket or others) * Changed the misleading TRANSPARENT_BUTTON constant with an attempt using themes calls +## 4.20.0 PySimpleGUI 6-Jun-2020 + +Fixes and new features... broad range + +* Fix for Typing import for Pi (3.4) users. Now "tries" to import typing +* Tooltip fonts - can change the font for tooltips +* Fixed tearoff for Menus. Had stoppped working +* Radio - If element is updated to False, the entire group of radio buttons will be set to false tooltips +* Multiline - fix for colors. Only set tags for output that has specific colors +* Multiline - keeping track of disabled with Disabled mumber variable +* Progress bar + * Added class variable "uniqueness counter" so that every bar will have its own settings + * Needed in case the same key is used in another window +* Fix for stdout being reset if someone sets flush on their call to print +* Mac special case added to tkfiledialog.askdirectory just like on askopenfilename +* Tab - can "update" the title +* Menu update - was not applying font when updating the menu +* Window.set_title - allows you to change the title for a window +* Added searching through Panes when looking for element with focus +* Removed Python 2 Add Menu Item code +* Added font to buttonmenu. +* Added font to the combobox drop-down list (wow what a pain) +* Table now uses the element's padding rather than 0,0 +* Tree now uses the element's padding rather than 0,0 +* set_options - added ability to set the tooltip font +* Fixed a couple of docstrings +* Reworked main() test harness to dispay DETAILED tkinter info and use bettter colors + ### Upcoming There will always be overlapping work as the ports will never actually be "complete" as there's always something new that can be built. However there's a definition for the base functionality for PySimpleGUI. This is what is being strived for with the currnt ports that are underway.