Release 4.50.0
This commit is contained in:
parent
4d8dad1efe
commit
d0f945c74e
|
@ -1,68 +1,12 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
version = __version__ = "4.49.0.19 Unreleased"
|
version = __version__ = "4.50.0 Released 17-Oct-2021"
|
||||||
|
|
||||||
_change_log = """
|
_change_log = """
|
||||||
|
|
||||||
Changelog since 4.49.0 release to PyPI on 30 Sept 2021
|
Changelog since 4.50.0 release to PyPI on 17-Oct-2021
|
||||||
|
|
||||||
|
|
||||||
4.49.0.1
|
|
||||||
Element.set_right_click_menu added so can set or change the right click menu for an element
|
|
||||||
4.49.0.2
|
|
||||||
Element.set_right_click_menu - If no menu supplied, use the parent form's right click menu
|
|
||||||
4.49.0.3
|
|
||||||
User Settings path created specifically for Trinkets
|
|
||||||
4.49.0.4
|
|
||||||
Addition of running_replit to determine if running on replit's site.
|
|
||||||
If on replit then a path for user settigs is set to .
|
|
||||||
4.49.0.5
|
|
||||||
Make pin's background match the element's background
|
|
||||||
4.49.0.6
|
|
||||||
set_options new option warn_button_key_duplicates - warn duplicate keys on buttons - defaults to False
|
|
||||||
4.49.0.7
|
|
||||||
Addition of Window.get_size_accurate - size based on the geometry string
|
|
||||||
Removed window move of the theme color swatch preview window. Seems to center correctly now.
|
|
||||||
4.49.0.8
|
|
||||||
Added check for a bad value being returned from tkinter during the table clicked event
|
|
||||||
Removed print when patch of 8.6.9 ttk treeview code is patched
|
|
||||||
4.49.0.9
|
|
||||||
Removed print when bind callback happens. Was there for debugging and forgot to remove.
|
|
||||||
4.49.0.10
|
|
||||||
Phase 1 Support of config files for UserSettings APIs - load, read/modify, save are done. The basic version is done.
|
|
||||||
This first phase supports them only via the object interface
|
|
||||||
Read access: settings[section][key]
|
|
||||||
Modify existing section and key: settings[section][key] = new_value
|
|
||||||
Create a new key in an existing section: settings[section][new_key] = new_value
|
|
||||||
Create a new section and key: settings[new_section][new_key] = new_value
|
|
||||||
Get a section as a dictionary-like object: settings[section]
|
|
||||||
This object can be modified and it will modify the settings file as a result.
|
|
||||||
Has a get and set method just like a normal setting.
|
|
||||||
Delete a section: settings.delete_section(section)
|
|
||||||
Save the INI file: settings.save()
|
|
||||||
Option to convert bools and None. Normally stored as strings. Will convert them to Python True, False, None automatically (on by default)
|
|
||||||
4.49.0.11
|
|
||||||
Better formnatted printing of INI based UserSettings object
|
|
||||||
4.49.0.12
|
|
||||||
Addition of horizontal scrollbar to Listbox
|
|
||||||
4.49.0.13
|
|
||||||
Better pin implementation, maybe. Was able to not use a Canvas element and instead use a blank Column element. Blended better. Still uses 1 pixel :-(
|
|
||||||
Column element - Changed how None in one of locations in size tuple handled.
|
|
||||||
If width is None, then required width will be used, if height is None, then 1/2 required height.
|
|
||||||
These are same values as None, None currently.
|
|
||||||
Window.LayoutAndRead deprication made more friendly with popup.
|
|
||||||
4.49.0.14
|
|
||||||
Added * to default for all place file_types is a parameter so that files without extensions are shown
|
|
||||||
4.49.0.15
|
|
||||||
Fixed errors in file_types in 0.14. Made into a constant FILE_TYPES_ALL_FILES so it's easy to find and change in the future
|
|
||||||
4.49.0.16
|
|
||||||
Reworked the repr method of UserSettings for config.ini files. Dumped using pprint and did my own instaed
|
|
||||||
popup_scrolled - add an additional line per parm. Sometimes not enough height was computed
|
|
||||||
4.49.0.17
|
|
||||||
Fixed problem in the delete_section code for UserSettings for INI files.
|
|
||||||
4.49.0.18
|
|
||||||
Removed the UserSettings merge_comments_from_file code (for now)
|
|
||||||
4.49.0.19
|
|
||||||
Docstring updates for FINAL RELEASE
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__version__ = version.split()[0] # For PEP 396 and PEP 345
|
__version__ = version.split()[0] # For PEP 396 and PEP 345
|
||||||
|
|
|
@ -42,7 +42,7 @@ Button(button_text = "",
|
||||||
button_type = 7,
|
button_type = 7,
|
||||||
target = (None, None),
|
target = (None, None),
|
||||||
tooltip = None,
|
tooltip = None,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
disabled = False,
|
disabled = False,
|
||||||
|
@ -83,7 +83,7 @@ Parameter Descriptions:
|
||||||
| int | button_type | You should NOT be setting this directly. ONLY the shortcut functions set this |
|
| int | button_type | You should NOT be setting this directly. ONLY the shortcut functions set this |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button |
|
| str or (int, int) | target | key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button |
|
||||||
| str | tooltip | text, that will appear when mouse hovers over the element |
|
| str | tooltip | text, that will appear when mouse hovers over the element |
|
||||||
| Tuple[(str, str), ...] | file_types | the filetypes that will be used to match files. To indicate all files: (("ALL Files", "*.*"),). Note - NOT SUPPORTED ON MAC |
|
| Tuple[(str, str), ...] | file_types | the filetypes that will be used to match files. To indicate all files: (("ALL Files", "*.* *"),). Note - NOT SUPPORTED ON MAC |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| (bool or str) | disabled | If True button will be created disabled. If BUTTON_DISABLED_MEANS_IGNORE then the button will be ignored rather than disabled using tkinter |
|
| (bool or str) | disabled | If True button will be created disabled. If BUTTON_DISABLED_MEANS_IGNORE then the button will be ignored rather than disabled using tkinter |
|
||||||
|
@ -1482,8 +1482,8 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| List[List[Element]] | layout | Layout that will be shown in the Column container |
|
| List[List[Element]] | layout | Layout that will be shown in the Column container |
|
||||||
| str | background_color | color of background of entire Column |
|
| str | background_color | color of background of entire Column |
|
||||||
| (int, int) | size | (width, height) size in pixels (doesn't work quite right, sometimes only 1 dimension is set by tkinter. Use a Sizer Element to help set sizes |
|
| (int or None, int or None) | size | (width, height) size in pixels (doesn't work quite right, sometimes only 1 dimension is set by tkinter. Use a Sizer Element to help set sizes |
|
||||||
| (int, int) or (None, None) | s | Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used |
|
| (int or None, int or None) | s | Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used |
|
||||||
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | pad | Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int) |
|
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | pad | Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int) |
|
||||||
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | p | Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used |
|
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | p | Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used |
|
||||||
| bool | scrollable | if True then scrollbars will be added to the column |
|
| bool | scrollable | if True then scrollbars will be added to the column |
|
||||||
|
@ -4628,6 +4628,7 @@ Listbox(values,
|
||||||
auto_size_text = None,
|
auto_size_text = None,
|
||||||
font = None,
|
font = None,
|
||||||
no_scrollbar = False,
|
no_scrollbar = False,
|
||||||
|
horizontal_scroll = False,
|
||||||
background_color = None,
|
background_color = None,
|
||||||
text_color = None,
|
text_color = None,
|
||||||
highlight_background_color = None,
|
highlight_background_color = None,
|
||||||
|
@ -4660,6 +4661,7 @@ Parameter Descriptions:
|
||||||
| bool | auto_size_text | True if element should be the same size as the contents |
|
| bool | auto_size_text | True if element should be the same size as the contents |
|
||||||
| (str or (str, int[, str]) or None) | font | specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike |
|
| (str or (str, int[, str]) or None) | font | specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike |
|
||||||
| bool | no_scrollbar | Controls if a scrollbar should be shown. If True, no scrollbar will be shown |
|
| bool | no_scrollbar | Controls if a scrollbar should be shown. If True, no scrollbar will be shown |
|
||||||
|
| bool | horizontal_scroll | Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical |
|
||||||
| str | background_color | color of background |
|
| str | background_color | color of background |
|
||||||
| str | text_color | color of the text |
|
| str | text_color | color of the text |
|
||||||
| str | highlight_background_color | color of the background when an item is selected. Defaults to normal text color (a reverse look) |
|
| str | highlight_background_color | color of the background when an item is selected. Defaults to normal text color (a reverse look) |
|
||||||
|
@ -11102,7 +11104,9 @@ User Settings
|
||||||
UserSettings(filename = None,
|
UserSettings(filename = None,
|
||||||
path = None,
|
path = None,
|
||||||
silent_on_error = False,
|
silent_on_error = False,
|
||||||
autosave = True)
|
autosave = True,
|
||||||
|
use_config_file = None,
|
||||||
|
convert_bools_and_none = True)
|
||||||
```
|
```
|
||||||
|
|
||||||
Parameter Descriptions:
|
Parameter Descriptions:
|
||||||
|
@ -11113,6 +11117,8 @@ Parameter Descriptions:
|
||||||
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
||||||
| bool | silent_on_error | If True errors will not be reported |
|
| bool | silent_on_error | If True errors will not be reported |
|
||||||
| bool | autosave | If True the settings file is saved after every update |
|
| bool | autosave | If True the settings file is saved after every update |
|
||||||
|
| bool | use_config_file | If True then the file format will be a config.ini rather than json |
|
||||||
|
| bool | convert_bools_and_none | If True then "True", "False", "None" will be converted to the Python values True, False, None when using INI files. Default is TRUE |
|
||||||
|
|
||||||
### delete_entry
|
### delete_entry
|
||||||
|
|
||||||
|
@ -11121,7 +11127,7 @@ then a default filename will be used.
|
||||||
After value has been deleted, the settings file is written to disk.
|
After value has been deleted, the settings file is written to disk.
|
||||||
|
|
||||||
```
|
```
|
||||||
delete_entry(key)
|
delete_entry(key, section = None)
|
||||||
```
|
```
|
||||||
|
|
||||||
Parameter Descriptions:
|
Parameter Descriptions:
|
||||||
|
@ -11149,6 +11155,20 @@ Parameter Descriptions:
|
||||||
| (str or None) | filename | The name of the file to use. Can be a full path and filename or just filename |
|
| (str or None) | filename | The name of the file to use. Can be a full path and filename or just filename |
|
||||||
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
||||||
|
|
||||||
|
### delete_section
|
||||||
|
|
||||||
|
Deletes a section with the name provided in the section parameter. Your INI file will be saved afterwards if auto-save enabled (default is ON)
|
||||||
|
|
||||||
|
```
|
||||||
|
delete_section(section)
|
||||||
|
```
|
||||||
|
|
||||||
|
Parameter Descriptions:
|
||||||
|
|
||||||
|
|Type|Name|Meaning|
|
||||||
|
|--|--|--|
|
||||||
|
| str | section | Name of the section to delete |
|
||||||
|
|
||||||
### exists
|
### exists
|
||||||
|
|
||||||
Check if a particular settings file exists. Returns True if file exists
|
Check if a particular settings file exists. Returns True if file exists
|
||||||
|
@ -11241,6 +11261,7 @@ Parameter Descriptions:
|
||||||
### read
|
### read
|
||||||
|
|
||||||
Reads settings file and returns the dictionary.
|
Reads settings file and returns the dictionary.
|
||||||
|
If you have anything changed in an existing settings dictionary, you will lose your changes.
|
||||||
|
|
||||||
`read()`
|
`read()`
|
||||||
|
|
||||||
|
@ -11270,6 +11291,8 @@ Parameter Descriptions:
|
||||||
Sets an individual setting to the specified value. If no filename has been specified up to this point,
|
Sets an individual setting to the specified value. If no filename has been specified up to this point,
|
||||||
then a default filename will be used.
|
then a default filename will be used.
|
||||||
After value has been modified, the settings file is written to disk.
|
After value has been modified, the settings file is written to disk.
|
||||||
|
Note that this call is not value for a config file normally. If it is, then the key is assumed to be the
|
||||||
|
Section key and the value written will be the default value.
|
||||||
|
|
||||||
```
|
```
|
||||||
set(key, value)
|
set(key, value)
|
||||||
|
@ -11281,7 +11304,6 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| Any | key | Setting to be saved. Can be any valid dictionary key type |
|
| Any | key | Setting to be saved. Can be any valid dictionary key type |
|
||||||
| Any | value | Value to save as the setting's value. Can be anything |
|
| Any | value | Value to save as the setting's value. Can be anything |
|
||||||
| bool | autosave | If True then the value will be saved to the file |
|
|
||||||
| (Any) | **RETURN** | value that key was set to
|
| (Any) | **RETURN** | value that key was set to
|
||||||
|
|
||||||
### set_default_value
|
### set_default_value
|
||||||
|
@ -13245,7 +13267,7 @@ Parameter Descriptions:
|
||||||
```
|
```
|
||||||
FileBrowse(button_text = "Browse",
|
FileBrowse(button_text = "Browse",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
tooltip = None,
|
tooltip = None,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
|
@ -13269,7 +13291,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Browse') |
|
| str | button_text | text in the button (Default value = 'Browse') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | filter file types (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | filter file types (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| | initial_folder | starting path for folders and files |
|
| | initial_folder | starting path for folders and files |
|
||||||
| str | tooltip | text, that will appear when mouse hovers over the element |
|
| str | tooltip | text, that will appear when mouse hovers over the element |
|
||||||
| (int, int) | size | (w,h) w=characters-wide, h=rows-high |
|
| (int, int) | size | (w,h) w=characters-wide, h=rows-high |
|
||||||
|
@ -13290,7 +13312,7 @@ Parameter Descriptions:
|
||||||
```
|
```
|
||||||
FileSaveAs(button_text = "Save As...",
|
FileSaveAs(button_text = "Save As...",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
disabled = False,
|
disabled = False,
|
||||||
|
@ -13315,7 +13337,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Save As...') |
|
| str | button_text | text in the button (Default value = 'Save As...') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| bool | disabled | set disable state for element (Default = False) |
|
| bool | disabled | set disable state for element (Default = False) |
|
||||||
|
@ -13339,7 +13361,7 @@ Allows browsing of multiple files. File list is returned as a single list with t
|
||||||
```
|
```
|
||||||
FilesBrowse(button_text = "Browse",
|
FilesBrowse(button_text = "Browse",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
disabled = False,
|
disabled = False,
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
tooltip = None,
|
tooltip = None,
|
||||||
|
@ -13364,7 +13386,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Browse') |
|
| str | button_text | text in the button (Default value = 'Browse') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| bool | disabled | set disable state for element (Default = False) |
|
| bool | disabled | set disable state for element (Default = False) |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| str | tooltip | text, that will appear when mouse hovers over the element |
|
| str | tooltip | text, that will appear when mouse hovers over the element |
|
||||||
|
@ -13779,7 +13801,7 @@ Parameter Descriptions:
|
||||||
```
|
```
|
||||||
SaveAs(button_text = "Save As...",
|
SaveAs(button_text = "Save As...",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
disabled = False,
|
disabled = False,
|
||||||
|
@ -13804,7 +13826,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Save As...') |
|
| str | button_text | text in the button (Default value = 'Save As...') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| bool | disabled | set disable state for element (Default = False) |
|
| bool | disabled | set disable state for element (Default = False) |
|
||||||
|
@ -14860,7 +14882,7 @@ popup_get_file(message,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
save_as = False,
|
save_as = False,
|
||||||
multiple_files = False,
|
multiple_files = False,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
no_window = False,
|
no_window = False,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
button_color = None,
|
button_color = None,
|
||||||
|
@ -14891,7 +14913,7 @@ Parameter Descriptions:
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
||||||
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
||||||
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) |
|
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.* *"),) |
|
||||||
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
||||||
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
||||||
| (str, str) or str | button_color | Color of the button (text, background) |
|
| (str, str) or str | button_color | Color of the button (text, background) |
|
||||||
|
@ -15863,7 +15885,7 @@ PopupGetFile(message,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
save_as = False,
|
save_as = False,
|
||||||
multiple_files = False,
|
multiple_files = False,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
no_window = False,
|
no_window = False,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
button_color = None,
|
button_color = None,
|
||||||
|
@ -15894,7 +15916,7 @@ Parameter Descriptions:
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
||||||
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
||||||
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) |
|
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.* *"),) |
|
||||||
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
||||||
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
||||||
| (str, str) or str | button_color | Color of the button (text, background) |
|
| (str, str) or str | button_color | Color of the button (text, background) |
|
||||||
|
@ -17470,6 +17492,7 @@ set_options(icon = None,
|
||||||
suppress_error_popups = None,
|
suppress_error_popups = None,
|
||||||
suppress_raise_key_errors = None,
|
suppress_raise_key_errors = None,
|
||||||
suppress_key_guessing = None,
|
suppress_key_guessing = None,
|
||||||
|
warn_button_key_duplicates = False,
|
||||||
enable_treeview_869_patch = None,
|
enable_treeview_869_patch = None,
|
||||||
enable_mac_notitlebar_patch = None,
|
enable_mac_notitlebar_patch = None,
|
||||||
use_custom_titlebar = None,
|
use_custom_titlebar = None,
|
||||||
|
@ -17526,6 +17549,7 @@ Parameter Descriptions:
|
||||||
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
||||||
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
||||||
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
||||||
|
| bool | warn_button_key_duplicates | If True then duplicate Button Keys generate warnings (not recommended as they're expected) |
|
||||||
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
||||||
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
||||||
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
||||||
|
@ -17594,6 +17618,7 @@ SetOptions(icon = None,
|
||||||
suppress_error_popups = None,
|
suppress_error_popups = None,
|
||||||
suppress_raise_key_errors = None,
|
suppress_raise_key_errors = None,
|
||||||
suppress_key_guessing = None,
|
suppress_key_guessing = None,
|
||||||
|
warn_button_key_duplicates = False,
|
||||||
enable_treeview_869_patch = None,
|
enable_treeview_869_patch = None,
|
||||||
enable_mac_notitlebar_patch = None,
|
enable_mac_notitlebar_patch = None,
|
||||||
use_custom_titlebar = None,
|
use_custom_titlebar = None,
|
||||||
|
@ -17650,6 +17675,7 @@ Parameter Descriptions:
|
||||||
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
||||||
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
||||||
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
||||||
|
| bool | warn_button_key_duplicates | If True then duplicate Button Keys generate warnings (not recommended as they're expected) |
|
||||||
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
||||||
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
||||||
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
||||||
|
|
246
docs/index.md
246
docs/index.md
|
@ -90,6 +90,49 @@ and returns the value input as well as the button clicked.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# 2021 Updates....
|
||||||
|
|
||||||
|
This documentation was originally written in 2018. So much has changed since, but the early stuff still runs just fine so there's not been a huge rush to update.
|
||||||
|
|
||||||
|
Some sections have been updated and added so it's not like this is a stale document.
|
||||||
|
|
||||||
|
## What's newer?
|
||||||
|
|
||||||
|
New APIs to save you time - not just for beginners
|
||||||
|
|
||||||
|
* Exec APIs (execution of subprocesses)
|
||||||
|
* User Settings APIs (management of settings in form of a dictionary)
|
||||||
|
* Threading API call - `write_event_value`
|
||||||
|
* True multiple windows support - `read_all_windows`
|
||||||
|
* System-wide global settings - theme, interpreter to use, Mac settings, ...
|
||||||
|
* Advanced error handling including launching your editor to line of code with error
|
||||||
|
* More advanced layouts - still trivial,maybe more trivial, to make windows
|
||||||
|
* Go wild - have a complicated (i.e. not simple) application... no problem here supporting your App. "It's on you". PSG solved the GUI problem, but you still have to make an application
|
||||||
|
* Docstrings - Tight integration with docstrings provides type checking and in-IDE documentation
|
||||||
|
* `sg.main` utilities - upgrade to the GitHub version in 1 click. Lots of good stuff built-into PySimpleGUI
|
||||||
|
* Demo Browser - Navigate the 315+ Demo Programs easily. Search, execute, edit all from one application
|
||||||
|
* Cookbook - There have been a number of updates in 2021
|
||||||
|
* This document has some sections new such as the User Settings APIs
|
||||||
|
|
||||||
|
### Dynamic Windows
|
||||||
|
|
||||||
|
- Making parts of windows expand/contract with the window.
|
||||||
|
- Swap out or collapse sections
|
||||||
|
- More parms in Elements to help with justification
|
||||||
|
- New `Push` & `VPush` Elements trivialize justification
|
||||||
|
|
||||||
|
### Threading
|
||||||
|
|
||||||
|
One simple call, `write_event_value`, solves threading issues.
|
||||||
|
|
||||||
|
Not ready for the threading module but need to run a thread? Use `window.perform_long_operation` to use threads. One call and done.
|
||||||
|
|
||||||
|
### What's Old?
|
||||||
|
|
||||||
|
The old parts of this documentation are the images. The good news is that things look better than you see here. Themes have made Windows colorful in 1 line of code.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
|
||||||
#### Looking for a GUI package? Are you...
|
#### Looking for a GUI package? Are you...
|
||||||
|
|
||||||
* looking to take your Python code from the world of command lines and into the convenience of a GUI?
|
* looking to take your Python code from the world of command lines and into the convenience of a GUI?
|
||||||
|
@ -254,11 +297,9 @@ PySimpleGUI runs on Windows, Linux and Mac, just like tkinter, Qt, WxPython and
|
||||||
|
|
||||||
As of 9/25/2018 **both Python 3 and Python 2.7 are supported** when using **tkinter version** of PySimpleGUI! The Python 3 version is named `PySimpleGUI`. The Python 2.7 version is `PySimpleGUI27`. They are installed separately and the imports are different. See instructions in Installation section for more info. **None** of the other ports can use Python 2.
|
As of 9/25/2018 **both Python 3 and Python 2.7 are supported** when using **tkinter version** of PySimpleGUI! The Python 3 version is named `PySimpleGUI`. The Python 2.7 version is `PySimpleGUI27`. They are installed separately and the imports are different. See instructions in Installation section for more info. **None** of the other ports can use Python 2.
|
||||||
|
|
||||||
###### Python 2.7 Code will be deleted from this GitHub on Dec 31, 2019
|
### Python 2.7 Code was be deleted from this GitHub on Dec 31, 2019
|
||||||
|
|
||||||
Note that the 2.7 port will *cease to exist on this GitHub* on Jan 1, 2020. If you would like to know how much time you have to move over to the Python 3 version of PySimpleGUI, then go here: https://pythonclock.org/. The only thing that will be available is an unsupported PyPI release of PySimpleGUI27.
|
At the suggestion of the Python community at large, the experts, and security folks, the support for 2.7 was pulled from this Repo.
|
||||||
|
|
||||||
By "will cease to exist on this GitHub" I mean, it will be deleted entirely. No source code, no supporting programs. Nothing. If you're stuck using 2.7 in December, it would behoove you to fork the 2.7 code on Dec 31, 2019. Legacy Python doesn't have a permanent home here. It sounds cruel, but experts in security particularly says 2.7 is a huge risk. Furthering it use only hurts the computing world.
|
|
||||||
|
|
||||||
#### Warning - tkinter + Python 3.7.3 and later, including 3.8 has problems
|
#### Warning - tkinter + Python 3.7.3 and later, including 3.8 has problems
|
||||||
|
|
||||||
|
@ -350,6 +391,14 @@ At the moment there are 4 actively developed and maintained "ports" of PySimpleG
|
||||||
|
|
||||||
While PySimpleGUI, the tkinter port, is the only 100% completed version of PySimpleGUI, the other 3 ports have a LOT of functionality in them and are in active use by a large portion of the installations. You can see the number of Pip installs at the very top of this document to get a comparison as to the size of the install base for each port. The "badges" are right after the logo.
|
While PySimpleGUI, the tkinter port, is the only 100% completed version of PySimpleGUI, the other 3 ports have a LOT of functionality in them and are in active use by a large portion of the installations. You can see the number of Pip installs at the very top of this document to get a comparison as to the size of the install base for each port. The "badges" are right after the logo.
|
||||||
|
|
||||||
|
## The Chain Link Fence
|
||||||
|
|
||||||
|
Maybe you've heard the "Walled Garden" term before. It's a boxing in effect.
|
||||||
|
|
||||||
|
While PySimpleGUI has a well-established parameter so you know where the edges are, there is no wall between you and the rest of the GUI framework. There's a chain link fence that's easy to reach through and get full access to the underlying frameworks.
|
||||||
|
|
||||||
|
The net result - it's easy to expand features that are not yet available in PySimpleGUI and easy to remove them too. Maybe the Listbox Element doesn't have a mode exposed that you want to enable. No problem, you can access the underlying Listbox Widget and make what is likely 1 or 2 calls and be done.
|
||||||
|
|
||||||
# The PySimpleGUI "Family"
|
# The PySimpleGUI "Family"
|
||||||
|
|
||||||
## What's The Big Deal? What is it?
|
## What's The Big Deal? What is it?
|
||||||
|
@ -1723,7 +1772,7 @@ popup_get_file(message,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
save_as = False,
|
save_as = False,
|
||||||
multiple_files = False,
|
multiple_files = False,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
no_window = False,
|
no_window = False,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
button_color = None,
|
button_color = None,
|
||||||
|
@ -1754,7 +1803,7 @@ Parameter Descriptions:
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
||||||
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
||||||
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) |
|
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.* *"),) |
|
||||||
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
||||||
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
||||||
| (str, str) or str | button_color | Color of the button (text, background) |
|
| (str, str) or str | button_color | Color of the button (text, background) |
|
||||||
|
@ -6046,13 +6095,15 @@ Exception module 'tkinter' has no attribute '__version__'
|
||||||
|
|
||||||
# User Settings API
|
# User Settings API
|
||||||
|
|
||||||
In release 4.30.0 there is a new set of API calls available to help with "user settings". Think of user settings as a dictionary that is automatically written to your hard drive. That's basically what it is. Underpinning the code is the JSON package provided by Python.
|
In release 4.30.0 there is a new set of API calls available to help with "user settings". Think of user settings as a dictionary that is automatically written to your hard drive. That's basically what it is.
|
||||||
|
|
||||||
While using JSON files to save and load a settings dictionary isn't very difficult, it is still code you'll need to write if you want to save settings as part of your GUI. Since having "settings" for a GUI based program isn't uncommon, it made sense to build this capability into PySimpleGUI. Clearly you can still use your own method for saving settings, but if you're looking for a simple and easy way to do it, these calls are likely about as easy as it gets.
|
In release 4.50.0 support for INI files was added in addition to the existing JSON file format.
|
||||||
|
|
||||||
|
While using JSON or config files to save and load a settings dictionary isn't very difficult, it is still code you'll need to write if you want to save settings as part of your GUI. Since having "settings" for a GUI based program isn't uncommon, it made sense to build this capability into PySimpleGUI. Clearly you can still use your own method for saving settings, but if you're looking for a simple and easy way to do it, these calls are likely about as easy as it gets.
|
||||||
|
|
||||||
There have already been some demo programs written that use JSON files to store settings. You can expect that this capability will begin to show up in more demos in the future since it's now part of PySimpleGUI.
|
There have already been some demo programs written that use JSON files to store settings. You can expect that this capability will begin to show up in more demos in the future since it's now part of PySimpleGUI.
|
||||||
|
|
||||||
User settings are stored in a Python dictionary which is saved to / loaded from disk. Individual settings are thus keys into a dictionary. You do not need to explicitly read nor write the file. Changing any entry will cause the file to be saved. Reading any entry will cause the file to be read if it hasn't already been read.
|
User settings are stored in a Python dictionary which is saved to / loaded from disk. Individual settings are thus keys into a dictionary. **You do not need to explicitly read nor write the file**. Changing any entry will cause the file to be saved. Reading any entry will cause the file to be read if it hasn't already been read.
|
||||||
|
|
||||||
## Two Interfaces
|
## Two Interfaces
|
||||||
|
|
||||||
|
@ -6063,6 +6114,8 @@ There are 2 ways to access User Settings
|
||||||
|
|
||||||
They both offer the same basic operations. The class interface has an added benefit of being able to access the individual settings using the same syntax as Python dictionary.
|
They both offer the same basic operations. The class interface has an added benefit of being able to access the individual settings using the same syntax as Python dictionary.
|
||||||
|
|
||||||
|
If you want to use INI files, then you'll need to use the object interface.
|
||||||
|
|
||||||
## List of Calls for Function Interface
|
## List of Calls for Function Interface
|
||||||
|
|
||||||
|Function|Description|
|
|Function|Description|
|
||||||
|
@ -6305,7 +6358,7 @@ in main
|
||||||
|
|
||||||
You should be able to easily figure out these errors as they are file operations and the error messages are clear in detailing what's happened and where the call originated.
|
You should be able to easily figure out these errors as they are file operations and the error messages are clear in detailing what's happened and where the call originated.
|
||||||
|
|
||||||
### Silenting the Errors
|
### Silencing the Errors
|
||||||
|
|
||||||
If you're the type that doesn't want to see any error messages printed out on your console, then you can silence the error output.
|
If you're the type that doesn't want to see any error messages printed out on your console, then you can silence the error output.
|
||||||
|
|
||||||
|
@ -6313,6 +6366,133 @@ When using the class interface, there is a parameter `silent_on_error` that you
|
||||||
|
|
||||||
For the function interface, call the function `user_settings_silent_on_error()` and set the parameter to `True`
|
For the function interface, call the function `user_settings_silent_on_error()` and set the parameter to `True`
|
||||||
|
|
||||||
|
## Config INI File Support
|
||||||
|
|
||||||
|
Using INI files has some advantages over JSON, particularly when humans are going to be modifying the settings files directly.
|
||||||
|
|
||||||
|
To specify use of INI files instead of JSON, set the parameter `use_config_file=True` when creating your `UserSetting` object.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings = sg.UserSettings('my_config.ini', use_config_file=True, convert_bools_and_none=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the 2 parameters that are specific for .ini files:
|
||||||
|
* `use_config_file` - Set to `True` to indicate you're using an INI file
|
||||||
|
* `convert_bools_and_none` - Defaults to `True`. Normally all settings from INI files are strings. This parameter will convert 'True', 'False', and 'None' to Python values `True`, `False`, `None`
|
||||||
|
|
||||||
|
There is also an additional method added `delete_section` which will delete an entire section from your INI file.
|
||||||
|
|
||||||
|
### Example File
|
||||||
|
|
||||||
|
Let's use this as our example INI file:
|
||||||
|
|
||||||
|
```
|
||||||
|
[My Section]
|
||||||
|
filename = test1234
|
||||||
|
filename2 = number 2
|
||||||
|
filename3 = number 3
|
||||||
|
|
||||||
|
[Section 2]
|
||||||
|
var = 123
|
||||||
|
|
||||||
|
[Empty]
|
||||||
|
|
||||||
|
[last section]
|
||||||
|
bool = True
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting / Setting Entries
|
||||||
|
|
||||||
|
Just like the JSON files, you can access the individual settings using the UserSettings class by using the `[ ]` notation or by calling `get` and `set` methods.
|
||||||
|
|
||||||
|
The big difference with the INI file support is the addition of an extra lookup / parameter, the section name.
|
||||||
|
|
||||||
|
To access the entry `var` in section `Section 2`, you can use wither of these:
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['Section 2']['var']
|
||||||
|
settings['Section 2'].get('var', 'Default Value')
|
||||||
|
```
|
||||||
|
|
||||||
|
The advantage of using the `get` method is that if the entry is not present, a default value will be returned instead.
|
||||||
|
|
||||||
|
To set an entry, you also have 2 choices:
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['Section 2']['var'] = 'New Value'
|
||||||
|
settings['Section 2'].set('var', 'New Value')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessing INI File Sections
|
||||||
|
|
||||||
|
Once you have created your `UserSettings` object, then you'll be accessing entries using 2 keys instead of 1 like JSON uses.
|
||||||
|
|
||||||
|
To access an entire section, you'll write:
|
||||||
|
|
||||||
|
`settings['section']`
|
||||||
|
|
||||||
|
To get all of 'My Section' it will be:
|
||||||
|
|
||||||
|
`settings['My Section']` which returns a section object that behaves much like a dictionary.
|
||||||
|
|
||||||
|
To access a value within a section, add on one more lookup. To get the value of the `filename` setting in the `My Section` section, it's done with this code:
|
||||||
|
|
||||||
|
`settings['My Section']['filename']`
|
||||||
|
|
||||||
|
### Deleting Entries
|
||||||
|
|
||||||
|
To delete an individual entry, you can use several different techniques. One is to use `del`
|
||||||
|
|
||||||
|
```python
|
||||||
|
del settings['My Section1']['test']
|
||||||
|
```
|
||||||
|
|
||||||
|
This deletes the setting `test` in the section `My Section1`
|
||||||
|
|
||||||
|
You can also do this by calling the `delete_entry` method
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings.delete_entry(section='My Section1', key='test')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deleting Sections
|
||||||
|
|
||||||
|
If you want to delete an entire section, you have 2 methods for doing this. One is to call the method `UserSettings.delete_section` and pass in the name of the section to be deleted.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings.delete_section(section='My Section1')
|
||||||
|
```
|
||||||
|
|
||||||
|
The other is to lookup the section and then call `delete_section` on that section.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['My Section1'].delete_section()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Printing Settings for INI Files
|
||||||
|
|
||||||
|
If you print (or cast to a string) a section or a UserSettings object for an INI file, then you will get a nicely formated output that shows the sections and what settings are in each section.
|
||||||
|
|
||||||
|
Going back to the example INI file from earlier. Printing the UserSettings object for this file produces this output:
|
||||||
|
|
||||||
|
```
|
||||||
|
My Section:
|
||||||
|
filename : test1234
|
||||||
|
filename2 : number 2
|
||||||
|
filename3 : number 3
|
||||||
|
Section 2:
|
||||||
|
var : 123
|
||||||
|
Empty:
|
||||||
|
last section:
|
||||||
|
bool : True
|
||||||
|
```
|
||||||
|
|
||||||
|
### INI File Comments (WARNING)
|
||||||
|
|
||||||
|
If you have created an INI file using a test editor or it was created output of Python, then when the file is written, your comments will be stripped out. Code is being added to PySimpleGUI to merge back your comments, but the code isn't done yet. You'll either live with this limitation for now or write your own merge code.
|
||||||
|
|
||||||
|
Yea, I know, it's a bummer, but the plan is to overcome this Python limitation.
|
||||||
|
|
||||||
## Coding Convention for User Settings Keys
|
## Coding Convention for User Settings Keys
|
||||||
|
|
||||||
The User Settings prompted a new coding convention that's been added to PySimpleGUI examples. As you're likely aware, keys in layouts have the format `'-KEY-`'. For UserSettings, a similar format is used, but instead of the string being in all upper case, the characters are lower case. In the example below, the user setting for "filename" has a User Setting key of `'-filename-'`. Coding conventions are a good thing to have in your projects. You don't have to follow this one of course, but you're urged to create your own for places in your code that it makes sense. You could say that PEP8 is one giant coding convention for the Python language as a whole. You don't have to follow it, but most Python programmers do. We follow it "by convention".
|
The User Settings prompted a new coding convention that's been added to PySimpleGUI examples. As you're likely aware, keys in layouts have the format `'-KEY-`'. For UserSettings, a similar format is used, but instead of the string being in all upper case, the characters are lower case. In the example below, the user setting for "filename" has a User Setting key of `'-filename-'`. Coding conventions are a good thing to have in your projects. You don't have to follow this one of course, but you're urged to create your own for places in your code that it makes sense. You could say that PEP8 is one giant coding convention for the Python language as a whole. You don't have to follow it, but most Python programmers do. We follow it "by convention".
|
||||||
|
@ -6848,7 +7028,9 @@ Consider this is a ***stern warning***
|
||||||
|
|
||||||
Tkinter also wants to be the MAIN thread in your code. So, if you have to run multiple threads, make sure the GUI is the main thread.
|
Tkinter also wants to be the MAIN thread in your code. So, if you have to run multiple threads, make sure the GUI is the main thread.
|
||||||
|
|
||||||
Other than that, feel free to use threads with PySimpleGUI on all of the ports. You'll find a good example for how to run "long running tasks" in your event loop by looking at the demo program: `Demo_Multithreaded_Long_Tasks.py`. There are several examples of using threads with PySimpleGUI.
|
There is ONE (and only one?) safe call you can make into PySimpleGUI from a thread - `window.write_event_value`
|
||||||
|
|
||||||
|
There are several examples of using threads with PySimpleGUI. Use the Demo Programs! Use the Cookbook! They will give you an immediate and valuable jump start.
|
||||||
|
|
||||||
Be sure and **delete** your windows after you close them if you are running with multiple threads. There is a chance another thread's garbage collect will attempt to delete the window when not in the mainthread which will cause tkinter to crash.
|
Be sure and **delete** your windows after you close them if you are running with multiple threads. There is a chance another thread's garbage collect will attempt to delete the window when not in the mainthread which will cause tkinter to crash.
|
||||||
|
|
||||||
|
@ -6881,7 +7063,7 @@ The sequence looks like this in code:
|
||||||
gc.collect()
|
gc.collect()
|
||||||
```
|
```
|
||||||
|
|
||||||
This will ensure that the tkinter widgets are all deleted in the context of the main-thread and another thread won't accidently run the Garbage Collect
|
This will ensure that the tkinter widgets are all deleted in the context of the main-thread and another thread won't accidentally run the Garbage Collect
|
||||||
|
|
||||||
# Contributing to PySimpleGUI
|
# Contributing to PySimpleGUI
|
||||||
|
|
||||||
|
@ -9037,6 +9219,46 @@ Image element - Simpler to use
|
||||||
- Changed docstring for Multiline default value to Any and added a cast to string
|
- Changed docstring for Multiline default value to Any and added a cast to string
|
||||||
- Added more tests and information to the `sg.main()` test harness
|
- Added more tests and information to the `sg.main()` test harness
|
||||||
|
|
||||||
|
## 4.50.0 PySimpleGUI 17-Oct-2021
|
||||||
|
UserSettings API - support for .INI files
|
||||||
|
Listbox horizontal scrollbar
|
||||||
|
Column Element allow None for 1 size direction
|
||||||
|
|
||||||
|
* UserSettings API
|
||||||
|
* INI File Support
|
||||||
|
* Read access: `settings[section][key]`
|
||||||
|
Modify existing section and key: `settings[section][key] = new_value`
|
||||||
|
Create a new key in an existing section: `settings[section][new_key] = new_value`
|
||||||
|
Create a new section and key: `settings[new_section][new_key] = new_value`
|
||||||
|
Delete a section: `settings.delete_section(section)`
|
||||||
|
Save the INI file: `settings.save()`
|
||||||
|
* Available for UserSettings object only, not the function interface
|
||||||
|
* Demo Program released specific to .ini features
|
||||||
|
* Option to convert strings to Python values for True, False, None
|
||||||
|
* Added checks for running on Trinket or Replit so path can be set to "." if on either
|
||||||
|
* Added `running_replit` function. Returns True if environment is repl.it
|
||||||
|
* New option in set_options - `warn_button_key_duplicates` will show a warning if duplicate keys found on buttons. Defaults to OFF (duplicate key attempts on Buttons are common and OK)
|
||||||
|
* Right Click Menus
|
||||||
|
* New Element method `Element.set_right_click_menu`
|
||||||
|
* Enables changing a right click menu after initial window is created
|
||||||
|
* If none specified, uses the parent's menu
|
||||||
|
* Added `Window.get_size_accurate()` to get the window's size based on the geometry string from tkinter
|
||||||
|
* Removed moving of the theme color swatch preview window and allowed to center now
|
||||||
|
* Added check for bad value returned from tkinter when table clicked event happens
|
||||||
|
* Removed print when 8.6.9 ttk treeview code is patched
|
||||||
|
* Removed a debug print accidentally left in the bind code
|
||||||
|
* Listbox - added horizontal scrollbar option
|
||||||
|
* New `pin` layout helper function implementation (hopefully better, not worse)
|
||||||
|
* Column Element - Allow `None` to be used in any part of the `size`.
|
||||||
|
* If None used on width, then Column will default to width required by contents.
|
||||||
|
* If None used on height, then Column will default to width required by contents divided by 2
|
||||||
|
* These are same values as `(None, None)` today but can invidually control now.
|
||||||
|
* Made `Window.LayoutAndRead` deprication more user friendly with a popup
|
||||||
|
* Added * to the `file_types` default so that files without an extension are shown (only a problem on non-Windows systems). Default is now `(("ALL Files", "*.* *"),)`
|
||||||
|
* Changed `popup_get_file`, the Browse buttons, etc
|
||||||
|
* `FILE_TYPES_ALL_FILES` is a new constant with this value
|
||||||
|
* `popup_scrolled` added 1 line per argument to fit the contents better in some cases
|
||||||
|
|
||||||
## Code Condition
|
## Code Condition
|
||||||
|
|
||||||
Make it run
|
Make it run
|
||||||
|
|
|
@ -133,6 +133,54 @@ and returns the value input as well as the button clicked.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# 2021 Updates....
|
||||||
|
|
||||||
|
This documentation was originally written in 2018. So much has changed since, but the early stuff still runs just fine so there's not been a huge rush to update.
|
||||||
|
|
||||||
|
Some sections have been updated and added so it's not like this is a stale document.
|
||||||
|
|
||||||
|
## What's newer?
|
||||||
|
|
||||||
|
New APIs to save you time - not just for beginners
|
||||||
|
|
||||||
|
* Exec APIs (execution of subprocesses)
|
||||||
|
* User Settings APIs (management of settings in form of a dictionary)
|
||||||
|
* Threading API call - `write_event_value`
|
||||||
|
* True multiple windows support - `read_all_windows`
|
||||||
|
* System-wide global settings - theme, interpreter to use, Mac settings, ...
|
||||||
|
* Advanced error handling including launching your editor to line of code with error
|
||||||
|
* More advanced layouts - still trivial,maybe more trivial, to make windows
|
||||||
|
* Go wild - have a complicated (i.e. not simple) application... no problem here supporting your App. "It's on you". PSG solved the GUI problem, but you still have to make an application
|
||||||
|
* Docstrings - Tight integration with docstrings provides type checking and in-IDE documentation
|
||||||
|
* `sg.main` utilities - upgrade to the GitHub version in 1 click. Lots of good stuff built-into PySimpleGUI
|
||||||
|
* Demo Browser - Navigate the 315+ Demo Programs easily. Search, execute, edit all from one application
|
||||||
|
* Cookbook - There have been a number of updates in 2021
|
||||||
|
* This document has some sections new such as the User Settings APIs
|
||||||
|
|
||||||
|
### Dynamic Windows
|
||||||
|
|
||||||
|
- Making parts of windows expand/contract with the window.
|
||||||
|
- Swap out or collapse sections
|
||||||
|
- More parms in Elements to help with justification
|
||||||
|
- New `Push` & `VPush` Elements trivialize justification
|
||||||
|
|
||||||
|
|
||||||
|
### Threading
|
||||||
|
|
||||||
|
One simple call, `write_event_value`, solves threading issues.
|
||||||
|
|
||||||
|
Not ready for the threading module but need to run a thread? Use `window.perform_long_operation` to use threads. One call and done.
|
||||||
|
|
||||||
|
### What's Old?
|
||||||
|
|
||||||
|
The old parts of this documentation are the images. The good news is that things look better than you see here. Themes have made Windows colorful in 1 line of code.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### Looking for a GUI package? Are you...
|
#### Looking for a GUI package? Are you...
|
||||||
|
|
||||||
|
@ -304,11 +352,9 @@ PySimpleGUI runs on Windows, Linux and Mac, just like tkinter, Qt, WxPython and
|
||||||
|
|
||||||
As of 9/25/2018 **both Python 3 and Python 2.7 are supported** when using **tkinter version** of PySimpleGUI! The Python 3 version is named `PySimpleGUI`. The Python 2.7 version is `PySimpleGUI27`. They are installed separately and the imports are different. See instructions in Installation section for more info. **None** of the other ports can use Python 2.
|
As of 9/25/2018 **both Python 3 and Python 2.7 are supported** when using **tkinter version** of PySimpleGUI! The Python 3 version is named `PySimpleGUI`. The Python 2.7 version is `PySimpleGUI27`. They are installed separately and the imports are different. See instructions in Installation section for more info. **None** of the other ports can use Python 2.
|
||||||
|
|
||||||
###### Python 2.7 Code will be deleted from this GitHub on Dec 31, 2019
|
### Python 2.7 Code was be deleted from this GitHub on Dec 31, 2019
|
||||||
|
|
||||||
Note that the 2.7 port will *cease to exist on this GitHub* on Jan 1, 2020. If you would like to know how much time you have to move over to the Python 3 version of PySimpleGUI, then go here: https://pythonclock.org/. The only thing that will be available is an unsupported PyPI release of PySimpleGUI27.
|
At the suggestion of the Python community at large, the experts, and security folks, the support for 2.7 was pulled from this Repo.
|
||||||
|
|
||||||
By "will cease to exist on this GitHub" I mean, it will be deleted entirely. No source code, no supporting programs. Nothing. If you're stuck using 2.7 in December, it would behoove you to fork the 2.7 code on Dec 31, 2019. Legacy Python doesn't have a permanent home here. It sounds cruel, but experts in security particularly says 2.7 is a huge risk. Furthering it use only hurts the computing world.
|
|
||||||
|
|
||||||
#### Warning - tkinter + Python 3.7.3 and later, including 3.8 has problems
|
#### Warning - tkinter + Python 3.7.3 and later, including 3.8 has problems
|
||||||
|
|
||||||
|
@ -406,6 +452,14 @@ At the moment there are 4 actively developed and maintained "ports" of PySimpleG
|
||||||
While PySimpleGUI, the tkinter port, is the only 100% completed version of PySimpleGUI, the other 3 ports have a LOT of functionality in them and are in active use by a large portion of the installations. You can see the number of Pip installs at the very top of this document to get a comparison as to the size of the install base for each port. The "badges" are right after the logo.
|
While PySimpleGUI, the tkinter port, is the only 100% completed version of PySimpleGUI, the other 3 ports have a LOT of functionality in them and are in active use by a large portion of the installations. You can see the number of Pip installs at the very top of this document to get a comparison as to the size of the install base for each port. The "badges" are right after the logo.
|
||||||
|
|
||||||
|
|
||||||
|
## The Chain Link Fence
|
||||||
|
|
||||||
|
Maybe you've heard the "Walled Garden" term before. It's a boxing in effect.
|
||||||
|
|
||||||
|
While PySimpleGUI has a well-established parameter so you know where the edges are, there is no wall between you and the rest of the GUI framework. There's a chain link fence that's easy to reach through and get full access to the underlying frameworks.
|
||||||
|
|
||||||
|
The net result - it's easy to expand features that are not yet available in PySimpleGUI and easy to remove them too. Maybe the Listbox Element doesn't have a mode exposed that you want to enable. No problem, you can access the underlying Listbox Widget and make what is likely 1 or 2 calls and be done.
|
||||||
|
|
||||||
# The PySimpleGUI "Family"
|
# The PySimpleGUI "Family"
|
||||||
|
|
||||||
## What's The Big Deal? What is it?
|
## What's The Big Deal? What is it?
|
||||||
|
|
|
@ -4612,13 +4612,15 @@ Exception module 'tkinter' has no attribute '__version__'
|
||||||
|
|
||||||
# User Settings API
|
# User Settings API
|
||||||
|
|
||||||
In release 4.30.0 there is a new set of API calls available to help with "user settings". Think of user settings as a dictionary that is automatically written to your hard drive. That's basically what it is. Underpinning the code is the JSON package provided by Python.
|
In release 4.30.0 there is a new set of API calls available to help with "user settings". Think of user settings as a dictionary that is automatically written to your hard drive. That's basically what it is.
|
||||||
|
|
||||||
While using JSON files to save and load a settings dictionary isn't very difficult, it is still code you'll need to write if you want to save settings as part of your GUI. Since having "settings" for a GUI based program isn't uncommon, it made sense to build this capability into PySimpleGUI. Clearly you can still use your own method for saving settings, but if you're looking for a simple and easy way to do it, these calls are likely about as easy as it gets.
|
In release 4.50.0 support for INI files was added in addition to the existing JSON file format.
|
||||||
|
|
||||||
|
While using JSON or config files to save and load a settings dictionary isn't very difficult, it is still code you'll need to write if you want to save settings as part of your GUI. Since having "settings" for a GUI based program isn't uncommon, it made sense to build this capability into PySimpleGUI. Clearly you can still use your own method for saving settings, but if you're looking for a simple and easy way to do it, these calls are likely about as easy as it gets.
|
||||||
|
|
||||||
There have already been some demo programs written that use JSON files to store settings. You can expect that this capability will begin to show up in more demos in the future since it's now part of PySimpleGUI.
|
There have already been some demo programs written that use JSON files to store settings. You can expect that this capability will begin to show up in more demos in the future since it's now part of PySimpleGUI.
|
||||||
|
|
||||||
User settings are stored in a Python dictionary which is saved to / loaded from disk. Individual settings are thus keys into a dictionary. You do not need to explicitly read nor write the file. Changing any entry will cause the file to be saved. Reading any entry will cause the file to be read if it hasn't already been read.
|
User settings are stored in a Python dictionary which is saved to / loaded from disk. Individual settings are thus keys into a dictionary. **You do not need to explicitly read nor write the file**. Changing any entry will cause the file to be saved. Reading any entry will cause the file to be read if it hasn't already been read.
|
||||||
|
|
||||||
## Two Interfaces
|
## Two Interfaces
|
||||||
|
|
||||||
|
@ -4629,6 +4631,7 @@ There are 2 ways to access User Settings
|
||||||
|
|
||||||
They both offer the same basic operations. The class interface has an added benefit of being able to access the individual settings using the same syntax as Python dictionary.
|
They both offer the same basic operations. The class interface has an added benefit of being able to access the individual settings using the same syntax as Python dictionary.
|
||||||
|
|
||||||
|
If you want to use INI files, then you'll need to use the object interface.
|
||||||
|
|
||||||
## List of Calls for Function Interface
|
## List of Calls for Function Interface
|
||||||
|
|
||||||
|
@ -4881,7 +4884,7 @@ in main
|
||||||
|
|
||||||
You should be able to easily figure out these errors as they are file operations and the error messages are clear in detailing what's happened and where the call originated.
|
You should be able to easily figure out these errors as they are file operations and the error messages are clear in detailing what's happened and where the call originated.
|
||||||
|
|
||||||
### Silenting the Errors
|
### Silencing the Errors
|
||||||
|
|
||||||
If you're the type that doesn't want to see any error messages printed out on your console, then you can silence the error output.
|
If you're the type that doesn't want to see any error messages printed out on your console, then you can silence the error output.
|
||||||
|
|
||||||
|
@ -4890,6 +4893,139 @@ When using the class interface, there is a parameter `silent_on_error` that you
|
||||||
For the function interface, call the function `user_settings_silent_on_error()` and set the parameter to `True`
|
For the function interface, call the function `user_settings_silent_on_error()` and set the parameter to `True`
|
||||||
|
|
||||||
|
|
||||||
|
## Config INI File Support
|
||||||
|
|
||||||
|
Using INI files has some advantages over JSON, particularly when humans are going to be modifying the settings files directly.
|
||||||
|
|
||||||
|
To specify use of INI files instead of JSON, set the parameter `use_config_file=True` when creating your `UserSetting` object.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings = sg.UserSettings('my_config.ini', use_config_file=True, convert_bools_and_none=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the 2 parameters that are specific for .ini files:
|
||||||
|
* `use_config_file` - Set to `True` to indicate you're using an INI file
|
||||||
|
* `convert_bools_and_none` - Defaults to `True`. Normally all settings from INI files are strings. This parameter will convert 'True', 'False', and 'None' to Python values `True`, `False`, `None`
|
||||||
|
|
||||||
|
There is also an additional method added `delete_section` which will delete an entire section from your INI file.
|
||||||
|
|
||||||
|
### Example File
|
||||||
|
|
||||||
|
Let's use this as our example INI file:
|
||||||
|
|
||||||
|
```
|
||||||
|
[My Section]
|
||||||
|
filename = test1234
|
||||||
|
filename2 = number 2
|
||||||
|
filename3 = number 3
|
||||||
|
|
||||||
|
[Section 2]
|
||||||
|
var = 123
|
||||||
|
|
||||||
|
[Empty]
|
||||||
|
|
||||||
|
[last section]
|
||||||
|
bool = True
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Getting / Setting Entries
|
||||||
|
|
||||||
|
Just like the JSON files, you can access the individual settings using the UserSettings class by using the `[ ]` notation or by calling `get` and `set` methods.
|
||||||
|
|
||||||
|
The big difference with the INI file support is the addition of an extra lookup / parameter, the section name.
|
||||||
|
|
||||||
|
To access the entry `var` in section `Section 2`, you can use wither of these:
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['Section 2']['var']
|
||||||
|
settings['Section 2'].get('var', 'Default Value')
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
The advantage of using the `get` method is that if the entry is not present, a default value will be returned instead.
|
||||||
|
|
||||||
|
To set an entry, you also have 2 choices:
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['Section 2']['var'] = 'New Value'
|
||||||
|
settings['Section 2'].set('var', 'New Value')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessing INI File Sections
|
||||||
|
|
||||||
|
Once you have created your `UserSettings` object, then you'll be accessing entries using 2 keys instead of 1 like JSON uses.
|
||||||
|
|
||||||
|
|
||||||
|
To access an entire section, you'll write:
|
||||||
|
|
||||||
|
`settings['section']`
|
||||||
|
|
||||||
|
To get all of 'My Section' it will be:
|
||||||
|
|
||||||
|
`settings['My Section']` which returns a section object that behaves much like a dictionary.
|
||||||
|
|
||||||
|
To access a value within a section, add on one more lookup. To get the value of the `filename` setting in the `My Section` section, it's done with this code:
|
||||||
|
|
||||||
|
`settings['My Section']['filename']`
|
||||||
|
|
||||||
|
### Deleting Entries
|
||||||
|
|
||||||
|
To delete an individual entry, you can use several different techniques. One is to use `del`
|
||||||
|
|
||||||
|
```python
|
||||||
|
del settings['My Section1']['test']
|
||||||
|
```
|
||||||
|
|
||||||
|
This deletes the setting `test` in the section `My Section1`
|
||||||
|
|
||||||
|
You can also do this by calling the `delete_entry` method
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings.delete_entry(section='My Section1', key='test')
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Deleting Sections
|
||||||
|
|
||||||
|
If you want to delete an entire section, you have 2 methods for doing this. One is to call the method `UserSettings.delete_section` and pass in the name of the section to be deleted.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings.delete_section(section='My Section1')
|
||||||
|
```
|
||||||
|
|
||||||
|
The other is to lookup the section and then call `delete_section` on that section.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['My Section1'].delete_section()
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Printing Settings for INI Files
|
||||||
|
|
||||||
|
If you print (or cast to a string) a section or a UserSettings object for an INI file, then you will get a nicely formated output that shows the sections and what settings are in each section.
|
||||||
|
|
||||||
|
Going back to the example INI file from earlier. Printing the UserSettings object for this file produces this output:
|
||||||
|
|
||||||
|
```
|
||||||
|
My Section:
|
||||||
|
filename : test1234
|
||||||
|
filename2 : number 2
|
||||||
|
filename3 : number 3
|
||||||
|
Section 2:
|
||||||
|
var : 123
|
||||||
|
Empty:
|
||||||
|
last section:
|
||||||
|
bool : True
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### INI File Comments (WARNING)
|
||||||
|
|
||||||
|
If you have created an INI file using a test editor or it was created output of Python, then when the file is written, your comments will be stripped out. Code is being added to PySimpleGUI to merge back your comments, but the code isn't done yet. You'll either live with this limitation for now or write your own merge code.
|
||||||
|
|
||||||
|
Yea, I know, it's a bummer, but the plan is to overcome this Python limitation.
|
||||||
|
|
||||||
## Coding Convention for User Settings Keys
|
## Coding Convention for User Settings Keys
|
||||||
|
|
||||||
The User Settings prompted a new coding convention that's been added to PySimpleGUI examples. As you're likely aware, keys in layouts have the format `'-KEY-`'. For UserSettings, a similar format is used, but instead of the string being in all upper case, the characters are lower case. In the example below, the user setting for "filename" has a User Setting key of `'-filename-'`. Coding conventions are a good thing to have in your projects. You don't have to follow this one of course, but you're urged to create your own for places in your code that it makes sense. You could say that PEP8 is one giant coding convention for the Python language as a whole. You don't have to follow it, but most Python programmers do. We follow it "by convention".
|
The User Settings prompted a new coding convention that's been added to PySimpleGUI examples. As you're likely aware, keys in layouts have the format `'-KEY-`'. For UserSettings, a similar format is used, but instead of the string being in all upper case, the characters are lower case. In the example below, the user setting for "filename" has a User Setting key of `'-filename-'`. Coding conventions are a good thing to have in your projects. You don't have to follow this one of course, but you're urged to create your own for places in your code that it makes sense. You could say that PEP8 is one giant coding convention for the Python language as a whole. You don't have to follow it, but most Python programmers do. We follow it "by convention".
|
||||||
|
|
|
@ -249,7 +249,9 @@ Consider this is a ***stern warning***
|
||||||
|
|
||||||
Tkinter also wants to be the MAIN thread in your code. So, if you have to run multiple threads, make sure the GUI is the main thread.
|
Tkinter also wants to be the MAIN thread in your code. So, if you have to run multiple threads, make sure the GUI is the main thread.
|
||||||
|
|
||||||
Other than that, feel free to use threads with PySimpleGUI on all of the ports. You'll find a good example for how to run "long running tasks" in your event loop by looking at the demo program: `Demo_Multithreaded_Long_Tasks.py`. There are several examples of using threads with PySimpleGUI.
|
There is ONE (and only one?) safe call you can make into PySimpleGUI from a thread - `window.write_event_value`
|
||||||
|
|
||||||
|
There are several examples of using threads with PySimpleGUI. Use the Demo Programs! Use the Cookbook! They will give you an immediate and valuable jump start.
|
||||||
|
|
||||||
Be sure and **delete** your windows after you close them if you are running with multiple threads. There is a chance another thread's garbage collect will attempt to delete the window when not in the mainthread which will cause tkinter to crash.
|
Be sure and **delete** your windows after you close them if you are running with multiple threads. There is a chance another thread's garbage collect will attempt to delete the window when not in the mainthread which will cause tkinter to crash.
|
||||||
|
|
||||||
|
@ -282,7 +284,7 @@ The sequence looks like this in code:
|
||||||
gc.collect()
|
gc.collect()
|
||||||
```
|
```
|
||||||
|
|
||||||
This will ensure that the tkinter widgets are all deleted in the context of the main-thread and another thread won't accidently run the Garbage Collect
|
This will ensure that the tkinter widgets are all deleted in the context of the main-thread and another thread won't accidentally run the Garbage Collect
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2184,6 +2184,48 @@ Image element - Simpler to use
|
||||||
- Changed docstring for Multiline default value to Any and added a cast to string
|
- Changed docstring for Multiline default value to Any and added a cast to string
|
||||||
- Added more tests and information to the `sg.main()` test harness
|
- Added more tests and information to the `sg.main()` test harness
|
||||||
|
|
||||||
|
|
||||||
|
## 4.50.0 PySimpleGUI 17-Oct-2021
|
||||||
|
UserSettings API - support for .INI files
|
||||||
|
Listbox horizontal scrollbar
|
||||||
|
Column Element allow None for 1 size direction
|
||||||
|
|
||||||
|
* UserSettings API
|
||||||
|
* INI File Support
|
||||||
|
* Read access: `settings[section][key]`
|
||||||
|
Modify existing section and key: `settings[section][key] = new_value`
|
||||||
|
Create a new key in an existing section: `settings[section][new_key] = new_value`
|
||||||
|
Create a new section and key: `settings[new_section][new_key] = new_value`
|
||||||
|
Delete a section: `settings.delete_section(section)`
|
||||||
|
Save the INI file: `settings.save()`
|
||||||
|
* Available for UserSettings object only, not the function interface
|
||||||
|
* Demo Program released specific to .ini features
|
||||||
|
* Option to convert strings to Python values for True, False, None
|
||||||
|
* Added checks for running on Trinket or Replit so path can be set to "." if on either
|
||||||
|
* Added `running_replit` function. Returns True if environment is repl.it
|
||||||
|
* New option in set_options - `warn_button_key_duplicates` will show a warning if duplicate keys found on buttons. Defaults to OFF (duplicate key attempts on Buttons are common and OK)
|
||||||
|
* Right Click Menus
|
||||||
|
* New Element method `Element.set_right_click_menu`
|
||||||
|
* Enables changing a right click menu after initial window is created
|
||||||
|
* If none specified, uses the parent's menu
|
||||||
|
* Added `Window.get_size_accurate()` to get the window's size based on the geometry string from tkinter
|
||||||
|
* Removed moving of the theme color swatch preview window and allowed to center now
|
||||||
|
* Added check for bad value returned from tkinter when table clicked event happens
|
||||||
|
* Removed print when 8.6.9 ttk treeview code is patched
|
||||||
|
* Removed a debug print accidentally left in the bind code
|
||||||
|
* Listbox - added horizontal scrollbar option
|
||||||
|
* New `pin` layout helper function implementation (hopefully better, not worse)
|
||||||
|
* Column Element - Allow `None` to be used in any part of the `size`.
|
||||||
|
* If None used on width, then Column will default to width required by contents.
|
||||||
|
* If None used on height, then Column will default to width required by contents divided by 2
|
||||||
|
* These are same values as `(None, None)` today but can invidually control now.
|
||||||
|
* Made `Window.LayoutAndRead` deprication more user friendly with a popup
|
||||||
|
* Added * to the `file_types` default so that files without an extension are shown (only a problem on non-Windows systems). Default is now `(("ALL Files", "*.* *"),)`
|
||||||
|
* Changed `popup_get_file`, the Browse buttons, etc
|
||||||
|
* `FILE_TYPES_ALL_FILES` is a new constant with this value
|
||||||
|
* `popup_scrolled` added 1 line per argument to fit the contents better in some cases
|
||||||
|
|
||||||
|
|
||||||
## Code Condition
|
## Code Condition
|
||||||
|
|
||||||
Make it run
|
Make it run
|
||||||
|
|
|
@ -2490,6 +2490,11 @@ The following methods are here for backwards compatibility reference. You will
|
||||||
### delete_file
|
### delete_file
|
||||||
<!-- <+UserSettings.delete_file+> -->
|
<!-- <+UserSettings.delete_file+> -->
|
||||||
|
|
||||||
|
|
||||||
|
### delete_section
|
||||||
|
<!-- <+UserSettings.delete_section+> -->
|
||||||
|
|
||||||
|
|
||||||
### exists
|
### exists
|
||||||
<!-- <+UserSettings.exists+> -->
|
<!-- <+UserSettings.exists+> -->
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ Button(button_text = "",
|
||||||
button_type = 7,
|
button_type = 7,
|
||||||
target = (None, None),
|
target = (None, None),
|
||||||
tooltip = None,
|
tooltip = None,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
disabled = False,
|
disabled = False,
|
||||||
|
@ -83,7 +83,7 @@ Parameter Descriptions:
|
||||||
| int | button_type | You should NOT be setting this directly. ONLY the shortcut functions set this |
|
| int | button_type | You should NOT be setting this directly. ONLY the shortcut functions set this |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button |
|
| str or (int, int) | target | key or (row,col) target for the button. Note that -1 for column means 1 element to the left of this one. The constant ThisRow is used to indicate the current row. The Button itself is a valid target for some types of button |
|
||||||
| str | tooltip | text, that will appear when mouse hovers over the element |
|
| str | tooltip | text, that will appear when mouse hovers over the element |
|
||||||
| Tuple[(str, str), ...] | file_types | the filetypes that will be used to match files. To indicate all files: (("ALL Files", "*.*"),). Note - NOT SUPPORTED ON MAC |
|
| Tuple[(str, str), ...] | file_types | the filetypes that will be used to match files. To indicate all files: (("ALL Files", "*.* *"),). Note - NOT SUPPORTED ON MAC |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| (bool or str) | disabled | If True button will be created disabled. If BUTTON_DISABLED_MEANS_IGNORE then the button will be ignored rather than disabled using tkinter |
|
| (bool or str) | disabled | If True button will be created disabled. If BUTTON_DISABLED_MEANS_IGNORE then the button will be ignored rather than disabled using tkinter |
|
||||||
|
@ -1482,8 +1482,8 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| List[List[Element]] | layout | Layout that will be shown in the Column container |
|
| List[List[Element]] | layout | Layout that will be shown in the Column container |
|
||||||
| str | background_color | color of background of entire Column |
|
| str | background_color | color of background of entire Column |
|
||||||
| (int, int) | size | (width, height) size in pixels (doesn't work quite right, sometimes only 1 dimension is set by tkinter. Use a Sizer Element to help set sizes |
|
| (int or None, int or None) | size | (width, height) size in pixels (doesn't work quite right, sometimes only 1 dimension is set by tkinter. Use a Sizer Element to help set sizes |
|
||||||
| (int, int) or (None, None) | s | Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used |
|
| (int or None, int or None) | s | Same as size parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, size will be used |
|
||||||
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | pad | Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int) |
|
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | pad | Amount of padding to put around element in pixels (left/right, top/bottom) or ((left, right), (top, bottom)) or an int. If an int, then it's converted into a tuple (int, int) |
|
||||||
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | p | Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used |
|
| (int, int or (int, int),(int,int) or int,(int,int)) or ((int, int),int) or int | p | Same as pad parameter. It's an alias. If EITHER of them are set, then the one that's set will be used. If BOTH are set, pad will be used |
|
||||||
| bool | scrollable | if True then scrollbars will be added to the column |
|
| bool | scrollable | if True then scrollbars will be added to the column |
|
||||||
|
@ -4628,6 +4628,7 @@ Listbox(values,
|
||||||
auto_size_text = None,
|
auto_size_text = None,
|
||||||
font = None,
|
font = None,
|
||||||
no_scrollbar = False,
|
no_scrollbar = False,
|
||||||
|
horizontal_scroll = False,
|
||||||
background_color = None,
|
background_color = None,
|
||||||
text_color = None,
|
text_color = None,
|
||||||
highlight_background_color = None,
|
highlight_background_color = None,
|
||||||
|
@ -4660,6 +4661,7 @@ Parameter Descriptions:
|
||||||
| bool | auto_size_text | True if element should be the same size as the contents |
|
| bool | auto_size_text | True if element should be the same size as the contents |
|
||||||
| (str or (str, int[, str]) or None) | font | specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike |
|
| (str or (str, int[, str]) or None) | font | specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike |
|
||||||
| bool | no_scrollbar | Controls if a scrollbar should be shown. If True, no scrollbar will be shown |
|
| bool | no_scrollbar | Controls if a scrollbar should be shown. If True, no scrollbar will be shown |
|
||||||
|
| bool | horizontal_scroll | Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical |
|
||||||
| str | background_color | color of background |
|
| str | background_color | color of background |
|
||||||
| str | text_color | color of the text |
|
| str | text_color | color of the text |
|
||||||
| str | highlight_background_color | color of the background when an item is selected. Defaults to normal text color (a reverse look) |
|
| str | highlight_background_color | color of the background when an item is selected. Defaults to normal text color (a reverse look) |
|
||||||
|
@ -11102,7 +11104,9 @@ User Settings
|
||||||
UserSettings(filename = None,
|
UserSettings(filename = None,
|
||||||
path = None,
|
path = None,
|
||||||
silent_on_error = False,
|
silent_on_error = False,
|
||||||
autosave = True)
|
autosave = True,
|
||||||
|
use_config_file = None,
|
||||||
|
convert_bools_and_none = True)
|
||||||
```
|
```
|
||||||
|
|
||||||
Parameter Descriptions:
|
Parameter Descriptions:
|
||||||
|
@ -11113,6 +11117,8 @@ Parameter Descriptions:
|
||||||
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
||||||
| bool | silent_on_error | If True errors will not be reported |
|
| bool | silent_on_error | If True errors will not be reported |
|
||||||
| bool | autosave | If True the settings file is saved after every update |
|
| bool | autosave | If True the settings file is saved after every update |
|
||||||
|
| bool | use_config_file | If True then the file format will be a config.ini rather than json |
|
||||||
|
| bool | convert_bools_and_none | If True then "True", "False", "None" will be converted to the Python values True, False, None when using INI files. Default is TRUE |
|
||||||
|
|
||||||
### delete_entry
|
### delete_entry
|
||||||
|
|
||||||
|
@ -11121,7 +11127,7 @@ then a default filename will be used.
|
||||||
After value has been deleted, the settings file is written to disk.
|
After value has been deleted, the settings file is written to disk.
|
||||||
|
|
||||||
```
|
```
|
||||||
delete_entry(key)
|
delete_entry(key, section = None)
|
||||||
```
|
```
|
||||||
|
|
||||||
Parameter Descriptions:
|
Parameter Descriptions:
|
||||||
|
@ -11149,6 +11155,20 @@ Parameter Descriptions:
|
||||||
| (str or None) | filename | The name of the file to use. Can be a full path and filename or just filename |
|
| (str or None) | filename | The name of the file to use. Can be a full path and filename or just filename |
|
||||||
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
| (str or None) | path | The folder that the settings file will be stored in. Do not include the filename. |
|
||||||
|
|
||||||
|
### delete_section
|
||||||
|
|
||||||
|
Deletes a section with the name provided in the section parameter. Your INI file will be saved afterwards if auto-save enabled (default is ON)
|
||||||
|
|
||||||
|
```
|
||||||
|
delete_section(section)
|
||||||
|
```
|
||||||
|
|
||||||
|
Parameter Descriptions:
|
||||||
|
|
||||||
|
|Type|Name|Meaning|
|
||||||
|
|--|--|--|
|
||||||
|
| str | section | Name of the section to delete |
|
||||||
|
|
||||||
### exists
|
### exists
|
||||||
|
|
||||||
Check if a particular settings file exists. Returns True if file exists
|
Check if a particular settings file exists. Returns True if file exists
|
||||||
|
@ -11241,6 +11261,7 @@ Parameter Descriptions:
|
||||||
### read
|
### read
|
||||||
|
|
||||||
Reads settings file and returns the dictionary.
|
Reads settings file and returns the dictionary.
|
||||||
|
If you have anything changed in an existing settings dictionary, you will lose your changes.
|
||||||
|
|
||||||
`read()`
|
`read()`
|
||||||
|
|
||||||
|
@ -11270,6 +11291,8 @@ Parameter Descriptions:
|
||||||
Sets an individual setting to the specified value. If no filename has been specified up to this point,
|
Sets an individual setting to the specified value. If no filename has been specified up to this point,
|
||||||
then a default filename will be used.
|
then a default filename will be used.
|
||||||
After value has been modified, the settings file is written to disk.
|
After value has been modified, the settings file is written to disk.
|
||||||
|
Note that this call is not value for a config file normally. If it is, then the key is assumed to be the
|
||||||
|
Section key and the value written will be the default value.
|
||||||
|
|
||||||
```
|
```
|
||||||
set(key, value)
|
set(key, value)
|
||||||
|
@ -11281,7 +11304,6 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| Any | key | Setting to be saved. Can be any valid dictionary key type |
|
| Any | key | Setting to be saved. Can be any valid dictionary key type |
|
||||||
| Any | value | Value to save as the setting's value. Can be anything |
|
| Any | value | Value to save as the setting's value. Can be anything |
|
||||||
| bool | autosave | If True then the value will be saved to the file |
|
|
||||||
| (Any) | **RETURN** | value that key was set to
|
| (Any) | **RETURN** | value that key was set to
|
||||||
|
|
||||||
### set_default_value
|
### set_default_value
|
||||||
|
@ -13245,7 +13267,7 @@ Parameter Descriptions:
|
||||||
```
|
```
|
||||||
FileBrowse(button_text = "Browse",
|
FileBrowse(button_text = "Browse",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
tooltip = None,
|
tooltip = None,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
|
@ -13269,7 +13291,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Browse') |
|
| str | button_text | text in the button (Default value = 'Browse') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | filter file types (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | filter file types (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| | initial_folder | starting path for folders and files |
|
| | initial_folder | starting path for folders and files |
|
||||||
| str | tooltip | text, that will appear when mouse hovers over the element |
|
| str | tooltip | text, that will appear when mouse hovers over the element |
|
||||||
| (int, int) | size | (w,h) w=characters-wide, h=rows-high |
|
| (int, int) | size | (w,h) w=characters-wide, h=rows-high |
|
||||||
|
@ -13290,7 +13312,7 @@ Parameter Descriptions:
|
||||||
```
|
```
|
||||||
FileSaveAs(button_text = "Save As...",
|
FileSaveAs(button_text = "Save As...",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
disabled = False,
|
disabled = False,
|
||||||
|
@ -13315,7 +13337,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Save As...') |
|
| str | button_text | text in the button (Default value = 'Save As...') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| bool | disabled | set disable state for element (Default = False) |
|
| bool | disabled | set disable state for element (Default = False) |
|
||||||
|
@ -13339,7 +13361,7 @@ Allows browsing of multiple files. File list is returned as a single list with t
|
||||||
```
|
```
|
||||||
FilesBrowse(button_text = "Browse",
|
FilesBrowse(button_text = "Browse",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
disabled = False,
|
disabled = False,
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
tooltip = None,
|
tooltip = None,
|
||||||
|
@ -13364,7 +13386,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Browse') |
|
| str | button_text | text in the button (Default value = 'Browse') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| bool | disabled | set disable state for element (Default = False) |
|
| bool | disabled | set disable state for element (Default = False) |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| str | tooltip | text, that will appear when mouse hovers over the element |
|
| str | tooltip | text, that will appear when mouse hovers over the element |
|
||||||
|
@ -13779,7 +13801,7 @@ Parameter Descriptions:
|
||||||
```
|
```
|
||||||
SaveAs(button_text = "Save As...",
|
SaveAs(button_text = "Save As...",
|
||||||
target = (555666777, -1),
|
target = (555666777, -1),
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
initial_folder = None,
|
initial_folder = None,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
disabled = False,
|
disabled = False,
|
||||||
|
@ -13804,7 +13826,7 @@ Parameter Descriptions:
|
||||||
|--|--|--|
|
|--|--|--|
|
||||||
| str | button_text | text in the button (Default value = 'Save As...') |
|
| str | button_text | text in the button (Default value = 'Save As...') |
|
||||||
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
| str or (int, int) | target | key or (row,col) target for the button (Default value = (ThisRow, -1)) |
|
||||||
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.*"))) |
|
| Tuple[(str, str), ...] | file_types | (Default value = (("ALL Files", "*.* *"))) |
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| str | initial_folder | starting path for folders and files |
|
| str | initial_folder | starting path for folders and files |
|
||||||
| bool | disabled | set disable state for element (Default = False) |
|
| bool | disabled | set disable state for element (Default = False) |
|
||||||
|
@ -14860,7 +14882,7 @@ popup_get_file(message,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
save_as = False,
|
save_as = False,
|
||||||
multiple_files = False,
|
multiple_files = False,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
no_window = False,
|
no_window = False,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
button_color = None,
|
button_color = None,
|
||||||
|
@ -14891,7 +14913,7 @@ Parameter Descriptions:
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
||||||
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
||||||
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) |
|
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.* *"),) |
|
||||||
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
||||||
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
||||||
| (str, str) or str | button_color | Color of the button (text, background) |
|
| (str, str) or str | button_color | Color of the button (text, background) |
|
||||||
|
@ -15863,7 +15885,7 @@ PopupGetFile(message,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
save_as = False,
|
save_as = False,
|
||||||
multiple_files = False,
|
multiple_files = False,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
no_window = False,
|
no_window = False,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
button_color = None,
|
button_color = None,
|
||||||
|
@ -15894,7 +15916,7 @@ Parameter Descriptions:
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
||||||
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
||||||
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) |
|
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.* *"),) |
|
||||||
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
||||||
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
||||||
| (str, str) or str | button_color | Color of the button (text, background) |
|
| (str, str) or str | button_color | Color of the button (text, background) |
|
||||||
|
@ -17470,6 +17492,7 @@ set_options(icon = None,
|
||||||
suppress_error_popups = None,
|
suppress_error_popups = None,
|
||||||
suppress_raise_key_errors = None,
|
suppress_raise_key_errors = None,
|
||||||
suppress_key_guessing = None,
|
suppress_key_guessing = None,
|
||||||
|
warn_button_key_duplicates = False,
|
||||||
enable_treeview_869_patch = None,
|
enable_treeview_869_patch = None,
|
||||||
enable_mac_notitlebar_patch = None,
|
enable_mac_notitlebar_patch = None,
|
||||||
use_custom_titlebar = None,
|
use_custom_titlebar = None,
|
||||||
|
@ -17526,6 +17549,7 @@ Parameter Descriptions:
|
||||||
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
||||||
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
||||||
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
||||||
|
| bool | warn_button_key_duplicates | If True then duplicate Button Keys generate warnings (not recommended as they're expected) |
|
||||||
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
||||||
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
||||||
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
||||||
|
@ -17594,6 +17618,7 @@ SetOptions(icon = None,
|
||||||
suppress_error_popups = None,
|
suppress_error_popups = None,
|
||||||
suppress_raise_key_errors = None,
|
suppress_raise_key_errors = None,
|
||||||
suppress_key_guessing = None,
|
suppress_key_guessing = None,
|
||||||
|
warn_button_key_duplicates = False,
|
||||||
enable_treeview_869_patch = None,
|
enable_treeview_869_patch = None,
|
||||||
enable_mac_notitlebar_patch = None,
|
enable_mac_notitlebar_patch = None,
|
||||||
use_custom_titlebar = None,
|
use_custom_titlebar = None,
|
||||||
|
@ -17650,6 +17675,7 @@ Parameter Descriptions:
|
||||||
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
| bool | suppress_error_popups | If True then error popups will not be shown if generated internally to PySimpleGUI |
|
||||||
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
| bool | suppress_raise_key_errors | If True then key errors won't be raised (you'll still get popup error) |
|
||||||
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
| bool | suppress_key_guessing | If True then key errors won't try and find closest matches for you |
|
||||||
|
| bool | warn_button_key_duplicates | If True then duplicate Button Keys generate warnings (not recommended as they're expected) |
|
||||||
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
| bool | enable_treeview_869_patch | If True, then will use the treeview color patch for tk 8.6.9 |
|
||||||
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
| bool | enable_mac_notitlebar_patch | If True then Windows with no titlebar use an alternative technique when tkinter version < 8.6.10 |
|
||||||
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
| bool | use_custom_titlebar | If True then a custom titlebar is used instead of the normal system titlebar |
|
||||||
|
|
|
@ -90,6 +90,49 @@ and returns the value input as well as the button clicked.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
# 2021 Updates....
|
||||||
|
|
||||||
|
This documentation was originally written in 2018. So much has changed since, but the early stuff still runs just fine so there's not been a huge rush to update.
|
||||||
|
|
||||||
|
Some sections have been updated and added so it's not like this is a stale document.
|
||||||
|
|
||||||
|
## What's newer?
|
||||||
|
|
||||||
|
New APIs to save you time - not just for beginners
|
||||||
|
|
||||||
|
* Exec APIs (execution of subprocesses)
|
||||||
|
* User Settings APIs (management of settings in form of a dictionary)
|
||||||
|
* Threading API call - `write_event_value`
|
||||||
|
* True multiple windows support - `read_all_windows`
|
||||||
|
* System-wide global settings - theme, interpreter to use, Mac settings, ...
|
||||||
|
* Advanced error handling including launching your editor to line of code with error
|
||||||
|
* More advanced layouts - still trivial,maybe more trivial, to make windows
|
||||||
|
* Go wild - have a complicated (i.e. not simple) application... no problem here supporting your App. "It's on you". PSG solved the GUI problem, but you still have to make an application
|
||||||
|
* Docstrings - Tight integration with docstrings provides type checking and in-IDE documentation
|
||||||
|
* `sg.main` utilities - upgrade to the GitHub version in 1 click. Lots of good stuff built-into PySimpleGUI
|
||||||
|
* Demo Browser - Navigate the 315+ Demo Programs easily. Search, execute, edit all from one application
|
||||||
|
* Cookbook - There have been a number of updates in 2021
|
||||||
|
* This document has some sections new such as the User Settings APIs
|
||||||
|
|
||||||
|
### Dynamic Windows
|
||||||
|
|
||||||
|
- Making parts of windows expand/contract with the window.
|
||||||
|
- Swap out or collapse sections
|
||||||
|
- More parms in Elements to help with justification
|
||||||
|
- New `Push` & `VPush` Elements trivialize justification
|
||||||
|
|
||||||
|
### Threading
|
||||||
|
|
||||||
|
One simple call, `write_event_value`, solves threading issues.
|
||||||
|
|
||||||
|
Not ready for the threading module but need to run a thread? Use `window.perform_long_operation` to use threads. One call and done.
|
||||||
|
|
||||||
|
### What's Old?
|
||||||
|
|
||||||
|
The old parts of this documentation are the images. The good news is that things look better than you see here. Themes have made Windows colorful in 1 line of code.
|
||||||
|
|
||||||
|
------------------
|
||||||
|
|
||||||
#### Looking for a GUI package? Are you...
|
#### Looking for a GUI package? Are you...
|
||||||
|
|
||||||
* looking to take your Python code from the world of command lines and into the convenience of a GUI?
|
* looking to take your Python code from the world of command lines and into the convenience of a GUI?
|
||||||
|
@ -254,11 +297,9 @@ PySimpleGUI runs on Windows, Linux and Mac, just like tkinter, Qt, WxPython and
|
||||||
|
|
||||||
As of 9/25/2018 **both Python 3 and Python 2.7 are supported** when using **tkinter version** of PySimpleGUI! The Python 3 version is named `PySimpleGUI`. The Python 2.7 version is `PySimpleGUI27`. They are installed separately and the imports are different. See instructions in Installation section for more info. **None** of the other ports can use Python 2.
|
As of 9/25/2018 **both Python 3 and Python 2.7 are supported** when using **tkinter version** of PySimpleGUI! The Python 3 version is named `PySimpleGUI`. The Python 2.7 version is `PySimpleGUI27`. They are installed separately and the imports are different. See instructions in Installation section for more info. **None** of the other ports can use Python 2.
|
||||||
|
|
||||||
###### Python 2.7 Code will be deleted from this GitHub on Dec 31, 2019
|
### Python 2.7 Code was be deleted from this GitHub on Dec 31, 2019
|
||||||
|
|
||||||
Note that the 2.7 port will *cease to exist on this GitHub* on Jan 1, 2020. If you would like to know how much time you have to move over to the Python 3 version of PySimpleGUI, then go here: https://pythonclock.org/. The only thing that will be available is an unsupported PyPI release of PySimpleGUI27.
|
At the suggestion of the Python community at large, the experts, and security folks, the support for 2.7 was pulled from this Repo.
|
||||||
|
|
||||||
By "will cease to exist on this GitHub" I mean, it will be deleted entirely. No source code, no supporting programs. Nothing. If you're stuck using 2.7 in December, it would behoove you to fork the 2.7 code on Dec 31, 2019. Legacy Python doesn't have a permanent home here. It sounds cruel, but experts in security particularly says 2.7 is a huge risk. Furthering it use only hurts the computing world.
|
|
||||||
|
|
||||||
#### Warning - tkinter + Python 3.7.3 and later, including 3.8 has problems
|
#### Warning - tkinter + Python 3.7.3 and later, including 3.8 has problems
|
||||||
|
|
||||||
|
@ -350,6 +391,14 @@ At the moment there are 4 actively developed and maintained "ports" of PySimpleG
|
||||||
|
|
||||||
While PySimpleGUI, the tkinter port, is the only 100% completed version of PySimpleGUI, the other 3 ports have a LOT of functionality in them and are in active use by a large portion of the installations. You can see the number of Pip installs at the very top of this document to get a comparison as to the size of the install base for each port. The "badges" are right after the logo.
|
While PySimpleGUI, the tkinter port, is the only 100% completed version of PySimpleGUI, the other 3 ports have a LOT of functionality in them and are in active use by a large portion of the installations. You can see the number of Pip installs at the very top of this document to get a comparison as to the size of the install base for each port. The "badges" are right after the logo.
|
||||||
|
|
||||||
|
## The Chain Link Fence
|
||||||
|
|
||||||
|
Maybe you've heard the "Walled Garden" term before. It's a boxing in effect.
|
||||||
|
|
||||||
|
While PySimpleGUI has a well-established parameter so you know where the edges are, there is no wall between you and the rest of the GUI framework. There's a chain link fence that's easy to reach through and get full access to the underlying frameworks.
|
||||||
|
|
||||||
|
The net result - it's easy to expand features that are not yet available in PySimpleGUI and easy to remove them too. Maybe the Listbox Element doesn't have a mode exposed that you want to enable. No problem, you can access the underlying Listbox Widget and make what is likely 1 or 2 calls and be done.
|
||||||
|
|
||||||
# The PySimpleGUI "Family"
|
# The PySimpleGUI "Family"
|
||||||
|
|
||||||
## What's The Big Deal? What is it?
|
## What's The Big Deal? What is it?
|
||||||
|
@ -1723,7 +1772,7 @@ popup_get_file(message,
|
||||||
default_extension = "",
|
default_extension = "",
|
||||||
save_as = False,
|
save_as = False,
|
||||||
multiple_files = False,
|
multiple_files = False,
|
||||||
file_types = (('ALL Files', '*.*'),),
|
file_types = (('ALL Files', '*.* *'),),
|
||||||
no_window = False,
|
no_window = False,
|
||||||
size = (None, None),
|
size = (None, None),
|
||||||
button_color = None,
|
button_color = None,
|
||||||
|
@ -1754,7 +1803,7 @@ Parameter Descriptions:
|
||||||
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
| str | default_extension | If no extension entered by user, add this to filename (only used in saveas dialogs) |
|
||||||
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
| bool | save_as | if True, the "save as" dialog is shown which will verify before overwriting |
|
||||||
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
| bool | multiple_files | if True, then allows multiple files to be selected that are returned with ';' between each filename |
|
||||||
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.*"),) |
|
| Tuple[Tuple[str,str]] | file_types | List of extensions to show using wildcards. All files (the default) = (("ALL Files", "*.* *"),) |
|
||||||
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
| bool | no_window | if True, no PySimpleGUI window will be shown. Instead just the tkinter dialog is shown |
|
||||||
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
| (int, int) | size | (width, height) of the InputText Element or Combo element if using history feature |
|
||||||
| (str, str) or str | button_color | Color of the button (text, background) |
|
| (str, str) or str | button_color | Color of the button (text, background) |
|
||||||
|
@ -6046,13 +6095,15 @@ Exception module 'tkinter' has no attribute '__version__'
|
||||||
|
|
||||||
# User Settings API
|
# User Settings API
|
||||||
|
|
||||||
In release 4.30.0 there is a new set of API calls available to help with "user settings". Think of user settings as a dictionary that is automatically written to your hard drive. That's basically what it is. Underpinning the code is the JSON package provided by Python.
|
In release 4.30.0 there is a new set of API calls available to help with "user settings". Think of user settings as a dictionary that is automatically written to your hard drive. That's basically what it is.
|
||||||
|
|
||||||
While using JSON files to save and load a settings dictionary isn't very difficult, it is still code you'll need to write if you want to save settings as part of your GUI. Since having "settings" for a GUI based program isn't uncommon, it made sense to build this capability into PySimpleGUI. Clearly you can still use your own method for saving settings, but if you're looking for a simple and easy way to do it, these calls are likely about as easy as it gets.
|
In release 4.50.0 support for INI files was added in addition to the existing JSON file format.
|
||||||
|
|
||||||
|
While using JSON or config files to save and load a settings dictionary isn't very difficult, it is still code you'll need to write if you want to save settings as part of your GUI. Since having "settings" for a GUI based program isn't uncommon, it made sense to build this capability into PySimpleGUI. Clearly you can still use your own method for saving settings, but if you're looking for a simple and easy way to do it, these calls are likely about as easy as it gets.
|
||||||
|
|
||||||
There have already been some demo programs written that use JSON files to store settings. You can expect that this capability will begin to show up in more demos in the future since it's now part of PySimpleGUI.
|
There have already been some demo programs written that use JSON files to store settings. You can expect that this capability will begin to show up in more demos in the future since it's now part of PySimpleGUI.
|
||||||
|
|
||||||
User settings are stored in a Python dictionary which is saved to / loaded from disk. Individual settings are thus keys into a dictionary. You do not need to explicitly read nor write the file. Changing any entry will cause the file to be saved. Reading any entry will cause the file to be read if it hasn't already been read.
|
User settings are stored in a Python dictionary which is saved to / loaded from disk. Individual settings are thus keys into a dictionary. **You do not need to explicitly read nor write the file**. Changing any entry will cause the file to be saved. Reading any entry will cause the file to be read if it hasn't already been read.
|
||||||
|
|
||||||
## Two Interfaces
|
## Two Interfaces
|
||||||
|
|
||||||
|
@ -6063,6 +6114,8 @@ There are 2 ways to access User Settings
|
||||||
|
|
||||||
They both offer the same basic operations. The class interface has an added benefit of being able to access the individual settings using the same syntax as Python dictionary.
|
They both offer the same basic operations. The class interface has an added benefit of being able to access the individual settings using the same syntax as Python dictionary.
|
||||||
|
|
||||||
|
If you want to use INI files, then you'll need to use the object interface.
|
||||||
|
|
||||||
## List of Calls for Function Interface
|
## List of Calls for Function Interface
|
||||||
|
|
||||||
|Function|Description|
|
|Function|Description|
|
||||||
|
@ -6305,7 +6358,7 @@ in main
|
||||||
|
|
||||||
You should be able to easily figure out these errors as they are file operations and the error messages are clear in detailing what's happened and where the call originated.
|
You should be able to easily figure out these errors as they are file operations and the error messages are clear in detailing what's happened and where the call originated.
|
||||||
|
|
||||||
### Silenting the Errors
|
### Silencing the Errors
|
||||||
|
|
||||||
If you're the type that doesn't want to see any error messages printed out on your console, then you can silence the error output.
|
If you're the type that doesn't want to see any error messages printed out on your console, then you can silence the error output.
|
||||||
|
|
||||||
|
@ -6313,6 +6366,133 @@ When using the class interface, there is a parameter `silent_on_error` that you
|
||||||
|
|
||||||
For the function interface, call the function `user_settings_silent_on_error()` and set the parameter to `True`
|
For the function interface, call the function `user_settings_silent_on_error()` and set the parameter to `True`
|
||||||
|
|
||||||
|
## Config INI File Support
|
||||||
|
|
||||||
|
Using INI files has some advantages over JSON, particularly when humans are going to be modifying the settings files directly.
|
||||||
|
|
||||||
|
To specify use of INI files instead of JSON, set the parameter `use_config_file=True` when creating your `UserSetting` object.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings = sg.UserSettings('my_config.ini', use_config_file=True, convert_bools_and_none=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note the 2 parameters that are specific for .ini files:
|
||||||
|
* `use_config_file` - Set to `True` to indicate you're using an INI file
|
||||||
|
* `convert_bools_and_none` - Defaults to `True`. Normally all settings from INI files are strings. This parameter will convert 'True', 'False', and 'None' to Python values `True`, `False`, `None`
|
||||||
|
|
||||||
|
There is also an additional method added `delete_section` which will delete an entire section from your INI file.
|
||||||
|
|
||||||
|
### Example File
|
||||||
|
|
||||||
|
Let's use this as our example INI file:
|
||||||
|
|
||||||
|
```
|
||||||
|
[My Section]
|
||||||
|
filename = test1234
|
||||||
|
filename2 = number 2
|
||||||
|
filename3 = number 3
|
||||||
|
|
||||||
|
[Section 2]
|
||||||
|
var = 123
|
||||||
|
|
||||||
|
[Empty]
|
||||||
|
|
||||||
|
[last section]
|
||||||
|
bool = True
|
||||||
|
```
|
||||||
|
|
||||||
|
### Getting / Setting Entries
|
||||||
|
|
||||||
|
Just like the JSON files, you can access the individual settings using the UserSettings class by using the `[ ]` notation or by calling `get` and `set` methods.
|
||||||
|
|
||||||
|
The big difference with the INI file support is the addition of an extra lookup / parameter, the section name.
|
||||||
|
|
||||||
|
To access the entry `var` in section `Section 2`, you can use wither of these:
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['Section 2']['var']
|
||||||
|
settings['Section 2'].get('var', 'Default Value')
|
||||||
|
```
|
||||||
|
|
||||||
|
The advantage of using the `get` method is that if the entry is not present, a default value will be returned instead.
|
||||||
|
|
||||||
|
To set an entry, you also have 2 choices:
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['Section 2']['var'] = 'New Value'
|
||||||
|
settings['Section 2'].set('var', 'New Value')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Accessing INI File Sections
|
||||||
|
|
||||||
|
Once you have created your `UserSettings` object, then you'll be accessing entries using 2 keys instead of 1 like JSON uses.
|
||||||
|
|
||||||
|
To access an entire section, you'll write:
|
||||||
|
|
||||||
|
`settings['section']`
|
||||||
|
|
||||||
|
To get all of 'My Section' it will be:
|
||||||
|
|
||||||
|
`settings['My Section']` which returns a section object that behaves much like a dictionary.
|
||||||
|
|
||||||
|
To access a value within a section, add on one more lookup. To get the value of the `filename` setting in the `My Section` section, it's done with this code:
|
||||||
|
|
||||||
|
`settings['My Section']['filename']`
|
||||||
|
|
||||||
|
### Deleting Entries
|
||||||
|
|
||||||
|
To delete an individual entry, you can use several different techniques. One is to use `del`
|
||||||
|
|
||||||
|
```python
|
||||||
|
del settings['My Section1']['test']
|
||||||
|
```
|
||||||
|
|
||||||
|
This deletes the setting `test` in the section `My Section1`
|
||||||
|
|
||||||
|
You can also do this by calling the `delete_entry` method
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings.delete_entry(section='My Section1', key='test')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deleting Sections
|
||||||
|
|
||||||
|
If you want to delete an entire section, you have 2 methods for doing this. One is to call the method `UserSettings.delete_section` and pass in the name of the section to be deleted.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings.delete_section(section='My Section1')
|
||||||
|
```
|
||||||
|
|
||||||
|
The other is to lookup the section and then call `delete_section` on that section.
|
||||||
|
|
||||||
|
```python
|
||||||
|
settings['My Section1'].delete_section()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Printing Settings for INI Files
|
||||||
|
|
||||||
|
If you print (or cast to a string) a section or a UserSettings object for an INI file, then you will get a nicely formated output that shows the sections and what settings are in each section.
|
||||||
|
|
||||||
|
Going back to the example INI file from earlier. Printing the UserSettings object for this file produces this output:
|
||||||
|
|
||||||
|
```
|
||||||
|
My Section:
|
||||||
|
filename : test1234
|
||||||
|
filename2 : number 2
|
||||||
|
filename3 : number 3
|
||||||
|
Section 2:
|
||||||
|
var : 123
|
||||||
|
Empty:
|
||||||
|
last section:
|
||||||
|
bool : True
|
||||||
|
```
|
||||||
|
|
||||||
|
### INI File Comments (WARNING)
|
||||||
|
|
||||||
|
If you have created an INI file using a test editor or it was created output of Python, then when the file is written, your comments will be stripped out. Code is being added to PySimpleGUI to merge back your comments, but the code isn't done yet. You'll either live with this limitation for now or write your own merge code.
|
||||||
|
|
||||||
|
Yea, I know, it's a bummer, but the plan is to overcome this Python limitation.
|
||||||
|
|
||||||
## Coding Convention for User Settings Keys
|
## Coding Convention for User Settings Keys
|
||||||
|
|
||||||
The User Settings prompted a new coding convention that's been added to PySimpleGUI examples. As you're likely aware, keys in layouts have the format `'-KEY-`'. For UserSettings, a similar format is used, but instead of the string being in all upper case, the characters are lower case. In the example below, the user setting for "filename" has a User Setting key of `'-filename-'`. Coding conventions are a good thing to have in your projects. You don't have to follow this one of course, but you're urged to create your own for places in your code that it makes sense. You could say that PEP8 is one giant coding convention for the Python language as a whole. You don't have to follow it, but most Python programmers do. We follow it "by convention".
|
The User Settings prompted a new coding convention that's been added to PySimpleGUI examples. As you're likely aware, keys in layouts have the format `'-KEY-`'. For UserSettings, a similar format is used, but instead of the string being in all upper case, the characters are lower case. In the example below, the user setting for "filename" has a User Setting key of `'-filename-'`. Coding conventions are a good thing to have in your projects. You don't have to follow this one of course, but you're urged to create your own for places in your code that it makes sense. You could say that PEP8 is one giant coding convention for the Python language as a whole. You don't have to follow it, but most Python programmers do. We follow it "by convention".
|
||||||
|
@ -6848,7 +7028,9 @@ Consider this is a ***stern warning***
|
||||||
|
|
||||||
Tkinter also wants to be the MAIN thread in your code. So, if you have to run multiple threads, make sure the GUI is the main thread.
|
Tkinter also wants to be the MAIN thread in your code. So, if you have to run multiple threads, make sure the GUI is the main thread.
|
||||||
|
|
||||||
Other than that, feel free to use threads with PySimpleGUI on all of the ports. You'll find a good example for how to run "long running tasks" in your event loop by looking at the demo program: `Demo_Multithreaded_Long_Tasks.py`. There are several examples of using threads with PySimpleGUI.
|
There is ONE (and only one?) safe call you can make into PySimpleGUI from a thread - `window.write_event_value`
|
||||||
|
|
||||||
|
There are several examples of using threads with PySimpleGUI. Use the Demo Programs! Use the Cookbook! They will give you an immediate and valuable jump start.
|
||||||
|
|
||||||
Be sure and **delete** your windows after you close them if you are running with multiple threads. There is a chance another thread's garbage collect will attempt to delete the window when not in the mainthread which will cause tkinter to crash.
|
Be sure and **delete** your windows after you close them if you are running with multiple threads. There is a chance another thread's garbage collect will attempt to delete the window when not in the mainthread which will cause tkinter to crash.
|
||||||
|
|
||||||
|
@ -6881,7 +7063,7 @@ The sequence looks like this in code:
|
||||||
gc.collect()
|
gc.collect()
|
||||||
```
|
```
|
||||||
|
|
||||||
This will ensure that the tkinter widgets are all deleted in the context of the main-thread and another thread won't accidently run the Garbage Collect
|
This will ensure that the tkinter widgets are all deleted in the context of the main-thread and another thread won't accidentally run the Garbage Collect
|
||||||
|
|
||||||
# Contributing to PySimpleGUI
|
# Contributing to PySimpleGUI
|
||||||
|
|
||||||
|
@ -9037,6 +9219,46 @@ Image element - Simpler to use
|
||||||
- Changed docstring for Multiline default value to Any and added a cast to string
|
- Changed docstring for Multiline default value to Any and added a cast to string
|
||||||
- Added more tests and information to the `sg.main()` test harness
|
- Added more tests and information to the `sg.main()` test harness
|
||||||
|
|
||||||
|
## 4.50.0 PySimpleGUI 17-Oct-2021
|
||||||
|
UserSettings API - support for .INI files
|
||||||
|
Listbox horizontal scrollbar
|
||||||
|
Column Element allow None for 1 size direction
|
||||||
|
|
||||||
|
* UserSettings API
|
||||||
|
* INI File Support
|
||||||
|
* Read access: `settings[section][key]`
|
||||||
|
Modify existing section and key: `settings[section][key] = new_value`
|
||||||
|
Create a new key in an existing section: `settings[section][new_key] = new_value`
|
||||||
|
Create a new section and key: `settings[new_section][new_key] = new_value`
|
||||||
|
Delete a section: `settings.delete_section(section)`
|
||||||
|
Save the INI file: `settings.save()`
|
||||||
|
* Available for UserSettings object only, not the function interface
|
||||||
|
* Demo Program released specific to .ini features
|
||||||
|
* Option to convert strings to Python values for True, False, None
|
||||||
|
* Added checks for running on Trinket or Replit so path can be set to "." if on either
|
||||||
|
* Added `running_replit` function. Returns True if environment is repl.it
|
||||||
|
* New option in set_options - `warn_button_key_duplicates` will show a warning if duplicate keys found on buttons. Defaults to OFF (duplicate key attempts on Buttons are common and OK)
|
||||||
|
* Right Click Menus
|
||||||
|
* New Element method `Element.set_right_click_menu`
|
||||||
|
* Enables changing a right click menu after initial window is created
|
||||||
|
* If none specified, uses the parent's menu
|
||||||
|
* Added `Window.get_size_accurate()` to get the window's size based on the geometry string from tkinter
|
||||||
|
* Removed moving of the theme color swatch preview window and allowed to center now
|
||||||
|
* Added check for bad value returned from tkinter when table clicked event happens
|
||||||
|
* Removed print when 8.6.9 ttk treeview code is patched
|
||||||
|
* Removed a debug print accidentally left in the bind code
|
||||||
|
* Listbox - added horizontal scrollbar option
|
||||||
|
* New `pin` layout helper function implementation (hopefully better, not worse)
|
||||||
|
* Column Element - Allow `None` to be used in any part of the `size`.
|
||||||
|
* If None used on width, then Column will default to width required by contents.
|
||||||
|
* If None used on height, then Column will default to width required by contents divided by 2
|
||||||
|
* These are same values as `(None, None)` today but can invidually control now.
|
||||||
|
* Made `Window.LayoutAndRead` deprication more user friendly with a popup
|
||||||
|
* Added * to the `file_types` default so that files without an extension are shown (only a problem on non-Windows systems). Default is now `(("ALL Files", "*.* *"),)`
|
||||||
|
* Changed `popup_get_file`, the Browse buttons, etc
|
||||||
|
* `FILE_TYPES_ALL_FILES` is a new constant with this value
|
||||||
|
* `popup_scrolled` added 1 line per argument to fit the contents better in some cases
|
||||||
|
|
||||||
## Code Condition
|
## Code Condition
|
||||||
|
|
||||||
Make it run
|
Make it run
|
||||||
|
|
Loading…
Reference in New Issue