From c3a6db921f14f425dd92f161fa9e08de6882b751 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 6 Jan 2023 16:01:52 -0500
Subject: [PATCH 001/145] Revert "Added option to enable/disable manual entry"
This reverts commit 73a66290456bb8e8e2a85be03b2b6402ed6fd524.
---
DemoPrograms/Demo_Time_Chooser.py | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
index 89e20a97..eb36b66e 100644
--- a/DemoPrograms/Demo_Time_Chooser.py
+++ b/DemoPrograms/Demo_Time_Chooser.py
@@ -16,7 +16,7 @@ import PySimpleGUI as sg
-def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow_manual_input=True, font=None):
+def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, font=None):
"""
Shows a window that will gather a time of day.
@@ -26,8 +26,6 @@ def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow
:type starting_hour: int
:param starting_minute: Value to initially show in the minute field
:type starting_minute: int
- :param allow_manual_input: If True, then the Spin elements can be manually edited
- :type allow_manual_input: bool
:param font: Font to use for the window
:type font: str | tuple
:return: Tuple with format: (hour, minute, am-pm string)
@@ -38,9 +36,9 @@ def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow
hour_list = [i for i in range(0, 15)]
minute_list = [i for i in range(-1, 62)]
- layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=not allow_manual_input),
+ layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=False),
sg.Text(':'),
- sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=False),
sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
[sg.Button('Ok'), sg.Button('Cancel')]]
From 02f3ae25be5cb2b25881e8878f0f27aa25838b58 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 6 Jan 2023 16:02:08 -0500
Subject: [PATCH 002/145] Revert "Demo program of an example window to choose a
time"
This reverts commit 86976f50c3c54c8a2b0741acfaeee457d8367e45.
---
DemoPrograms/Demo_Time_Chooser.py | 77 -------------------------------
1 file changed, 77 deletions(-)
delete mode 100644 DemoPrograms/Demo_Time_Chooser.py
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
deleted file mode 100644
index eb36b66e..00000000
--- a/DemoPrograms/Demo_Time_Chooser.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Demo Time Chooser
-
- A sample window for choosing a time.
-
- This particular implementation uses a Spin element. Numerous possibilities exist for entering a time of day. Instead
- of Spin elements, Input or Combo Elements could be used.
-
- If you do not want your user to be able to manually enter values using the keyboard, then set readonly=True in
- the Spin elements.
-
- Copyright 2023 PySimpleGUI
-"""
-
-
-
-def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, font=None):
- """
- Shows a window that will gather a time of day.
-
- :param title: The title that is shown on the window
- :type title: str
- :param starting_hour: Value to initially show in the hour field
- :type starting_hour: int
- :param starting_minute: Value to initially show in the minute field
- :type starting_minute: int
- :param font: Font to use for the window
- :type font: str | tuple
- :return: Tuple with format: (hour, minute, am-pm string)
- :type: (int, int, str)
- """
-
- max_value_dict = {'-HOUR-':(1, 12), '-MIN-':(0, 59)}
- hour_list = [i for i in range(0, 15)]
- minute_list = [i for i in range(-1, 62)]
-
- layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=False),
- sg.Text(':'),
- sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=False),
- sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
- [sg.Button('Ok'), sg.Button('Cancel')]]
-
- window = sg.Window(title, layout, font=font)
-
- while True:
- event, values = window.read()
- # print(event, values)
- if event == sg.WIN_CLOSED or event == 'Cancel':
- hours = minutes = ampm = None
- break
-
- if event == '-HOUR-' or event == '-MIN-':
- spin_value = values[event]
- if spin_value > max_value_dict[event][1]:
- values[event] = max_value_dict[event][0]
- window[event].update(values[event])
- elif spin_value < max_value_dict[event][0]:
- values[event] = max_value_dict[event][1]
- window[event].update(values[event])
- if event == 'Ok':
- # Do validation on the input values to ensure they're valid
- try:
- hours = int(values["-HOUR-"])
- minutes = int(values["-MIN-"])
- ampm = values["-AMPM-"]
- except:
- continue # if not valid, then don't allow exiting the window using OK.
- if 1 <= hours <= 12 and 0 <= minutes < 60: # make sure the hour and minute values are in a valid range
- break
-
- window.close()
-
- return hours, minutes, ampm
-
-print(popup_get_time(font='_ 15'))
\ No newline at end of file
From 0c77b57659d372ef0dc42e6ca58ba89c40074073 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 6 Jan 2023 16:04:33 -0500
Subject: [PATCH 003/145] Demo Program - Time chooser
---
DemoPrograms/Demo_Time_Chooser.py | 79 +++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 DemoPrograms/Demo_Time_Chooser.py
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
new file mode 100644
index 00000000..89e20a97
--- /dev/null
+++ b/DemoPrograms/Demo_Time_Chooser.py
@@ -0,0 +1,79 @@
+import PySimpleGUI as sg
+
+"""
+ Demo Time Chooser
+
+ A sample window for choosing a time.
+
+ This particular implementation uses a Spin element. Numerous possibilities exist for entering a time of day. Instead
+ of Spin elements, Input or Combo Elements could be used.
+
+ If you do not want your user to be able to manually enter values using the keyboard, then set readonly=True in
+ the Spin elements.
+
+ Copyright 2023 PySimpleGUI
+"""
+
+
+
+def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow_manual_input=True, font=None):
+ """
+ Shows a window that will gather a time of day.
+
+ :param title: The title that is shown on the window
+ :type title: str
+ :param starting_hour: Value to initially show in the hour field
+ :type starting_hour: int
+ :param starting_minute: Value to initially show in the minute field
+ :type starting_minute: int
+ :param allow_manual_input: If True, then the Spin elements can be manually edited
+ :type allow_manual_input: bool
+ :param font: Font to use for the window
+ :type font: str | tuple
+ :return: Tuple with format: (hour, minute, am-pm string)
+ :type: (int, int, str)
+ """
+
+ max_value_dict = {'-HOUR-':(1, 12), '-MIN-':(0, 59)}
+ hour_list = [i for i in range(0, 15)]
+ minute_list = [i for i in range(-1, 62)]
+
+ layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Text(':'),
+ sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
+ [sg.Button('Ok'), sg.Button('Cancel')]]
+
+ window = sg.Window(title, layout, font=font)
+
+ while True:
+ event, values = window.read()
+ # print(event, values)
+ if event == sg.WIN_CLOSED or event == 'Cancel':
+ hours = minutes = ampm = None
+ break
+
+ if event == '-HOUR-' or event == '-MIN-':
+ spin_value = values[event]
+ if spin_value > max_value_dict[event][1]:
+ values[event] = max_value_dict[event][0]
+ window[event].update(values[event])
+ elif spin_value < max_value_dict[event][0]:
+ values[event] = max_value_dict[event][1]
+ window[event].update(values[event])
+ if event == 'Ok':
+ # Do validation on the input values to ensure they're valid
+ try:
+ hours = int(values["-HOUR-"])
+ minutes = int(values["-MIN-"])
+ ampm = values["-AMPM-"]
+ except:
+ continue # if not valid, then don't allow exiting the window using OK.
+ if 1 <= hours <= 12 and 0 <= minutes < 60: # make sure the hour and minute values are in a valid range
+ break
+
+ window.close()
+
+ return hours, minutes, ampm
+
+print(popup_get_time(font='_ 15'))
\ No newline at end of file
From 7fdee8f91b243f4e6861b82724c4ba98ca95fd4c Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Fri, 6 Jan 2023 16:08:54 -0500
Subject: [PATCH 004/145] Delete Demo_Time_Chooser.py
---
DemoPrograms/Demo_Time_Chooser.py | 79 -------------------------------
1 file changed, 79 deletions(-)
delete mode 100644 DemoPrograms/Demo_Time_Chooser.py
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
deleted file mode 100644
index 89e20a97..00000000
--- a/DemoPrograms/Demo_Time_Chooser.py
+++ /dev/null
@@ -1,79 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Demo Time Chooser
-
- A sample window for choosing a time.
-
- This particular implementation uses a Spin element. Numerous possibilities exist for entering a time of day. Instead
- of Spin elements, Input or Combo Elements could be used.
-
- If you do not want your user to be able to manually enter values using the keyboard, then set readonly=True in
- the Spin elements.
-
- Copyright 2023 PySimpleGUI
-"""
-
-
-
-def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow_manual_input=True, font=None):
- """
- Shows a window that will gather a time of day.
-
- :param title: The title that is shown on the window
- :type title: str
- :param starting_hour: Value to initially show in the hour field
- :type starting_hour: int
- :param starting_minute: Value to initially show in the minute field
- :type starting_minute: int
- :param allow_manual_input: If True, then the Spin elements can be manually edited
- :type allow_manual_input: bool
- :param font: Font to use for the window
- :type font: str | tuple
- :return: Tuple with format: (hour, minute, am-pm string)
- :type: (int, int, str)
- """
-
- max_value_dict = {'-HOUR-':(1, 12), '-MIN-':(0, 59)}
- hour_list = [i for i in range(0, 15)]
- minute_list = [i for i in range(-1, 62)]
-
- layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=not allow_manual_input),
- sg.Text(':'),
- sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=not allow_manual_input),
- sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
- [sg.Button('Ok'), sg.Button('Cancel')]]
-
- window = sg.Window(title, layout, font=font)
-
- while True:
- event, values = window.read()
- # print(event, values)
- if event == sg.WIN_CLOSED or event == 'Cancel':
- hours = minutes = ampm = None
- break
-
- if event == '-HOUR-' or event == '-MIN-':
- spin_value = values[event]
- if spin_value > max_value_dict[event][1]:
- values[event] = max_value_dict[event][0]
- window[event].update(values[event])
- elif spin_value < max_value_dict[event][0]:
- values[event] = max_value_dict[event][1]
- window[event].update(values[event])
- if event == 'Ok':
- # Do validation on the input values to ensure they're valid
- try:
- hours = int(values["-HOUR-"])
- minutes = int(values["-MIN-"])
- ampm = values["-AMPM-"]
- except:
- continue # if not valid, then don't allow exiting the window using OK.
- if 1 <= hours <= 12 and 0 <= minutes < 60: # make sure the hour and minute values are in a valid range
- break
-
- window.close()
-
- return hours, minutes, ampm
-
-print(popup_get_time(font='_ 15'))
\ No newline at end of file
From c8d01725f1a26615c93da975565f9af97fa29980 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 6 Jan 2023 16:09:39 -0500
Subject: [PATCH 005/145] Demo Program - Time Chooser
---
DemoPrograms/Demo_Time_Chooser.py | 79 +++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 DemoPrograms/Demo_Time_Chooser.py
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
new file mode 100644
index 00000000..89e20a97
--- /dev/null
+++ b/DemoPrograms/Demo_Time_Chooser.py
@@ -0,0 +1,79 @@
+import PySimpleGUI as sg
+
+"""
+ Demo Time Chooser
+
+ A sample window for choosing a time.
+
+ This particular implementation uses a Spin element. Numerous possibilities exist for entering a time of day. Instead
+ of Spin elements, Input or Combo Elements could be used.
+
+ If you do not want your user to be able to manually enter values using the keyboard, then set readonly=True in
+ the Spin elements.
+
+ Copyright 2023 PySimpleGUI
+"""
+
+
+
+def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow_manual_input=True, font=None):
+ """
+ Shows a window that will gather a time of day.
+
+ :param title: The title that is shown on the window
+ :type title: str
+ :param starting_hour: Value to initially show in the hour field
+ :type starting_hour: int
+ :param starting_minute: Value to initially show in the minute field
+ :type starting_minute: int
+ :param allow_manual_input: If True, then the Spin elements can be manually edited
+ :type allow_manual_input: bool
+ :param font: Font to use for the window
+ :type font: str | tuple
+ :return: Tuple with format: (hour, minute, am-pm string)
+ :type: (int, int, str)
+ """
+
+ max_value_dict = {'-HOUR-':(1, 12), '-MIN-':(0, 59)}
+ hour_list = [i for i in range(0, 15)]
+ minute_list = [i for i in range(-1, 62)]
+
+ layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Text(':'),
+ sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
+ [sg.Button('Ok'), sg.Button('Cancel')]]
+
+ window = sg.Window(title, layout, font=font)
+
+ while True:
+ event, values = window.read()
+ # print(event, values)
+ if event == sg.WIN_CLOSED or event == 'Cancel':
+ hours = minutes = ampm = None
+ break
+
+ if event == '-HOUR-' or event == '-MIN-':
+ spin_value = values[event]
+ if spin_value > max_value_dict[event][1]:
+ values[event] = max_value_dict[event][0]
+ window[event].update(values[event])
+ elif spin_value < max_value_dict[event][0]:
+ values[event] = max_value_dict[event][1]
+ window[event].update(values[event])
+ if event == 'Ok':
+ # Do validation on the input values to ensure they're valid
+ try:
+ hours = int(values["-HOUR-"])
+ minutes = int(values["-MIN-"])
+ ampm = values["-AMPM-"]
+ except:
+ continue # if not valid, then don't allow exiting the window using OK.
+ if 1 <= hours <= 12 and 0 <= minutes < 60: # make sure the hour and minute values are in a valid range
+ break
+
+ window.close()
+
+ return hours, minutes, ampm
+
+print(popup_get_time(font='_ 15'))
\ No newline at end of file
From 2821880b3cbbd842ffdf2186f78d4ce413437f02 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Fri, 6 Jan 2023 16:11:28 -0500
Subject: [PATCH 006/145] Delete Demo_Time_Chooser.py
---
DemoPrograms/Demo_Time_Chooser.py | 79 -------------------------------
1 file changed, 79 deletions(-)
delete mode 100644 DemoPrograms/Demo_Time_Chooser.py
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
deleted file mode 100644
index 89e20a97..00000000
--- a/DemoPrograms/Demo_Time_Chooser.py
+++ /dev/null
@@ -1,79 +0,0 @@
-import PySimpleGUI as sg
-
-"""
- Demo Time Chooser
-
- A sample window for choosing a time.
-
- This particular implementation uses a Spin element. Numerous possibilities exist for entering a time of day. Instead
- of Spin elements, Input or Combo Elements could be used.
-
- If you do not want your user to be able to manually enter values using the keyboard, then set readonly=True in
- the Spin elements.
-
- Copyright 2023 PySimpleGUI
-"""
-
-
-
-def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow_manual_input=True, font=None):
- """
- Shows a window that will gather a time of day.
-
- :param title: The title that is shown on the window
- :type title: str
- :param starting_hour: Value to initially show in the hour field
- :type starting_hour: int
- :param starting_minute: Value to initially show in the minute field
- :type starting_minute: int
- :param allow_manual_input: If True, then the Spin elements can be manually edited
- :type allow_manual_input: bool
- :param font: Font to use for the window
- :type font: str | tuple
- :return: Tuple with format: (hour, minute, am-pm string)
- :type: (int, int, str)
- """
-
- max_value_dict = {'-HOUR-':(1, 12), '-MIN-':(0, 59)}
- hour_list = [i for i in range(0, 15)]
- minute_list = [i for i in range(-1, 62)]
-
- layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=not allow_manual_input),
- sg.Text(':'),
- sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=not allow_manual_input),
- sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
- [sg.Button('Ok'), sg.Button('Cancel')]]
-
- window = sg.Window(title, layout, font=font)
-
- while True:
- event, values = window.read()
- # print(event, values)
- if event == sg.WIN_CLOSED or event == 'Cancel':
- hours = minutes = ampm = None
- break
-
- if event == '-HOUR-' or event == '-MIN-':
- spin_value = values[event]
- if spin_value > max_value_dict[event][1]:
- values[event] = max_value_dict[event][0]
- window[event].update(values[event])
- elif spin_value < max_value_dict[event][0]:
- values[event] = max_value_dict[event][1]
- window[event].update(values[event])
- if event == 'Ok':
- # Do validation on the input values to ensure they're valid
- try:
- hours = int(values["-HOUR-"])
- minutes = int(values["-MIN-"])
- ampm = values["-AMPM-"]
- except:
- continue # if not valid, then don't allow exiting the window using OK.
- if 1 <= hours <= 12 and 0 <= minutes < 60: # make sure the hour and minute values are in a valid range
- break
-
- window.close()
-
- return hours, minutes, ampm
-
-print(popup_get_time(font='_ 15'))
\ No newline at end of file
From d9e42ed2e7fd3801396a457de40c4d7f39fbe9d9 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 6 Jan 2023 16:12:40 -0500
Subject: [PATCH 007/145] Demo Program - Time Chooser (ONE more time!)
---
DemoPrograms/Demo_Time_Chooser.py | 79 +++++++++++++++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 DemoPrograms/Demo_Time_Chooser.py
diff --git a/DemoPrograms/Demo_Time_Chooser.py b/DemoPrograms/Demo_Time_Chooser.py
new file mode 100644
index 00000000..89e20a97
--- /dev/null
+++ b/DemoPrograms/Demo_Time_Chooser.py
@@ -0,0 +1,79 @@
+import PySimpleGUI as sg
+
+"""
+ Demo Time Chooser
+
+ A sample window for choosing a time.
+
+ This particular implementation uses a Spin element. Numerous possibilities exist for entering a time of day. Instead
+ of Spin elements, Input or Combo Elements could be used.
+
+ If you do not want your user to be able to manually enter values using the keyboard, then set readonly=True in
+ the Spin elements.
+
+ Copyright 2023 PySimpleGUI
+"""
+
+
+
+def popup_get_time(title='Time Entry', starting_hour=1, starting_minute=0, allow_manual_input=True, font=None):
+ """
+ Shows a window that will gather a time of day.
+
+ :param title: The title that is shown on the window
+ :type title: str
+ :param starting_hour: Value to initially show in the hour field
+ :type starting_hour: int
+ :param starting_minute: Value to initially show in the minute field
+ :type starting_minute: int
+ :param allow_manual_input: If True, then the Spin elements can be manually edited
+ :type allow_manual_input: bool
+ :param font: Font to use for the window
+ :type font: str | tuple
+ :return: Tuple with format: (hour, minute, am-pm string)
+ :type: (int, int, str)
+ """
+
+ max_value_dict = {'-HOUR-':(1, 12), '-MIN-':(0, 59)}
+ hour_list = [i for i in range(0, 15)]
+ minute_list = [i for i in range(-1, 62)]
+
+ layout = [[sg.Spin(hour_list, initial_value=starting_hour, key='-HOUR-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Text(':'),
+ sg.Spin(minute_list, initial_value=starting_minute, key='-MIN-', s=3, enable_events=True, readonly=not allow_manual_input),
+ sg.Combo(['AM', 'PM'], 'AM', readonly=True, key='-AMPM-')],
+ [sg.Button('Ok'), sg.Button('Cancel')]]
+
+ window = sg.Window(title, layout, font=font)
+
+ while True:
+ event, values = window.read()
+ # print(event, values)
+ if event == sg.WIN_CLOSED or event == 'Cancel':
+ hours = minutes = ampm = None
+ break
+
+ if event == '-HOUR-' or event == '-MIN-':
+ spin_value = values[event]
+ if spin_value > max_value_dict[event][1]:
+ values[event] = max_value_dict[event][0]
+ window[event].update(values[event])
+ elif spin_value < max_value_dict[event][0]:
+ values[event] = max_value_dict[event][1]
+ window[event].update(values[event])
+ if event == 'Ok':
+ # Do validation on the input values to ensure they're valid
+ try:
+ hours = int(values["-HOUR-"])
+ minutes = int(values["-MIN-"])
+ ampm = values["-AMPM-"]
+ except:
+ continue # if not valid, then don't allow exiting the window using OK.
+ if 1 <= hours <= 12 and 0 <= minutes < 60: # make sure the hour and minute values are in a valid range
+ break
+
+ window.close()
+
+ return hours, minutes, ampm
+
+print(popup_get_time(font='_ 15'))
\ No newline at end of file
From d0c558f5c8416bfb2c9c6028eebb97e35ec0d9ad Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 12 Jan 2023 06:11:05 -0500
Subject: [PATCH 008/145] Tree element - if no headings are specified (set to
None) then the header will not be added
---
PySimpleGUI.py | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index fa0fbc42..35ea4f2b 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.135 Unreleased"
+version = __version__ = "4.60.4.136 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -337,7 +337,8 @@ _change_log = """
popup_get_date - exposed the fonts as parameters so that the user code and modify them (specifically to get around a Mac font bug)
4.60.4.135
Renamed QuickMeter to _QuickMeter so that it's clear that it's not an object meant to be used by users
-
+ 4.60.4.136
+ Tree element - if headings is set to None, no headings area is shown
"""
__version__ = version.split()[0] # For PEP 396 and PEP 345
@@ -17504,7 +17505,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
column_headings = element.ColumnHeadings
# ------------- GET THE TREEVIEW WIDGET -------------
element.TKTreeview = element.Widget = ttk.Treeview(element_frame, columns=column_headings,
- displaycolumns=displaycolumns, show='tree headings',
+ displaycolumns=displaycolumns,
+ show='tree headings' if column_headings is not None else 'tree',
height=height,
selectmode=element.SelectMode)
treeview = element.TKTreeview
@@ -17515,19 +17517,19 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
if len(str(value)) > max_width:
max_widths[i] = len(str(value))
-
- for i, heading in enumerate(element.ColumnHeadings): # Configure cols + headings
- treeview.heading(heading, text=heading)
- if element.AutoSizeColumns:
- max_width = max_widths.get(i, 0)
- max_width = max(max_width, len(heading))
- width = min(element.MaxColumnWidth, max_width+1)
- else:
- try:
- width = element.ColumnWidths[i]
- except:
- width = element.DefaultColumnWidth
- treeview.column(heading, width=width * _char_width_in_pixels(font) + 10, anchor=anchor)
+ if element.ColumnHeadings is not None:
+ for i, heading in enumerate(element.ColumnHeadings): # Configure cols + headings
+ treeview.heading(heading, text=heading)
+ if element.AutoSizeColumns:
+ max_width = max_widths.get(i, 0)
+ max_width = max(max_width, len(heading))
+ width = min(element.MaxColumnWidth, max_width+1)
+ else:
+ try:
+ width = element.ColumnWidths[i]
+ except:
+ width = element.DefaultColumnWidth
+ treeview.column(heading, width=width * _char_width_in_pixels(font) + 10, anchor=anchor)
def add_treeview_data(node):
"""
@@ -26233,4 +26235,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#2d2045fc87ee17cd939d4e616b04275ddcce76fd8db3487270058eb7ccb30c1dbab79d6c7956da4eefa99fedf57f849d7106d75dbf09aaa1e372ccc051d85418f14c6b9252fa3870cb5d88023398f9d503145049ec9f9f148650f10040ae8ff41a79915066663d75df7bc63827711503d6e0a2f6b5f1f15ad8d8517f7a5cfa04bb7614ca65fa6ef8a3a0f4d5f8a0b432bb60f20dc1b3cd68dd047e5c00a93930732be95921a4ae79f4dbb1ccb9c34de276e7e704a7f179a72be7e14a4d537463807e0b73ab8a040e33918e596374af841c5e9a6b9cd350280e3d3ab577f247bdafdccf659b26b231322973c78fdb0464d5b93ffac5e0a177dce4291d73ea535c01b579812d7929f0e8b3a3ace84524d2e55ee617171782de6866bb7e219d5f46ee3ecd4821207a224880c0826e70fd2e00292bcb034a8b61cc8782ea035c4e566337b4ba7e5ebf018450042966f99c68a1fd4cfa1649042ef3ccaac8a0c472d0d81da274d4028246660ad6b16334ff3b8d77096dbb7640a92a7127713443e7a1c184542f8069c04f4e6528b19766f26f3eac9743f3d16558789d1579ecfc955e4d7ff7ed78aa1f2e33b25e73c7751bd267947bc4643992e030523cab2d8c025f38bec65c270a036d4fe76f6a19d729f9b544f155d3a775c944615ed0bf87cf04515bfe51fe5d1ec4ffe39c0c04ea0861fe91d385aa42fa97bb7f2d898e186ae0
\ No newline at end of file
+#15b898227394d50e7b41524f11f1fe498d2c6c114f5c1bf5278bb9b486181938a3ac012b4a6e144fad3d0b23748d9012d3bb7ce016e5c946332dac672c965e04829e7c484ba4f06bb1a98b86ed382d27f5a5124a1451cafb3e700cfc90cdf212ce393aa01b64dee02bc42b90328f6b05e935d2b1725d8c596392cd37740ca969aab3165a6aa808a6d318f161d7ee826c536e4d5cc5a45ce948c139c3008b9edad36fc981fc6028e42b7aec5cd5d14e9b440fbb48ac29240371e40a28fbb1ed000bd1fc48df381d44efaa48e54bbdd280c07e7889c67bef7281e5e64987a4be969511e6db440ea0811c4b6e17489b138485022217e8f3f923bf4a70bab8263b3298cbd388aa4c0f9355917e114b3b1bc536e7e066f9f0e6d52e06e89dd165d46b9106a1f18313359fc90d7ec4d5ac149eb1d4ca729c634e20f3b2f42a1c20da96addfcc42f55479ebdbf2dfbf98deac050ef93196fa7b6a14b39bb81bafeedf4cb3ea4b38a51ce0df2f4ae3b5400e5c375c3897e3a2498ebe9530bc3502d471da0fbb11762a8d2505b0a2866d0fc0972ed29a9cfa4aaa5012cf618e77bc139d01e13a5239d85a78f8be1f3194166cfac6dafbc4a154f42b4b19a8bd9f923ced14409024fff87f90db4f35b317ce4e6679f08151dedeef6f81c37f26e2532a57cf056b765c2ea0a6970e66c27de68306a97614517ec0f1b1d2ea8e81f631ab9f9c
\ No newline at end of file
From b216a254809d35764caeb25418dd952dddd4b599 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 12 Jan 2023 06:23:28 -0500
Subject: [PATCH 009/145] Disables "Take me to error" button if no editor is
configured
---
PySimpleGUI.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 35ea4f2b..f71df6f1 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.136 Unreleased"
+version = __version__ = "4.60.4.137 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -339,6 +339,9 @@ _change_log = """
Renamed QuickMeter to _QuickMeter so that it's clear that it's not an object meant to be used by users
4.60.4.136
Tree element - if headings is set to None, no headings area is shown
+ 4.60.4.137
+ "Take me to error" button is disabled in error traceback popup if not editor is configured. Also adds instructions if no editor.
+
"""
__version__ = version.split()[0] # For PEP 396 and PEP 345
@@ -22202,6 +22205,7 @@ def _error_popup_with_code(title, filename, line_num, *args, emoji=None):
:param emoji: An optional BASE64 Encoded image to shows in the error window
:type emoji: bytes
"""
+ editor_filename = _get_editor()
emoji_data = emoji if emoji is not None else _random_error_emoji()
layout = [[Text('ERROR'), Text(title)],
[Image(data=emoji_data)]]
@@ -22219,8 +22223,9 @@ def _error_popup_with_code(title, filename, line_num, *args, emoji=None):
layout += [[Text(''.join(line), size=(min(max_line_len, 90), None))] for line in lines]
- layout += [[Button('Close'), Button('Take me to error'), Button('Kill Application', button_color='white on red')]]
-
+ layout += [[Button('Close'), Button('Take me to error', disabled=True if not editor_filename else False), Button('Kill Application', button_color='white on red')]]
+ if not editor_filename:
+ layout += [[Text('Configure editor in the Global settings to enable "Take me to error" feature')]]
window = Window(title, layout, keep_on_top=True)
while True:
@@ -26235,4 +26240,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#15b898227394d50e7b41524f11f1fe498d2c6c114f5c1bf5278bb9b486181938a3ac012b4a6e144fad3d0b23748d9012d3bb7ce016e5c946332dac672c965e04829e7c484ba4f06bb1a98b86ed382d27f5a5124a1451cafb3e700cfc90cdf212ce393aa01b64dee02bc42b90328f6b05e935d2b1725d8c596392cd37740ca969aab3165a6aa808a6d318f161d7ee826c536e4d5cc5a45ce948c139c3008b9edad36fc981fc6028e42b7aec5cd5d14e9b440fbb48ac29240371e40a28fbb1ed000bd1fc48df381d44efaa48e54bbdd280c07e7889c67bef7281e5e64987a4be969511e6db440ea0811c4b6e17489b138485022217e8f3f923bf4a70bab8263b3298cbd388aa4c0f9355917e114b3b1bc536e7e066f9f0e6d52e06e89dd165d46b9106a1f18313359fc90d7ec4d5ac149eb1d4ca729c634e20f3b2f42a1c20da96addfcc42f55479ebdbf2dfbf98deac050ef93196fa7b6a14b39bb81bafeedf4cb3ea4b38a51ce0df2f4ae3b5400e5c375c3897e3a2498ebe9530bc3502d471da0fbb11762a8d2505b0a2866d0fc0972ed29a9cfa4aaa5012cf618e77bc139d01e13a5239d85a78f8be1f3194166cfac6dafbc4a154f42b4b19a8bd9f923ced14409024fff87f90db4f35b317ce4e6679f08151dedeef6f81c37f26e2532a57cf056b765c2ea0a6970e66c27de68306a97614517ec0f1b1d2ea8e81f631ab9f9c
\ No newline at end of file
+#0fc8e76e80cf311966aea1caad0abf27e052e259fa5cdd101f47301d25ced192cf52177eb64ac7554f7e4546cbb3dcaf5210b2d4c9116958f54fcb1f1f4882a3e553b4c9ef77a1eaee3fcabb8abd047107bcdc891f60ea96cbe345316d48f261a000f8434b9337a4e57ba9caf783f85038d9759872d9ad9613433e07207db1e94bc416b87ddff2c4836da4a98a405c6b28482cca84f60cf1c1924099668b71a33701b35e978924f9abcc904e88f3830acea23b69eacc81bbdbf07eb53438060630badfb914f1ea7d00c3d717da8f6199719476d93dcdf37aebd148e1a4641deb6955140aac1f9bf91244ac1a7b9439b45011aca3d4d02adce54efc6b9c20c0892485de5b343909ce6c89e0921adc7a35d9b9fb03e544d022b1549b0c016b72a70b7ffdb5aa92b3e2a49d52de9196008944b4455c3c8df4e9f9bfc6a8d6369081b19ca0b21b7b2333a0fea526f3935c21d40d3c2b74e10b3c0ec6166e0592fe85086d4ad3fb52d1080e921d37ead81fd2a5b1e4ac91dbd90f611a5373ec04ec735198454f52caad2bb3439790194ee4f546e23bcd84b9b54ac372ac5e5855dd97a02c06e6b3d5a285a3b482ecd90f7b89f819feece3e75154cd423d08c30c1f20872be13b0201c83720e0398e3ab9adcbd7b3718838bdd6073239d326bf7b2f54caee78b0f01eac621f379b25af78d7625f1797c6b87e6cf7f43a089980c07ace
\ No newline at end of file
From 81c16c6b5fc5559a79b037ef7c2e947c0c54d85f Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 12 Jan 2023 13:37:32 -0500
Subject: [PATCH 010/145] Added begin_at_sunday_plus to the docstring for
CalendarButton
---
PySimpleGUI.py | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index f71df6f1..8c63093e 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.137 Unreleased"
+version = __version__ = "4.60.4.138 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -341,6 +341,8 @@ _change_log = """
Tree element - if headings is set to None, no headings area is shown
4.60.4.137
"Take me to error" button is disabled in error traceback popup if not editor is configured. Also adds instructions if no editor.
+ 4.60.4.138
+ Added begin_at_sunday_plus to the CalendarButton docstring
"""
@@ -14661,6 +14663,8 @@ def CalendarButton(button_text, target=(ThisRow, -1), close_when_date_chosen=Tru
:type locale: str
:param format: formats result using this strftime format
:type format: str
+ :param begin_at_sunday_plus: Determines the left-most day in the display. 0=sunday, 1=monday, etc
+ :type begin_at_sunday_plus: (int)
:param month_names: optional list of month names to use (should be 12 items)
:type month_names: List[str]
:param day_abbreviations: optional list of abbreviations to display as the day of week
@@ -26240,4 +26244,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#0fc8e76e80cf311966aea1caad0abf27e052e259fa5cdd101f47301d25ced192cf52177eb64ac7554f7e4546cbb3dcaf5210b2d4c9116958f54fcb1f1f4882a3e553b4c9ef77a1eaee3fcabb8abd047107bcdc891f60ea96cbe345316d48f261a000f8434b9337a4e57ba9caf783f85038d9759872d9ad9613433e07207db1e94bc416b87ddff2c4836da4a98a405c6b28482cca84f60cf1c1924099668b71a33701b35e978924f9abcc904e88f3830acea23b69eacc81bbdbf07eb53438060630badfb914f1ea7d00c3d717da8f6199719476d93dcdf37aebd148e1a4641deb6955140aac1f9bf91244ac1a7b9439b45011aca3d4d02adce54efc6b9c20c0892485de5b343909ce6c89e0921adc7a35d9b9fb03e544d022b1549b0c016b72a70b7ffdb5aa92b3e2a49d52de9196008944b4455c3c8df4e9f9bfc6a8d6369081b19ca0b21b7b2333a0fea526f3935c21d40d3c2b74e10b3c0ec6166e0592fe85086d4ad3fb52d1080e921d37ead81fd2a5b1e4ac91dbd90f611a5373ec04ec735198454f52caad2bb3439790194ee4f546e23bcd84b9b54ac372ac5e5855dd97a02c06e6b3d5a285a3b482ecd90f7b89f819feece3e75154cd423d08c30c1f20872be13b0201c83720e0398e3ab9adcbd7b3718838bdd6073239d326bf7b2f54caee78b0f01eac621f379b25af78d7625f1797c6b87e6cf7f43a089980c07ace
\ No newline at end of file
+#72a37da2ed2698572ff1dd1ff7c3117548c6d90f24a80357f9ab68bf2ce2631e77578781d2a862823b929a07256888312fd4d577981e55c841544ea2aa0705867d41371f9b5ebf3e779fa0af4dee1bbacc65e6c4c8f8524a881eebb41121b3664966154f6346594dd364552465cd951eae92dfd878fb092ebc3885e4186537addeca75a45074d7027d7c91c0a9f294770d35757a46164a5d33e16f18eac7ca661fc184cc68d2d9204e34b01ad877ac4aadb020bf86e36decdeb51417866aa9e03a9ee34902c9ed84f604f15267cdfd6d4dc75bb0cd7b989c4552941a91ec3fecfa7abc13c179cfcbc943ca197f42d602c22966e40eb4230381a12da8d5a8c9c1ba31c8a857cbb3376a7d046b5e27567680abc2c10f4fde972371fd8b3005fc536f998834139061bfe8291aa641c767cd6996d7684d36bf388da4ea8ff26685625f4c757520df5772af2d2e1029009562628aad1acdc91d924269eb44d6e1427ffda09c46e44dcfac8bf46d3cd8139c20109e61966695176386ff8fd289ef9d62419824283ba656b9e744ad49eb0345375e1d3cefbc11c2a09f4309d9b33edf38de9dbbf2656198459b5bd051b18b1dc8ccd5edc87fe45b85e6b083b52c1748e16f4952609278705daa1475b83669922dd1168db67b4ea7dbfa1526e9bd89f3c30a4334fd198ce05f3dfcc4358cd1682428890d795541fea9b405447ee485d0ff
\ No newline at end of file
From 529c285489e51f7c2e96a7264d21fcf82ac8e896 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 12 Jan 2023 21:06:16 -0500
Subject: [PATCH 011/145] Moved debugger constants to sinde of the debugger
class. Simplified the locals and globals popups.
---
PySimpleGUI.py | 104 ++++++++++++++++++++++++++-----------------------
1 file changed, 55 insertions(+), 49 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 8c63093e..294d80bb 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.138 Unreleased"
+version = __version__ = "4.60.4.139 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -343,6 +343,8 @@ _change_log = """
"Take me to error" button is disabled in error traceback popup if not editor is configured. Also adds instructions if no editor.
4.60.4.138
Added begin_at_sunday_plus to the CalendarButton docstring
+ 4.60.4.139
+ Moved debugger constants to sinde of the debugger class. Simplified the locals and globals popups.
"""
@@ -23654,26 +23656,28 @@ def main_mac_feature_control():
red_x = b"R0lGODlhEAAQAPeQAIsAAI0AAI4AAI8AAJIAAJUAAJQCApkAAJoAAJ4AAJkJCaAAAKYAAKcAAKcCAKcDA6cGAKgAAKsAAKsCAKwAAK0AAK8AAK4CAK8DAqUJAKULAKwLALAAALEAALIAALMAALMDALQAALUAALYAALcEALoAALsAALsCALwAAL8AALkJAL4NAL8NAKoTAKwbAbEQALMVAL0QAL0RAKsREaodHbkQELMsALg2ALk3ALs+ALE2FbgpKbA1Nbc1Nb44N8AAAMIWAMsvAMUgDMcxAKVABb9NBbVJErFYEq1iMrtoMr5kP8BKAMFLAMxKANBBANFCANJFANFEB9JKAMFcANFZANZcANpfAMJUEMZVEc5hAM5pAMluBdRsANR8AM9YOrdERMpIQs1UVMR5WNt8X8VgYMdlZcxtYtx4YNF/btp9eraNf9qXXNCCZsyLeNSLd8SSecySf82kd9qqc9uBgdyBgd+EhN6JgtSIiNuJieGHhOGLg+GKhOKamty1ste4sNO+ueenp+inp+HHrebGrefKuOPTzejWzera1O7b1vLb2/bl4vTu7fbw7ffx7vnz8f///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJAALAAAAAAQABAAAAjUACEJHEiwYEEABniQKfNFgQCDkATQwAMokEU+PQgUFDAjjR09e/LUmUNnh8aBCcCgUeRmzBkzie6EeQBAoAAMXuA8ciRGCaJHfXzUMCAQgYooWN48anTokR8dQk4sELggBhQrU9Q8evSHiJQgLCIIfMDCSZUjhbYuQkLFCRAMAiOQGGLE0CNBcZYmaRIDLqQFGF60eTRoSxc5jwjhACFWIAgMLtgUocJFy5orL0IQRHAiQgsbRZYswbEhBIiCCH6EiJAhAwQMKU5DjHCi9gnZEHMTDAgAOw=="
-COLOR_SCHEME = 'dark grey 13'
-DEBUGGER_POPOUT_THEME = 'dark grey 13'
-WIDTH_VARIABLES = 23
-WIDTH_RESULTS = 46
-WIDTH_WATCHER_VARIABLES = 20
-WIDTH_WATCHER_RESULTS = 60
-
-WIDTH_LOCALS = 80
-NUM_AUTO_WATCH = 9
-
-MAX_LINES_PER_RESULT_FLOATING = 4
-MAX_LINES_PER_RESULT_MAIN = 3
-
-POPOUT_WINDOW_FONT = 'Sans 8'
-DEBUGGER_VARIABLE_DETAILS_FONT = 'Courier 10'
class _Debugger:
debugger = None
+ DEBUGGER_MAIN_WINDOW_THEME = 'dark grey 13'
+ DEBUGGER_POPOUT_THEME = 'dark grey 13'
+ WIDTH_VARIABLES = 23
+ WIDTH_RESULTS = 46
+
+ WIDTH_WATCHER_VARIABLES = 20
+ WIDTH_WATCHER_RESULTS = 60
+
+ WIDTH_LOCALS = 80
+ NUM_AUTO_WATCH = 9
+
+ MAX_LINES_PER_RESULT_FLOATING = 4
+ MAX_LINES_PER_RESULT_MAIN = 3
+
+ DEBUGGER_POPOUT_WINDOW_FONT = 'Sans 8'
+ DEBUGGER_VARIABLE_DETAILS_FONT = 'Courier 10'
+
'''
# # ######
## ## ## # # # # # ###### ##### # # #### #### ###### #####
@@ -23696,12 +23700,12 @@ class _Debugger:
# Includes the DUAL PANE (now 2 tabs)! Don't forget REPL is there too!
def _build_main_debugger_window(self, location=(None, None)):
old_theme = theme()
- theme(COLOR_SCHEME)
+ theme(_Debugger.DEBUGGER_MAIN_WINDOW_THEME)
def InVar(key1):
row1 = [T(' '),
- I(key=key1, size=(WIDTH_VARIABLES, 1)),
- T('', key=key1 + 'CHANGED_', size=(WIDTH_RESULTS, 1)), B('Detail', key=key1 + 'DETAIL_'),
+ I(key=key1, size=(_Debugger.WIDTH_VARIABLES, 1)),
+ T('', key=key1 + 'CHANGED_', size=(_Debugger.WIDTH_RESULTS, 1)), B('Detail', key=key1 + 'DETAIL_'),
B('Obj', key=key1 + 'OBJ_'), ]
return row1
@@ -23722,10 +23726,9 @@ class _Debugger:
Button('Popout', key='-POPOUT-')]]
var_layout = []
- for i in range(NUM_AUTO_WATCH):
- var_layout.append([T('', size=(WIDTH_WATCHER_VARIABLES, 1), key='_WATCH%s_' % i),
- T('', size=(WIDTH_WATCHER_RESULTS, MAX_LINES_PER_RESULT_MAIN), key='_WATCH%s_RESULT_' % i,
- )])
+ for i in range(_Debugger.NUM_AUTO_WATCH):
+ var_layout.append([T('', size=(_Debugger.WIDTH_WATCHER_VARIABLES, 1), key='_WATCH%s_' % i),
+ T('', size=(_Debugger.WIDTH_WATCHER_RESULTS, _Debugger.MAX_LINES_PER_RESULT_MAIN), key='_WATCH%s_RESULT_' % i,)])
col1 = [
# [Frame('Auto Watches', autowatch_frame+variable_values, title_color='blue')]
@@ -23742,8 +23745,7 @@ class _Debugger:
[TabGroup([[Tab('Variables', col1), Tab('REPL & Watches', col2)]])]]
# ------------------------------- Create main window -------------------------------
- window = Window("PySimpleGUI Debugger", layout, icon=PSG_DEBUGGER_LOGO, margins=(0, 0), location=location, keep_on_top=True,
- right_click_menu=[[''], ['Exit', ]])
+ window = Window("PySimpleGUI Debugger", layout, icon=PSG_DEBUGGER_LOGO, margins=(0, 0), location=location, keep_on_top=True, right_click_menu=[[''], ['Exit', ]])
Window._read_call_from_debugger = True
window.finalize()
@@ -23801,7 +23803,7 @@ class _Debugger:
result = str(eval(str(var), myglobals, mylocals))
except:
result = ''
- popup_scrolled(str(values['_VAR{}_'.format(event[4])]) + '\n' + result, title=var, non_blocking=True, font=DEBUGGER_VARIABLE_DETAILS_FONT)
+ popup_scrolled(str(values['_VAR{}_'.format(event[4])]) + '\n' + result, title=var, non_blocking=True, font=_Debugger.DEBUGGER_VARIABLE_DETAILS_FONT)
# BUTTON - OBJ
elif event.endswith('_OBJ_'): # OBJECT BUTTON
var = values['_VAR{}_'.format(event[4])]
@@ -23813,17 +23815,17 @@ class _Debugger:
result = ObjToStringSingleObj(result)
except Exception as e:
result = '{}\nError showing object {}'.format(e, var)
- popup_scrolled(str(var) + '\n' + str(result), title=var, non_blocking=True, font=DEBUGGER_VARIABLE_DETAILS_FONT)
+ popup_scrolled(str(var) + '\n' + str(result), title=var, non_blocking=True, font=Debugger.DEBUGGER_VARIABLE_DETAILS_FONT)
# ------------------------------- Process Watch Tab -------------------------------
# BUTTON - Choose Locals to see
elif event == '-LOCALS-': # Show all locals BUTTON
self._choose_auto_watches(mylocals)
# BUTTON - Locals (quick popup)
elif event == '-ALL_LOCALS-':
- self._display_all_vars(mylocals)
+ self._display_all_vars('All Locals', mylocals)
# BUTTON - Globals (quick popup)
elif event == '-GLOBALS-':
- self._display_all_vars(myglobals)
+ self._display_all_vars('All Globals', myglobals)
# BUTTON - clear all
elif event == 'Clear All Auto Watches':
if popup_yes_no('Do you really want to clear all Auto-Watches?', 'Really Clear??') == 'Yes':
@@ -23866,7 +23868,7 @@ class _Debugger:
self.watcher_window.Element('_WATCH{}_RESULT_'.format(slot)).Update('')
slot += 1
- if slot + int(not self.custom_watch in (None, '')) >= NUM_AUTO_WATCH:
+ if slot + int(not self.custom_watch in (None, '')) >= _Debugger.NUM_AUTO_WATCH:
break
# If a custom watch was set, display that value in the window
if self.custom_watch:
@@ -23878,7 +23880,7 @@ class _Debugger:
self.watcher_window.Element('_WATCH{}_RESULT_'.format(slot)).Update(self.myrc)
slot += 1
# blank out all of the slots not used (blank)
- for i in range(slot, NUM_AUTO_WATCH):
+ for i in range(slot, _Debugger.NUM_AUTO_WATCH):
self.watcher_window.Element('_WATCH{}_'.format(i)).Update('')
self.watcher_window.Element('_WATCH{}_RESULT_'.format(i)).Update('')
@@ -23927,12 +23929,12 @@ class _Debugger:
'''
# displays them into a single text box
- def _display_all_vars(self, dict):
+ def _display_all_vars(self, title, dict):
num_cols = 3
output_text = ''
num_lines = 2
cur_col = 0
- out_text = 'All of your Vars'
+ out_text = title + '\n'
longest_line = max([len(key) for key in dict])
line = []
sorted_dict = {}
@@ -23940,15 +23942,19 @@ class _Debugger:
sorted_dict[key] = dict[key]
for key in sorted_dict:
value = dict[key]
- wrapped_list = textwrap.wrap(str(value), 60)
- wrapped_text = '\n'.join(wrapped_list)
+ # wrapped_list = textwrap.wrap(str(value), 60)
+ # wrapped_text = '\n'.join(wrapped_list)
+ wrapped_text = str(value)
out_text += '{} - {}\n'.format(key, wrapped_text)
- if cur_col + 1 == num_cols:
- cur_col = 0
- num_lines += len(wrapped_list)
- else:
- cur_col += 1
- popup_scrolled(out_text, non_blocking=True)
+ # if cur_col + 1 == num_cols:
+ # cur_col = 0
+ # num_lines += len(wrapped_list)
+ # else:
+ # cur_col += 1
+ old_theme = theme()
+ theme(_Debugger.DEBUGGER_MAIN_WINDOW_THEME)
+ popup_scrolled(out_text, title=title, non_blocking=True, font=_Debugger.DEBUGGER_VARIABLE_DETAILS_FONT, keep_on_top=True, icon=PSG_DEBUGGER_LOGO)
+ theme(old_theme)
'''
##### # #
@@ -23970,7 +23976,7 @@ class _Debugger:
def _choose_auto_watches(self, my_locals):
old_theme = theme()
- theme(COLOR_SCHEME)
+ theme(_Debugger.DEBUGGER_MAIN_WINDOW_THEME)
num_cols = 3
output_text = ''
num_lines = 2
@@ -23998,7 +24004,7 @@ class _Debugger:
layout += [
[Ok(), Cancel(), Button('Clear All'), Button('Select [almost] All', key='-AUTO_SELECT-')]]
- window = Window('All Locals', layout, icon=PSG_DEBUGGER_LOGO, finalize=True)
+ window = Window('Choose Watches', layout, icon=PSG_DEBUGGER_LOGO, finalize=True, keep_on_top=True)
while True: # event loop
event, values = window.read()
@@ -24053,7 +24059,7 @@ class _Debugger:
if self.popout_window: # if floating window already exists, close it first
self.popout_window.Close()
old_theme = theme()
- theme(DEBUGGER_POPOUT_THEME)
+ theme(_Debugger.DEBUGGER_POPOUT_THEME)
num_cols = 2
width_var = 15
width_value = 30
@@ -24070,10 +24076,10 @@ class _Debugger:
for key in self.popout_choices:
if self.popout_choices[key] is True:
value = str(self.locals.get(key))
- h = min(len(value) // width_value + 1, MAX_LINES_PER_RESULT_FLOATING)
- line += [Text('{}'.format(key), size=(width_var, 1), font=POPOUT_WINDOW_FONT),
- Text(' = ', font=POPOUT_WINDOW_FONT),
- Text(value, key=key, size=(width_value, h), font=POPOUT_WINDOW_FONT)]
+ h = min(len(value) // width_value + 1, _Debugger.MAX_LINES_PER_RESULT_FLOATING)
+ line += [Text('{}'.format(key), size=(width_var, 1), font=_Debugger.DEBUGGER_POPOUT_WINDOW_FONT),
+ Text(' = ', font=_Debugger.DEBUGGER_POPOUT_WINDOW_FONT),
+ Text(value, key=key, size=(width_value, h), font=_Debugger.DEBUGGER_POPOUT_WINDOW_FONT)]
if col + 1 < num_cols:
line += [VerticalSeparator(), T(' ')]
col += 1
@@ -26244,4 +26250,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#72a37da2ed2698572ff1dd1ff7c3117548c6d90f24a80357f9ab68bf2ce2631e77578781d2a862823b929a07256888312fd4d577981e55c841544ea2aa0705867d41371f9b5ebf3e779fa0af4dee1bbacc65e6c4c8f8524a881eebb41121b3664966154f6346594dd364552465cd951eae92dfd878fb092ebc3885e4186537addeca75a45074d7027d7c91c0a9f294770d35757a46164a5d33e16f18eac7ca661fc184cc68d2d9204e34b01ad877ac4aadb020bf86e36decdeb51417866aa9e03a9ee34902c9ed84f604f15267cdfd6d4dc75bb0cd7b989c4552941a91ec3fecfa7abc13c179cfcbc943ca197f42d602c22966e40eb4230381a12da8d5a8c9c1ba31c8a857cbb3376a7d046b5e27567680abc2c10f4fde972371fd8b3005fc536f998834139061bfe8291aa641c767cd6996d7684d36bf388da4ea8ff26685625f4c757520df5772af2d2e1029009562628aad1acdc91d924269eb44d6e1427ffda09c46e44dcfac8bf46d3cd8139c20109e61966695176386ff8fd289ef9d62419824283ba656b9e744ad49eb0345375e1d3cefbc11c2a09f4309d9b33edf38de9dbbf2656198459b5bd051b18b1dc8ccd5edc87fe45b85e6b083b52c1748e16f4952609278705daa1475b83669922dd1168db67b4ea7dbfa1526e9bd89f3c30a4334fd198ce05f3dfcc4358cd1682428890d795541fea9b405447ee485d0ff
\ No newline at end of file
+#33fbe913c63f0fa0f0893ef55e3f6af4895e599092b2f002692e055f221a53df9b32f5642ce0d85df2d6f7a8eb74aaea23ff3e3b7b60db9bb7746ea8383c9a3c9950c8a1eef3573bd88760d605dd513dee435968c36503c87cc5ae59e2bc32406922fc801a2ce114f12134c6fdc40207a08a93164c44591824222cd0fd6eb7e13255257ba3359d2d2026c8404e351949788c32d159018219ac53b5ca362e86c0c8d6e44158ee39d142f6b2326d16c1616ca86e2f17299d2df53dedd7af1a7f7ff5ed61aa78881f3f4ecf612ca5b170c780122bb4c7cd53dfe3cb421bd78b1748f611b3de86357a98e0258e08480b8d0e3a81978565a11db28a2ba288e6f1271b01b93561e35e7aa1107801896afd249b9ba60c5557bf1040656c6e6d790a72f6dfeedf5cf4b7270e90a897e5b86964bf1c87f6c3c49f2df6e6474f2b4397c2804d16b69d289440e8763373ed5fd73f967203e65b0aec8ef83add0a286c41c4d324faa94b0dd1fd6b0f49ab61755317a954dada3b2661e24afef5cc9721f6ac9a8468b0b051c98993202e4dabb0607dc98720712adc9f567613d3237491a7933881a7efa57f2ff6776b6d49674c24e334ce3d6a006d2b5e7e0d9c6b5253688bd86ba462bd2df37b5ece8a1050b9379f9da0e0fea97868eaaff566d2f5ad34f71456495138244bf983be36be53a90ecc1c2b712bdb123391296a7c770bfff48590
\ No newline at end of file
From 6a64f8cfd22699924a234954a8e7378e6a6785a0 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 13 Jan 2023 12:01:52 -0500
Subject: [PATCH 012/145] Experimental change to Table.get. Using the tkinter
widget's selection method. Looks like it could work.
---
PySimpleGUI.py | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 294d80bb..158de052 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.139 Unreleased"
+version = __version__ = "4.60.4.140 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -344,7 +344,9 @@ _change_log = """
4.60.4.138
Added begin_at_sunday_plus to the CalendarButton docstring
4.60.4.139
- Moved debugger constants to sinde of the debugger class. Simplified the locals and globals popups.
+ Moved debugger constants to inside of the debugger class. Simplified the locals and globals popups.
+ 4.60.4.140
+ Experimental change.... Table.get now returns the values from the widget's selection method
"""
@@ -9284,15 +9286,14 @@ class Table(Element):
def get(self):
"""
- Dummy function for tkinter port. In the Qt port you can read back the values in the table in case they were
- edited. Don't know yet how to enable editing of a Tree in tkinter so just returning the values provided by
- user when Table was created or Updated.
+ Get the selected rows using tktiner's selection method. Experimenting with this change....
- :return: the current table values (for now what was originally provided up updated)
+ :return: the current table values
:rtype: List[List[Any]]
"""
- return self.Values
-
+ selections = self.TKTreeview.selection()
+ selected_rows = [int(x) - 1 for x in selections]
+ return selected_rows
def get_last_clicked_position(self):
"""
@@ -26250,4 +26251,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#33fbe913c63f0fa0f0893ef55e3f6af4895e599092b2f002692e055f221a53df9b32f5642ce0d85df2d6f7a8eb74aaea23ff3e3b7b60db9bb7746ea8383c9a3c9950c8a1eef3573bd88760d605dd513dee435968c36503c87cc5ae59e2bc32406922fc801a2ce114f12134c6fdc40207a08a93164c44591824222cd0fd6eb7e13255257ba3359d2d2026c8404e351949788c32d159018219ac53b5ca362e86c0c8d6e44158ee39d142f6b2326d16c1616ca86e2f17299d2df53dedd7af1a7f7ff5ed61aa78881f3f4ecf612ca5b170c780122bb4c7cd53dfe3cb421bd78b1748f611b3de86357a98e0258e08480b8d0e3a81978565a11db28a2ba288e6f1271b01b93561e35e7aa1107801896afd249b9ba60c5557bf1040656c6e6d790a72f6dfeedf5cf4b7270e90a897e5b86964bf1c87f6c3c49f2df6e6474f2b4397c2804d16b69d289440e8763373ed5fd73f967203e65b0aec8ef83add0a286c41c4d324faa94b0dd1fd6b0f49ab61755317a954dada3b2661e24afef5cc9721f6ac9a8468b0b051c98993202e4dabb0607dc98720712adc9f567613d3237491a7933881a7efa57f2ff6776b6d49674c24e334ce3d6a006d2b5e7e0d9c6b5253688bd86ba462bd2df37b5ece8a1050b9379f9da0e0fea97868eaaff566d2f5ad34f71456495138244bf983be36be53a90ecc1c2b712bdb123391296a7c770bfff48590
\ No newline at end of file
+#54251a437ae53503c980748d9b49f5e541745a71f9633a639b5d1df4f2ce9722d3521a73a57c87dcf17e57225f46f455ccf04dbe5066e1c09e19830a9ab3866b40f91f8af4093c954e5c608f8eb49d7e1d82b9db4b9a680fde861b4c55b5ccb68e918710b9df3395fc5f156c88ab737739dde188ca4ae0e7559179b06d9573e18eb597cee9a8dc7363380e5bbeee99aef17f5b81ed8d06e533b4a38e1b1ed79a2fc4ad4e9a19f93042ac1f5eb637b2875694b65908f35888aa27fbb2361599332411117fa5a6090eace1b0d3f749a6ccbbf52f80b39cf04fd7dacaeb79893792017f79da8749338b4dbb4e9203f17a1728248a323d6f67c09a1052e44f2ccb821b0c7b6c41ce2d52fec97ffcd02e3257853d3691e5c6bc6ed9ada4eef49174560dad6e7d25c8346c1f634e759dd4d07e71363809c39d54ecacfaf662231a43e76d253d332a2eccde36823ea99d14bf6c62ace0cedcf815045deb9839efa7b5407fed7ce368059a19a50692b16c429cecebdbb62bcf46d4f66fa43647c4a03453fabc56f18a4ac92a8225bdb6fbb6d968fd189889392c0377d4b2ca34b45683a3ae5efdb959a06dd3e61ddf3d2a7dd3f4da60aecb3912277dc53534c74a2f768563ad77819269d9c39ed11194666e6a0f0c9581bcfb7cbb0afa19731500e1e4f9d92de8bc2ab3fa835dfe454b6dffb6e215a94c2ae5b03b1c7a75876880494dcc
\ No newline at end of file
From 805727fed9b28998564a641c5d5258443e999d50 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 13 Jan 2023 14:30:33 -0500
Subject: [PATCH 013/145] Get the latest docstrings from PySimpleGUI on github
so that the SDK docs online match.
---
docs/call reference.md | 35 ++++++++++++++-----------
docs/index.md | 8 +++---
readme_creator/output/call reference.md | 35 ++++++++++++++-----------
readme_creator/output/index.md | 8 +++---
4 files changed, 46 insertions(+), 40 deletions(-)
diff --git a/docs/call reference.md b/docs/call reference.md
index b2037bda..ad33251c 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -11420,15 +11420,13 @@ Parameter Descriptions:
### get
-Dummy function for tkinter port. In the Qt port you can read back the values in the table in case they were
-edited. Don't know yet how to enable editing of a Tree in tkinter so just returning the values provided by
-user when Table was created or Updated.
+Get the selected rows using tktiner's selection method. Experimenting with this change....
`get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values (for now what was originally provided up updated) |
+|List[List[Any]]| **return** | the current table values |
### get_next_focus
@@ -11652,15 +11650,13 @@ The following methods are here for backwards compatibility reference. You will
### Get
-Dummy function for tkinter port. In the Qt port you can read back the values in the table in case they were
-edited. Don't know yet how to enable editing of a Tree in tkinter so just returning the values provided by
-user when Table was created or Updated.
+Get the selected rows using tktiner's selection method. Experimenting with this change....
`Get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values (for now what was originally provided up updated) |
+|List[List[Any]]| **return** | the current table values |
### SetFocus
@@ -14919,6 +14915,7 @@ Parameter Descriptions:
| str or int or tuple or object | k | Same as the Key. You can use either k or key. Which ever is set will be used. |
| str | locale | defines the locale used to get day names |
| str | format | formats result using this strftime format |
+| int | begin_at_sunday_plus | Determines the left-most day in the display. 0=sunday, 1=monday, etc |
| List[str] | month_names | optional list of month names to use (should be 12 items) |
| List[str] | day_abbreviations | optional list of abbreviations to display as the day of week |
| str | title | Title shown on the date chooser window |
@@ -16571,11 +16568,11 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | title | text to display in eleemnt |
+| str | title | text to display in titlebar of window |
| int | current_value | current value |
-| int | max_value | max value of QuickMeter |
-| Any | *args | stuff to output |
-| str or int or tuple or object | key | Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
+| int | max_value | max value of progress meter |
+| Any | *args | stuff to output as text in the window along with the meter |
+| str or int or tuple or object | key | Used to differentiate between multiple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
| str | orientation | 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') |
| (str, str) or str | bar_color | The 2 colors that make up a progress bar. Either a tuple of 2 strings or a string. Tuple - (bar, background). A string with 1 color changes the background of the bar only. A string with 2 colors separated by "on" like "red on blue" specifies a red bar on a blue background. |
| (str, str) or str | button_color | button color (foreground, background) |
@@ -16625,11 +16622,11 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | title | text to display in eleemnt |
+| str | title | text to display in titlebar of window |
| int | current_value | current value |
-| int | max_value | max value of QuickMeter |
-| Any | *args | stuff to output |
-| str or int or tuple or object | key | Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
+| int | max_value | max value of progress meter |
+| Any | *args | stuff to output as text in the window along with the meter |
+| str or int or tuple or object | key | Used to differentiate between multiple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
| str | orientation | 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') |
| (str, str) or str | bar_color | The 2 colors that make up a progress bar. Either a tuple of 2 strings or a string. Tuple - (bar, background). A string with 1 color changes the background of the bar only. A string with 2 colors separated by "on" like "red on blue" specifies a red bar on a blue background. |
| (str, str) or str | button_color | button color (foreground, background) |
@@ -16942,6 +16939,9 @@ popup_get_date(start_mon = None,
locale = None,
month_names = None,
day_abbreviations = None,
+ day_font = "TkFixedFont 9",
+ mon_year_font = "TkFixedFont 10",
+ arrow_font = "TkFixedFont 7",
modal = True)
```
@@ -16963,6 +16963,9 @@ Parameter Descriptions:
| bool | keep_on_top | If True the window will remain above all current windows |
| List[str] | month_names | optional list of month names to use (should be 12 items) |
| List[str] | day_abbreviations | optional list of abbreviations to display as the day of week |
+| str or tuple | day_font | Font and size to use for the calendar |
+| str or tuple | mon_year_font | Font and size to use for the month and year at the top |
+| str or tuple | arrow_font | Font and size to use for the arrow buttons |
| bool | modal | If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True |
| None or (int, int, int) | **RETURN** | Tuple containing (month, day, year) of chosen date or None if was cancelled
diff --git a/docs/index.md b/docs/index.md
index 52331638..b851cf66 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -2078,11 +2078,11 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | title | text to display in eleemnt |
+| str | title | text to display in titlebar of window |
| int | current_value | current value |
-| int | max_value | max value of QuickMeter |
-| Any | *args | stuff to output |
-| str or int or tuple or object | key | Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
+| int | max_value | max value of progress meter |
+| Any | *args | stuff to output as text in the window along with the meter |
+| str or int or tuple or object | key | Used to differentiate between multiple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
| str | orientation | 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') |
| (str, str) or str | bar_color | The 2 colors that make up a progress bar. Either a tuple of 2 strings or a string. Tuple - (bar, background). A string with 1 color changes the background of the bar only. A string with 2 colors separated by "on" like "red on blue" specifies a red bar on a blue background. |
| (str, str) or str | button_color | button color (foreground, background) |
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index b2037bda..ad33251c 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -11420,15 +11420,13 @@ Parameter Descriptions:
### get
-Dummy function for tkinter port. In the Qt port you can read back the values in the table in case they were
-edited. Don't know yet how to enable editing of a Tree in tkinter so just returning the values provided by
-user when Table was created or Updated.
+Get the selected rows using tktiner's selection method. Experimenting with this change....
`get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values (for now what was originally provided up updated) |
+|List[List[Any]]| **return** | the current table values |
### get_next_focus
@@ -11652,15 +11650,13 @@ The following methods are here for backwards compatibility reference. You will
### Get
-Dummy function for tkinter port. In the Qt port you can read back the values in the table in case they were
-edited. Don't know yet how to enable editing of a Tree in tkinter so just returning the values provided by
-user when Table was created or Updated.
+Get the selected rows using tktiner's selection method. Experimenting with this change....
`Get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values (for now what was originally provided up updated) |
+|List[List[Any]]| **return** | the current table values |
### SetFocus
@@ -14919,6 +14915,7 @@ Parameter Descriptions:
| str or int or tuple or object | k | Same as the Key. You can use either k or key. Which ever is set will be used. |
| str | locale | defines the locale used to get day names |
| str | format | formats result using this strftime format |
+| int | begin_at_sunday_plus | Determines the left-most day in the display. 0=sunday, 1=monday, etc |
| List[str] | month_names | optional list of month names to use (should be 12 items) |
| List[str] | day_abbreviations | optional list of abbreviations to display as the day of week |
| str | title | Title shown on the date chooser window |
@@ -16571,11 +16568,11 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | title | text to display in eleemnt |
+| str | title | text to display in titlebar of window |
| int | current_value | current value |
-| int | max_value | max value of QuickMeter |
-| Any | *args | stuff to output |
-| str or int or tuple or object | key | Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
+| int | max_value | max value of progress meter |
+| Any | *args | stuff to output as text in the window along with the meter |
+| str or int or tuple or object | key | Used to differentiate between multiple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
| str | orientation | 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') |
| (str, str) or str | bar_color | The 2 colors that make up a progress bar. Either a tuple of 2 strings or a string. Tuple - (bar, background). A string with 1 color changes the background of the bar only. A string with 2 colors separated by "on" like "red on blue" specifies a red bar on a blue background. |
| (str, str) or str | button_color | button color (foreground, background) |
@@ -16625,11 +16622,11 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | title | text to display in eleemnt |
+| str | title | text to display in titlebar of window |
| int | current_value | current value |
-| int | max_value | max value of QuickMeter |
-| Any | *args | stuff to output |
-| str or int or tuple or object | key | Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
+| int | max_value | max value of progress meter |
+| Any | *args | stuff to output as text in the window along with the meter |
+| str or int or tuple or object | key | Used to differentiate between multiple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
| str | orientation | 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') |
| (str, str) or str | bar_color | The 2 colors that make up a progress bar. Either a tuple of 2 strings or a string. Tuple - (bar, background). A string with 1 color changes the background of the bar only. A string with 2 colors separated by "on" like "red on blue" specifies a red bar on a blue background. |
| (str, str) or str | button_color | button color (foreground, background) |
@@ -16942,6 +16939,9 @@ popup_get_date(start_mon = None,
locale = None,
month_names = None,
day_abbreviations = None,
+ day_font = "TkFixedFont 9",
+ mon_year_font = "TkFixedFont 10",
+ arrow_font = "TkFixedFont 7",
modal = True)
```
@@ -16963,6 +16963,9 @@ Parameter Descriptions:
| bool | keep_on_top | If True the window will remain above all current windows |
| List[str] | month_names | optional list of month names to use (should be 12 items) |
| List[str] | day_abbreviations | optional list of abbreviations to display as the day of week |
+| str or tuple | day_font | Font and size to use for the calendar |
+| str or tuple | mon_year_font | Font and size to use for the month and year at the top |
+| str or tuple | arrow_font | Font and size to use for the arrow buttons |
| bool | modal | If True then makes the popup will behave like a Modal window... all other windows are non-operational until this one is closed. Default = True |
| None or (int, int, int) | **RETURN** | Tuple containing (month, day, year) of chosen date or None if was cancelled
diff --git a/readme_creator/output/index.md b/readme_creator/output/index.md
index 52331638..b851cf66 100644
--- a/readme_creator/output/index.md
+++ b/readme_creator/output/index.md
@@ -2078,11 +2078,11 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | title | text to display in eleemnt |
+| str | title | text to display in titlebar of window |
| int | current_value | current value |
-| int | max_value | max value of QuickMeter |
-| Any | *args | stuff to output |
-| str or int or tuple or object | key | Used to differentiate between mutliple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
+| int | max_value | max value of progress meter |
+| Any | *args | stuff to output as text in the window along with the meter |
+| str or int or tuple or object | key | Used to differentiate between multiple meters. Used to cancel meter early. Now optional as there is a default value for single meters |
| str | orientation | 'horizontal' or 'vertical' ('h' or 'v' work) (Default value = 'vertical' / 'v') |
| (str, str) or str | bar_color | The 2 colors that make up a progress bar. Either a tuple of 2 strings or a string. Tuple - (bar, background). A string with 1 color changes the background of the bar only. A string with 2 colors separated by "on" like "red on blue" specifies a red bar on a blue background. |
| (str, str) or str | button_color | button color (foreground, background) |
From 4ca5cf084a1e7ca993a0250d4e6fbb3d8a4e0996 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 15 Jan 2023 10:39:30 -0500
Subject: [PATCH 014/145] Made the Debugger's use of popups change the theme to
the same dark gray theme used in the rest of the debugger windows. Fixed bug
introduced when constants were moved into the class.
---
PySimpleGUI.py | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 158de052..69618f3a 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.140 Unreleased"
+version = __version__ = "4.60.4.141 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -347,6 +347,8 @@ _change_log = """
Moved debugger constants to inside of the debugger class. Simplified the locals and globals popups.
4.60.4.140
Experimental change.... Table.get now returns the values from the widget's selection method
+ 4.60.4.141
+ Made the Debugger's use of popups change the theme to the same dark gray theme used in the rest of the debugger windows.
"""
@@ -23804,7 +23806,10 @@ class _Debugger:
result = str(eval(str(var), myglobals, mylocals))
except:
result = ''
+ old_theme = theme()
+ theme(_Debugger.DEBUGGER_MAIN_WINDOW_THEME)
popup_scrolled(str(values['_VAR{}_'.format(event[4])]) + '\n' + result, title=var, non_blocking=True, font=_Debugger.DEBUGGER_VARIABLE_DETAILS_FONT)
+ theme(old_theme)
# BUTTON - OBJ
elif event.endswith('_OBJ_'): # OBJECT BUTTON
var = values['_VAR{}_'.format(event[4])]
@@ -23816,7 +23821,10 @@ class _Debugger:
result = ObjToStringSingleObj(result)
except Exception as e:
result = '{}\nError showing object {}'.format(e, var)
- popup_scrolled(str(var) + '\n' + str(result), title=var, non_blocking=True, font=Debugger.DEBUGGER_VARIABLE_DETAILS_FONT)
+ old_theme = theme()
+ theme(_Debugger.DEBUGGER_MAIN_WINDOW_THEME)
+ popup_scrolled(str(var) + '\n' + str(result), title=var, non_blocking=True, font=_Debugger.DEBUGGER_VARIABLE_DETAILS_FONT)
+ theme(old_theme)
# ------------------------------- Process Watch Tab -------------------------------
# BUTTON - Choose Locals to see
elif event == '-LOCALS-': # Show all locals BUTTON
@@ -26251,4 +26259,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#54251a437ae53503c980748d9b49f5e541745a71f9633a639b5d1df4f2ce9722d3521a73a57c87dcf17e57225f46f455ccf04dbe5066e1c09e19830a9ab3866b40f91f8af4093c954e5c608f8eb49d7e1d82b9db4b9a680fde861b4c55b5ccb68e918710b9df3395fc5f156c88ab737739dde188ca4ae0e7559179b06d9573e18eb597cee9a8dc7363380e5bbeee99aef17f5b81ed8d06e533b4a38e1b1ed79a2fc4ad4e9a19f93042ac1f5eb637b2875694b65908f35888aa27fbb2361599332411117fa5a6090eace1b0d3f749a6ccbbf52f80b39cf04fd7dacaeb79893792017f79da8749338b4dbb4e9203f17a1728248a323d6f67c09a1052e44f2ccb821b0c7b6c41ce2d52fec97ffcd02e3257853d3691e5c6bc6ed9ada4eef49174560dad6e7d25c8346c1f634e759dd4d07e71363809c39d54ecacfaf662231a43e76d253d332a2eccde36823ea99d14bf6c62ace0cedcf815045deb9839efa7b5407fed7ce368059a19a50692b16c429cecebdbb62bcf46d4f66fa43647c4a03453fabc56f18a4ac92a8225bdb6fbb6d968fd189889392c0377d4b2ca34b45683a3ae5efdb959a06dd3e61ddf3d2a7dd3f4da60aecb3912277dc53534c74a2f768563ad77819269d9c39ed11194666e6a0f0c9581bcfb7cbb0afa19731500e1e4f9d92de8bc2ab3fa835dfe454b6dffb6e215a94c2ae5b03b1c7a75876880494dcc
\ No newline at end of file
+#4db6b98b71ad586548e87cc9e4d297e44fcf6242b3833a738c844f448f1e5c7ddc085afd61eabde9bb8750619f12db065e69640cebf5edf9f4b745c4a3caf5e1670d2d8ad3a7e8090bdca1322ccad1c69967e866aef3c1bd5e118d3de7cba9e6f8b96b334ba3add026cddd8ce35be473577d5be009100e3ffb4ec78807b3916a8e40f292032ef67ba342ab9a971f3aac089684e21da209b728eaf8b9f0a7158b9aae4139f0212e1909a961c60951b56ffe832778b6537f85e29d5a77b4444fcf680a48a4340a4be5d910b11ce0e5675ac40a7f556ba062602c1cf2e19138782546118b343fae8c7bcd9765318996f5c7ebd1f7a7d079839d9456320d14cd2e62a14be59f40d25b11d1cfe1b902304f87bb27bbbc58bff1d1c333bb184b9d3033ee9c60b2bd72d69363708ab0280104c481453b0aee209f4e0c3af21dcbb8e64c165b1284d82a4a9b2ecd89522cb89807f297c5a41ee98a98a3aaf498e65eea040a309f41732f3105858d08266bcf0781fa7cd1ce218968b3e5ac8a660c1335aee944c0cbb17ea4766f603b2fbc10e28da3981d2160e256183e9d52355efe2a22e4c1369fd4e3838923b27e6db641955310a4c3c95cce90a6371d52ef3e7ca8104e0b88ebf340ddc7c133c1b696d5b34d796ebbdeac5e3b419b425b72a0bc0db3d6d572dadaf20abad3e81e7a64e7432af588b3f635202b4cfa6025bd4ca3812f
\ No newline at end of file
From 59cbf6311611212efdde8d78b5d25c5a3ed8ee81 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Wed, 18 Jan 2023 14:13:43 -0500
Subject: [PATCH 015/145] Added selected_text_color & selected_background_color
to Input element as an experiment
---
PySimpleGUI.py | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 69618f3a..2883f756 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.141 Unreleased"
+version = __version__ = "4.60.4.142 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -349,6 +349,8 @@ _change_log = """
Experimental change.... Table.get now returns the values from the widget's selection method
4.60.4.141
Made the Debugger's use of popups change the theme to the same dark gray theme used in the rest of the debugger windows.
+ 4.60.4.142
+ Added selected_text_color & selected_background_color to Input element. Will override the default values
"""
@@ -2287,7 +2289,7 @@ class Input(Element):
def __init__(self, default_text='', size=(None, None), s=(None, None), disabled=False, password_char='',
justification=None, background_color=None, text_color=None, font=None, tooltip=None, border_width=None,
change_submits=False, enable_events=False, do_not_clear=True, key=None, k=None, focus=False, pad=None, p=None,
- use_readonly_for_disable=True, readonly=False, disabled_readonly_background_color=None, disabled_readonly_text_color=None, expand_x=False, expand_y=False,
+ use_readonly_for_disable=True, readonly=False, disabled_readonly_background_color=None, disabled_readonly_text_color=None, selected_text_color=None, selected_background_color=None, expand_x=False, expand_y=False,
right_click_menu=None, visible=True, metadata=None):
"""
:param default_text: Text initially shown in the input box as a default value(Default value = ''). Will automatically be converted to string
@@ -2336,6 +2338,10 @@ class Input(Element):
:type disabled_readonly_background_color: (str)
:param disabled_readonly_text_color: If state is set to readonly or disabled, the color to use for the text
:type disabled_readonly_text_color: (str)
+ :param selected_text_color: Color of text when it is selected (using mouse or control+A, etc)
+ :type selected_text_color: (str)
+ :param selected_background_color: Color of background when it is selected (using mouse or control+A, etc)
+ :type selected_background_color: (str)
:param expand_x: If True the element will automatically expand in the X direction to fill available space
:type expand_x: (bool)
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
@@ -2353,6 +2359,8 @@ class Input(Element):
self.PasswordCharacter = password_char
bg = background_color if background_color is not None else DEFAULT_INPUT_ELEMENTS_COLOR
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
+ self.seclected_text_color = selected_text_color
+ self.selected_background_color = selected_background_color
self.Focus = focus
self.do_not_clear = do_not_clear
self.Justification = justification
@@ -16425,11 +16433,15 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
element.TKEntry.bind('', element._KeyboardHandler)
element.TKEntry.bind('', element._ReturnKeyHandler)
+
if element.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT):
element.TKEntry.configure(background=element.BackgroundColor, selectforeground=element.BackgroundColor)
if text_color not in (None, COLOR_SYSTEM_DEFAULT):
element.TKEntry.configure(fg=text_color, selectbackground=text_color)
-
+ if element.selected_background_color not in (None, COLOR_SYSTEM_DEFAULT):
+ element.TKEntry.configure(selectbackground=element.selected_background_color)
+ if element.seclected_text_color not in (None, COLOR_SYSTEM_DEFAULT):
+ element.TKEntry.configure(selectforeground=element.seclected_text_color)
if element.disabled_readonly_background_color not in (None, COLOR_SYSTEM_DEFAULT):
element.TKEntry.config(readonlybackground=element.disabled_readonly_background_color)
if element.disabled_readonly_text_color not in (None, COLOR_SYSTEM_DEFAULT):
@@ -26259,4 +26271,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#4db6b98b71ad586548e87cc9e4d297e44fcf6242b3833a738c844f448f1e5c7ddc085afd61eabde9bb8750619f12db065e69640cebf5edf9f4b745c4a3caf5e1670d2d8ad3a7e8090bdca1322ccad1c69967e866aef3c1bd5e118d3de7cba9e6f8b96b334ba3add026cddd8ce35be473577d5be009100e3ffb4ec78807b3916a8e40f292032ef67ba342ab9a971f3aac089684e21da209b728eaf8b9f0a7158b9aae4139f0212e1909a961c60951b56ffe832778b6537f85e29d5a77b4444fcf680a48a4340a4be5d910b11ce0e5675ac40a7f556ba062602c1cf2e19138782546118b343fae8c7bcd9765318996f5c7ebd1f7a7d079839d9456320d14cd2e62a14be59f40d25b11d1cfe1b902304f87bb27bbbc58bff1d1c333bb184b9d3033ee9c60b2bd72d69363708ab0280104c481453b0aee209f4e0c3af21dcbb8e64c165b1284d82a4a9b2ecd89522cb89807f297c5a41ee98a98a3aaf498e65eea040a309f41732f3105858d08266bcf0781fa7cd1ce218968b3e5ac8a660c1335aee944c0cbb17ea4766f603b2fbc10e28da3981d2160e256183e9d52355efe2a22e4c1369fd4e3838923b27e6db641955310a4c3c95cce90a6371d52ef3e7ca8104e0b88ebf340ddc7c133c1b696d5b34d796ebbdeac5e3b419b425b72a0bc0db3d6d572dadaf20abad3e81e7a64e7432af588b3f635202b4cfa6025bd4ca3812f
\ No newline at end of file
+#1a3a9f560ea0d7827ea35a6f671e4232f531fe8510b4d98dd30dcea7e27ea5d820cc220d0146cdb57452d1e869e91c6b5660834e98a0a65495ca9060ac4b84f4398cee2fe2b7e6fd3654ac4f4ce0661a19e370c66aeef8f724677db6b0b8a0b005b2728f6f72079747a33515c3716868d94c2c31e0feec3f8da32947c651b399775130dfaa2bca1ce71f4a65ca4dcde455d0ca46f00863de191f80cf4e894e38c0ec483edc586496c062e51844a7fc77bb68963096c1ecac54ac0073c5d42ada0ef747f26f3752d70de1f8ba55fd66f88751aec8281ca3312b84f7fc11523117118b56f6c153cce8a2d8dde522388e82b633644d8a11da3f8a08eea66c9b56a519c831d11ad717a585f72e933a5cfb77f03c61fd58e978e5e1fc1deb3a6e187b29ce1ade80b3214f78e2fde39106c7c95537a4251d02c55ce773e02c36ced132ba5187c69de894dea2be52ce34fef51286e291a72a7684e5ff5bce381d05af0b70c67c0deb0681f9291d2da87b8523f66b0b1ce1afc248a17aa6c8726f33f440c4ff2de4f07e8ac7b8f05f3a4fa14b502425c465c838d9d7e1fe41d197be17655d37aa399178363147fe9654c495a25abe3f4a4ed4b0ddff35995d26fede35dba2a2358c46b6de8b90e0922402e4a326f74f2d8221f6aaed051881a55e31e8dbe26235f00ef0a624afa171144d6bc0d9df19c41fa5bc2624134809861a76cf62
\ No newline at end of file
From 7e88e04ceeac746ab2c77bb7331a72ddf7ef4cd1 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 20 Jan 2023 17:54:50 -0500
Subject: [PATCH 016/145] Fixed bug in Combo.update - width wasn't getting
updated to match new values
---
PySimpleGUI.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 2883f756..2df041d5 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.142 Unreleased"
+version = __version__ = "4.60.4.143 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -351,6 +351,8 @@ _change_log = """
Made the Debugger's use of popups change the theme to the same dark gray theme used in the rest of the debugger windows.
4.60.4.142
Added selected_text_color & selected_background_color to Input element. Will override the default values
+ 4.60.4.143
+ Fixed bug in Combo.update - the width of the element wasn't getting updated to match new values
"""
@@ -2648,7 +2650,7 @@ class Combo(Element):
width = self.Size[0]
else:
width = max_line_len + 1
- # self.TKCombo.configure(width=width)
+ self.TKCombo.configure(width=width)
else:
self.TKCombo.configure(height=size[1])
self.TKCombo.configure(width=size[0])
@@ -26271,4 +26273,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#1a3a9f560ea0d7827ea35a6f671e4232f531fe8510b4d98dd30dcea7e27ea5d820cc220d0146cdb57452d1e869e91c6b5660834e98a0a65495ca9060ac4b84f4398cee2fe2b7e6fd3654ac4f4ce0661a19e370c66aeef8f724677db6b0b8a0b005b2728f6f72079747a33515c3716868d94c2c31e0feec3f8da32947c651b399775130dfaa2bca1ce71f4a65ca4dcde455d0ca46f00863de191f80cf4e894e38c0ec483edc586496c062e51844a7fc77bb68963096c1ecac54ac0073c5d42ada0ef747f26f3752d70de1f8ba55fd66f88751aec8281ca3312b84f7fc11523117118b56f6c153cce8a2d8dde522388e82b633644d8a11da3f8a08eea66c9b56a519c831d11ad717a585f72e933a5cfb77f03c61fd58e978e5e1fc1deb3a6e187b29ce1ade80b3214f78e2fde39106c7c95537a4251d02c55ce773e02c36ced132ba5187c69de894dea2be52ce34fef51286e291a72a7684e5ff5bce381d05af0b70c67c0deb0681f9291d2da87b8523f66b0b1ce1afc248a17aa6c8726f33f440c4ff2de4f07e8ac7b8f05f3a4fa14b502425c465c838d9d7e1fe41d197be17655d37aa399178363147fe9654c495a25abe3f4a4ed4b0ddff35995d26fede35dba2a2358c46b6de8b90e0922402e4a326f74f2d8221f6aaed051881a55e31e8dbe26235f00ef0a624afa171144d6bc0d9df19c41fa5bc2624134809861a76cf62
\ No newline at end of file
+#05575c0321f1544102608baf59fa822078b0f49b10c74497210f0b121630604b4e499d86b8da16c35e5055a1f4b2439e4d517292dcc71d28ffa0ddd88356b4c858f039198e04890a2545f5c0c202aa4d3dbb213c9fd0582922f29a5b669f16c380fc4b34d78b3af787347e3bf2b6b8b8632bb666239749709ae4f0dd35591964d841408ba1a71dac773e09a71356bb280f6c80d4ff30cb1385b4bd4cc6c930fc79f4b28418e40a30723f26fe5ad64c772e542949029265b1cd66d12b2593f95b48982777759ee64920b9f33a22e3f3aa7dfae01a6eb55782832496ef299a33174991261aa2e8dc76b2d273e8a0c56ac69fdfea2460c7a6299c41182faa0a7bd3d4f85fbef8ba36de2d70381244510ad153df900e371cf4d1b3d2e9c09b00a54503e4504dcbc5ad9b5c50aa0c2fa10d5b0bf94a707fdd594bd92c00e8f675fce40cef403187639ba2ac30c685e7e838faa5d208c47fe18fb31f590dd2ff8a9055894f73fd026d5ef2f8580b6a1a1ea4e7072a2ba64d3185e399fc487a1b828ac8a4802f757d498bfaf7a54e18cb9ae1e4d38e911c4ece4e9cd3ca735f1605b3fec2b5ab52c63791be5a1766169f575e2eb3a63f7185b24864e27019c32aa9470b74d507be1f90b6a05e385d4d8ad22e390a34913b28c265a0b45ed9da45dcad2c7ede9162740333735ed2b686524453e1e8321515c7f08f31e1ee8d9ce74f476b
\ No newline at end of file
From 2492b2353d7e94be2d55fb02b2e0988b1c0d8203 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sat, 21 Jan 2023 15:08:45 -0500
Subject: [PATCH 017/145] Added selected_text_color and
selected_background_color to Multline element
---
PySimpleGUI.py | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 2df041d5..c6940b5c 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.143 Unreleased"
+version = __version__ = "4.60.4.144 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -353,7 +353,9 @@ _change_log = """
Added selected_text_color & selected_background_color to Input element. Will override the default values
4.60.4.143
Fixed bug in Combo.update - the width of the element wasn't getting updated to match new values
-
+ 4.60.4.144
+ Added selected_text_color & selected_background_color to Multiline element. Will override the default values
+
"""
__version__ = version.split()[0] # For PEP 396 and PEP 345
@@ -2361,7 +2363,7 @@ class Input(Element):
self.PasswordCharacter = password_char
bg = background_color if background_color is not None else DEFAULT_INPUT_ELEMENTS_COLOR
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
- self.seclected_text_color = selected_text_color
+ self.selected_text_color = selected_text_color
self.selected_background_color = selected_background_color
self.Focus = focus
self.do_not_clear = do_not_clear
@@ -3735,7 +3737,7 @@ class Multiline(Element):
"""
def __init__(self, default_text='', enter_submits=False, disabled=False, autoscroll=False, border_width=None,
- size=(None, None), s=(None, None), auto_size_text=None, background_color=None, text_color=None, horizontal_scroll=False, change_submits=False,
+ size=(None, None), s=(None, None), auto_size_text=None, background_color=None, text_color=None, selected_text_color=None, selected_background_color=None, horizontal_scroll=False, change_submits=False,
enable_events=False, do_not_clear=True, key=None, k=None, write_only=False, auto_refresh=False, reroute_stdout=False, reroute_stderr=False, reroute_cprint=False, echo_stdout_stderr=False, focus=False, font=None, pad=None, p=None, tooltip=None, justification=None, no_scrollbar=False, wrap_lines=None,
sbar_trough_color=None, sbar_background_color=None, sbar_arrow_color=None, sbar_width=None, sbar_arrow_width=None, sbar_frame_color=None, sbar_relief=None,
expand_x=False, expand_y=False, rstrip=True, right_click_menu=None, visible=True, metadata=None):
@@ -3760,6 +3762,10 @@ class Multiline(Element):
:type background_color: (str)
:param text_color: color of the text
:type text_color: (str)
+ :param selected_text_color: Color of text when it is selected (using mouse or control+A, etc)
+ :type selected_text_color: (str)
+ :param selected_background_color: Color of background when it is selected (using mouse or control+A, etc)
+ :type selected_background_color: (str)
:param horizontal_scroll: Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical
:type horizontal_scroll: (bool)
:param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead
@@ -3835,6 +3841,9 @@ class Multiline(Element):
self.Focus = focus
self.do_not_clear = do_not_clear
fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
+ fg = text_color if text_color is not None else DEFAULT_INPUT_TEXT_COLOR
+ self.selected_text_color = selected_text_color
+ self.selected_background_color = selected_background_color
self.Autoscroll = autoscroll
self.Disabled = disabled
self.ChangeSubmits = change_submits or enable_events
@@ -16442,8 +16451,8 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
element.TKEntry.configure(fg=text_color, selectbackground=text_color)
if element.selected_background_color not in (None, COLOR_SYSTEM_DEFAULT):
element.TKEntry.configure(selectbackground=element.selected_background_color)
- if element.seclected_text_color not in (None, COLOR_SYSTEM_DEFAULT):
- element.TKEntry.configure(selectforeground=element.seclected_text_color)
+ if element.selected_text_color not in (None, COLOR_SYSTEM_DEFAULT):
+ element.TKEntry.configure(selectforeground=element.selected_text_color)
if element.disabled_readonly_background_color not in (None, COLOR_SYSTEM_DEFAULT):
element.TKEntry.config(readonlybackground=element.disabled_readonly_background_color)
if element.disabled_readonly_text_color not in (None, COLOR_SYSTEM_DEFAULT):
@@ -16744,9 +16753,14 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
if element.DefaultText:
element.TKText.insert(1.0, element.DefaultText) # set the default text
element.TKText.config(highlightthickness=0)
+ if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
+ element.TKText.configure(fg=text_color, selectbackground=text_color)
if element.BackgroundColor is not None and element.BackgroundColor != COLOR_SYSTEM_DEFAULT:
element.TKText.configure(background=element.BackgroundColor, selectforeground=element.BackgroundColor)
-
+ if element.selected_background_color not in (None, COLOR_SYSTEM_DEFAULT):
+ element.TKText.configure(selectbackground=element.selected_background_color)
+ if element.selected_text_color not in (None, COLOR_SYSTEM_DEFAULT):
+ element.TKText.configure(selectforeground=element.selected_text_color)
element.TKText.tag_configure("center", justify='center')
element.TKText.tag_configure("left", justify='left')
element.TKText.tag_configure("right", justify='right')
@@ -16781,8 +16795,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
if element.Focus is True or (toplevel_form.UseDefaultFocus and not toplevel_form.FocusSet):
toplevel_form.FocusSet = True
element.TKText.focus_set()
- if text_color is not None and text_color != COLOR_SYSTEM_DEFAULT:
- element.TKText.configure(fg=text_color, selectbackground=text_color)
+
if element.Disabled is True:
@@ -26273,4 +26286,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#05575c0321f1544102608baf59fa822078b0f49b10c74497210f0b121630604b4e499d86b8da16c35e5055a1f4b2439e4d517292dcc71d28ffa0ddd88356b4c858f039198e04890a2545f5c0c202aa4d3dbb213c9fd0582922f29a5b669f16c380fc4b34d78b3af787347e3bf2b6b8b8632bb666239749709ae4f0dd35591964d841408ba1a71dac773e09a71356bb280f6c80d4ff30cb1385b4bd4cc6c930fc79f4b28418e40a30723f26fe5ad64c772e542949029265b1cd66d12b2593f95b48982777759ee64920b9f33a22e3f3aa7dfae01a6eb55782832496ef299a33174991261aa2e8dc76b2d273e8a0c56ac69fdfea2460c7a6299c41182faa0a7bd3d4f85fbef8ba36de2d70381244510ad153df900e371cf4d1b3d2e9c09b00a54503e4504dcbc5ad9b5c50aa0c2fa10d5b0bf94a707fdd594bd92c00e8f675fce40cef403187639ba2ac30c685e7e838faa5d208c47fe18fb31f590dd2ff8a9055894f73fd026d5ef2f8580b6a1a1ea4e7072a2ba64d3185e399fc487a1b828ac8a4802f757d498bfaf7a54e18cb9ae1e4d38e911c4ece4e9cd3ca735f1605b3fec2b5ab52c63791be5a1766169f575e2eb3a63f7185b24864e27019c32aa9470b74d507be1f90b6a05e385d4d8ad22e390a34913b28c265a0b45ed9da45dcad2c7ede9162740333735ed2b686524453e1e8321515c7f08f31e1ee8d9ce74f476b
\ No newline at end of file
+#4e3d3948980125933466017e428c1dc993601ea86dfe8356c300cf2b0cfcb6441b6bdd5efcd5787f432fa4ba558cfa0243d09ec1ed5d78c5d2b25639ac4a7ec9bbddea5d00379aab0d46996b8dab188d0d361470abe50841d6e7bfa102c8cbacb60734b261f7bd81fbd66498e0b1890822902dc4c16a29914c39d78c10ae462b4e00093bd28fe7fb1ca8a1a43ec4e56b29fa1a6d38feff72885e38ba37f727ec7b0eaece73e8c49e7b2fa3563f06fa9e3e9575596d5824a490510b412fc67f40c4713d27d74d7e0065741b7f05dd9b00715fde6f877867e828f51c34b31091e72b47a7afa600d4eb27d4b9f1971ef181b0f44ff0d0e2a355aca1bf98da4660d2f58a7b65b680e51f16d65ffe2f5e4151434dd2bf3c726e65bc1e863e080b61a4241b2e5e59558eb637a34b557b1ae44fcaf75aa25db7d4dc782d4d9c8e190e9b6093a69706ae98937ee96c5cd98242378e58159f65b90042077d26ccc62e4425c80abefc0d5e44dd757255be58bf8c8831d2ccab684fdd0950db23deaea9d3bbb96fe87c4b361c2ee7e072422718bfdf1fe7b082856a264d3148a11ffc2a2a5b64898133a6275b774b32114415daf11bd17ee3c3c6f9cc42d47bdc12cb6f418db25215be6341ade53528529e907d5d18adf34b4c2990425b3739556cf652ad08b64d1b2ed93dbc1b4c0991ea95efce22b0ab1f1476827ce51c56b972b1286176
\ No newline at end of file
From de3beca51a853558b9f309222d5a78d1ff402eb8 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 22 Jan 2023 10:11:51 -0500
Subject: [PATCH 018/145] Fixed bind_return_key docstrings in the pre-defined
buttons. Made the Button bind_return_key docstring more descriptive
---
PySimpleGUI.py | 50 ++++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index c6940b5c..43ddf381 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.144 Unreleased"
+version = __version__ = "4.60.4.145 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -355,6 +355,8 @@ _change_log = """
Fixed bug in Combo.update - the width of the element wasn't getting updated to match new values
4.60.4.144
Added selected_text_color & selected_background_color to Multiline element. Will override the default values
+ 4.60.4.145
+ Fixed bind_return_key docstrings in the pre-defined buttons. Made the Button bind_return_key docstring more descriptive
"""
@@ -2529,7 +2531,7 @@ class Combo(Element):
:type button_background_color: (str)
:param button_arrow_color: The color of the arrow on the button on the combo box
:type button_arrow_color: (str)
- :param bind_return_key: If True, then the return key will cause a the Combo to generate an event
+ :param bind_return_key: If True, then the return key will cause a the Combo to generate an event when return key is pressed
:type bind_return_key: (bool)
:param change_submits: DEPRICATED DO NOT USE. Use `enable_events` instead
:type change_submits: (bool)
@@ -2896,7 +2898,7 @@ class Listbox(Element):
:type change_submits: (bool)
:param enable_events: Turns on the element specific events. Listbox generates events when an item is clicked
:type enable_events: (bool)
- :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event when return key is pressed
:type bind_return_key: (bool)
:param size: w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1
:type size: (int, int) | (int, None) | int
@@ -3562,7 +3564,7 @@ class Spin(Element):
:type s: (int, int) | (None, None) | int
:param auto_size_text: if True will size the element to match the length of the text
:type auto_size_text: (bool)
- :param bind_return_key: If True, then the return key will cause a the element to generate an event
+ :param bind_return_key: If True, then the return key will cause a the element to generate an event when return key is pressed
:type bind_return_key: (bool)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
@@ -4881,7 +4883,7 @@ class Button(Element):
:type use_ttk_buttons: (bool)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: If True the return key will cause this button to be pressed
+ :param bind_return_key: If True then pressing the return key in an Input or Multiline Element will cause this button to appear to be clicked (generates event with this button's key
:type bind_return_key: (bool)
:param focus: if True, initial focus will be put on this button
:type focus: (bool)
@@ -13726,7 +13728,7 @@ def Save(button_text='Save', size=(None, None), s=(None, None), auto_size_button
:type auto_size_button: (bool)
:param button_color: button color (foreground, background)
:type button_color: (str, str) | str
- :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
@@ -13777,7 +13779,7 @@ def Submit(button_text='Submit', size=(None, None), s=(None, None), auto_size_bu
:type button_color: (str, str) | str
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
- :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
@@ -13827,7 +13829,7 @@ def Open(button_text='Open', size=(None, None), s=(None, None), auto_size_button
:type button_color: (str, str) | str
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
- :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
@@ -13876,7 +13878,7 @@ def OK(button_text='OK', size=(None, None), s=(None, None), auto_size_button=Non
:type button_color: (str, str) | str
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
- :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
@@ -13925,7 +13927,7 @@ def Ok(button_text='Ok', size=(None, None), s=(None, None), auto_size_button=Non
:type button_color: (str, str) | str
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
- :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
@@ -13978,7 +13980,7 @@ def Cancel(button_text='Cancel', size=(None, None), s=(None, None), auto_size_bu
:type tooltip: (str)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus:
@@ -14027,7 +14029,7 @@ def Quit(button_text='Quit', size=(None, None), s=(None, None), auto_size_button
:type tooltip: (str)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus: (bool)
@@ -14076,7 +14078,7 @@ def Exit(button_text='Exit', size=(None, None), s=(None, None), auto_size_button
:type tooltip: (str)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus:
@@ -14125,7 +14127,7 @@ def Yes(button_text='Yes', size=(None, None), s=(None, None), auto_size_button=N
:type tooltip: (str)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = True) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus:
@@ -14223,7 +14225,7 @@ def Help(button_text='Help', size=(None, None), s=(None, None), auto_size_button
:type font: (str or (str, int[, str]) or None)
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus:
@@ -14275,7 +14277,7 @@ def Debug(button_text='', size=(None, None), s=(None, None), auto_size_button=No
:type font: (str or (str, int[, str]) or None)
:param tooltip: text, that will appear when mouse hovers over the element
:type tooltip: (str)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus:
@@ -14339,7 +14341,7 @@ def SimpleButton(button_text, image_filename=None, image_data=None, image_size=(
:type button_color: (str, str) | str
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
@@ -14401,7 +14403,7 @@ def CloseButton(button_text, image_filename=None, image_data=None, image_size=(N
:type button_color: (str, str) | str
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
@@ -14461,7 +14463,7 @@ def ReadButton(button_text, image_filename=None, image_data=None, image_size=(No
:type button_color: (str, str) | str
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
@@ -14530,7 +14532,7 @@ def RealtimeButton(button_text, image_filename=None, image_data=None, image_size
:type font: (str or (str, int[, str]) or None)
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus: (bool)
@@ -14598,7 +14600,7 @@ def DummyButton(button_text, image_filename=None, image_data=None, image_size=(N
:type font: (str or (str, int[, str]) or None)
:param disabled: set disable state for element (Default = False)
:type disabled: (bool)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: if focus should be set to this
:type focus: (bool)
@@ -14671,7 +14673,7 @@ def CalendarButton(button_text, target=(ThisRow, -1), close_when_date_chosen=Tru
:type disabled: (bool)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: (Default = False) If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: bool
:param focus: if focus should be set to this
:type focus: bool
@@ -14765,7 +14767,7 @@ def ColorChooserButton(button_text, target=(ThisRow, -1), image_filename=None, i
:type disabled: (bool)
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
:type font: (str or (str, int[, str]) or None)
- :param bind_return_key: If True, then the return key will cause a the Listbox to generate an event
+ :param bind_return_key: (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options
:type bind_return_key: (bool)
:param focus: Determines if initial focus should go to this element.
:type focus: (bool)
@@ -26286,4 +26288,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#4e3d3948980125933466017e428c1dc993601ea86dfe8356c300cf2b0cfcb6441b6bdd5efcd5787f432fa4ba558cfa0243d09ec1ed5d78c5d2b25639ac4a7ec9bbddea5d00379aab0d46996b8dab188d0d361470abe50841d6e7bfa102c8cbacb60734b261f7bd81fbd66498e0b1890822902dc4c16a29914c39d78c10ae462b4e00093bd28fe7fb1ca8a1a43ec4e56b29fa1a6d38feff72885e38ba37f727ec7b0eaece73e8c49e7b2fa3563f06fa9e3e9575596d5824a490510b412fc67f40c4713d27d74d7e0065741b7f05dd9b00715fde6f877867e828f51c34b31091e72b47a7afa600d4eb27d4b9f1971ef181b0f44ff0d0e2a355aca1bf98da4660d2f58a7b65b680e51f16d65ffe2f5e4151434dd2bf3c726e65bc1e863e080b61a4241b2e5e59558eb637a34b557b1ae44fcaf75aa25db7d4dc782d4d9c8e190e9b6093a69706ae98937ee96c5cd98242378e58159f65b90042077d26ccc62e4425c80abefc0d5e44dd757255be58bf8c8831d2ccab684fdd0950db23deaea9d3bbb96fe87c4b361c2ee7e072422718bfdf1fe7b082856a264d3148a11ffc2a2a5b64898133a6275b774b32114415daf11bd17ee3c3c6f9cc42d47bdc12cb6f418db25215be6341ade53528529e907d5d18adf34b4c2990425b3739556cf652ad08b64d1b2ed93dbc1b4c0991ea95efce22b0ab1f1476827ce51c56b972b1286176
\ No newline at end of file
+#40e80a71aea2a1b41dfdcba9263cffd1ea8d8dba433feb55ec28f46041ead94584c0357919f99c17c0f55cc1270b5f742f90a6cb967060d420598da884b48952987be0aa687b06556ac829c34bf84d705ef76b6a11eefc2fd3bc808e968f6fe4aca40d643643ec2906f4a8420af6d4fce3ca585591591cce1bf067c77edd7a555f5977205bd8ed1ea55ce615dd47e1f138c54f6fe23dc14764563c00d158164c9b7daab5c5b772c90ad040133a441a45e39b66567f4b957b5db188a8155e2fe72d0c06ba927c55260d1c2e4199a86d69765872b059f5b167202fcebed340c6fd91da8d7831f7ced36886e0a5a51947aeba24f62e8a5675ec01ee0e122983bc8cc9d9c7dfc77d78708f8e889ba91676b3b183aaf8cae3ed0cf79051561a2cd692f933b5f40a17b987644978c59962ead7011f369580e30d665fd5f4860411df8fea4d1027e653da3b2e7baff69c5035a311143efba8609383af517ed23e363af68fa1a1f95a1ef3c7991b79f55634787e14e32a0c32442feaf4df13a0212754c207cb27a129fc702d206d50d90bfbd4d10d10ede5fba0dedf3ec2c0d66e4741c30033356bc5911de8395977214646517e6e94e8130b32330d0e63fb13ec8eeaee673a68e94151ed9ecb92a506e184df9c53b798277c5cb10acec0e3f2a1dafba2510687d9eaad97a79d729ce2a33b2e9229f03289c111f8f3774e89e329e76c4e
\ No newline at end of file
From cef6e8e0cdbacd2dd0fbdf578e8cc32b8009566c Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 22 Jan 2023 10:23:55 -0500
Subject: [PATCH 019/145] Get the latest doctrings and post to the online
documentation in the call reference
---
docs/call reference.md | 140 +++++++++++++-----------
readme_creator/output/call reference.md | 140 +++++++++++++-----------
2 files changed, 148 insertions(+), 132 deletions(-)
diff --git a/docs/call reference.md b/docs/call reference.md
index ad33251c..77b324bb 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -126,7 +126,7 @@ Parameter Descriptions:
| (str, str) or str | mouseover_colors | Important difference between Linux & Windows! Linux - Colors when mouse moved over button. Windows - colors when button is pressed. The default is to switch the text and background colors (an inverse effect) |
| bool | use_ttk_buttons | True = use ttk buttons. False = do not use ttk buttons. None (Default) = use ttk buttons only if on a Mac and not with button images |
| (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 | bind_return_key | If True the return key will cause this button to be pressed |
+| bool | bind_return_key | If True then pressing the return key in an Input or Multiline Element will cause this button to appear to be clicked (generates event with this button's key |
| bool | focus | if True, initial focus will be put on this button |
| (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 |
@@ -2214,7 +2214,7 @@ Parameter Descriptions:
| str | text_color | color of the text |
| str | button_background_color | The color of the background of the button on the combo box |
| str | button_arrow_color | The color of the arrow on the button on the combo box |
-| bool | bind_return_key | If True, then the return key will cause a the Combo to generate an event |
+| bool | bind_return_key | If True, then the return key will cause a the Combo to generate an event when return key is pressed |
| bool | change_submits | DEPRICATED DO NOT USE. Use `enable_events` instead |
| bool | enable_events | Turns on the element specific events. Combo event is when a choice is made |
| bool | enable_per_char_events | Enables generation of events for every character that's input. This is like the Input element's events |
@@ -4881,6 +4881,8 @@ Input(default_text = "",
readonly = False,
disabled_readonly_background_color = None,
disabled_readonly_text_color = None,
+ selected_text_color = None,
+ selected_background_color = None,
expand_x = False,
expand_y = False,
right_click_menu = None,
@@ -4915,6 +4917,8 @@ Parameter Descriptions:
| bool | readonly | If True tkinter state set to 'readonly'. Use this in place of use_readonly_for_disable as another way of achieving readonly. Note cannot set BOTH readonly and disabled as tkinter only supplies a single flag |
| str | disabled_readonly_background_color | If state is set to readonly or disabled, the color to use for the background |
| str | disabled_readonly_text_color | If state is set to readonly or disabled, the color to use for the text |
+| str | selected_text_color | Color of text when it is selected (using mouse or control+A, etc) |
+| str | selected_background_color | Color of background when it is selected (using mouse or control+A, etc) |
| bool | expand_x | If True the element will automatically expand in the X direction to fill available space |
| bool | expand_y | If True the element will automatically expand in the Y direction to fill available space |
| List[List[ List[str] or str ]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. |
@@ -5359,7 +5363,7 @@ Parameter Descriptions:
| [enum] | select_mode | Select modes are used to determine if only 1 item can be selected or multiple and how they can be selected. Valid choices begin with "LISTBOX_SELECT_MODE_" and include: LISTBOX_SELECT_MODE_SINGLE LISTBOX_SELECT_MODE_MULTIPLE LISTBOX_SELECT_MODE_BROWSE LISTBOX_SELECT_MODE_EXTENDED |
| bool | change_submits | DO NOT USE. Only listed for backwards compat - Use enable_events instead |
| bool | enable_events | Turns on the element specific events. Listbox generates events when an item is clicked |
-| bool | bind_return_key | If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | If True, then the return key will cause a the Listbox to generate an event when return key is pressed |
| (int, int) or (int, None) or int | size | w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
| (int, int) or (None, None) or int | 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 |
| bool | disabled | set disable state for element |
@@ -6250,6 +6254,8 @@ Multiline(default_text = "",
auto_size_text = None,
background_color = None,
text_color = None,
+ selected_text_color = None,
+ selected_background_color = None,
horizontal_scroll = False,
change_submits = False,
enable_events = False,
@@ -6289,49 +6295,51 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| Any | default_text | Initial text to show |
-| bool | enter_submits | if True, the Window.read call will return is enter key is pressed in this element |
-| bool | disabled | set disable state |
-| bool | autoscroll | If True the contents of the element will automatically scroll as more data added to the end |
-| int | border_width | width of border around element in pixels |
-| (int, int) or (None, None) or int | size | (w, h) w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
-| (int, int) or (None, None) or int | 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 |
-| bool | auto_size_text | if True will size the element to match the length of the text |
-| str | background_color | color of background |
-| str | text_color | color of the text |
-| bool | horizontal_scroll | Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical |
-| bool | change_submits | DO NOT USE. Only listed for backwards compat - Use enable_events instead |
-| bool | enable_events | If True then any key press that happens when the element has focus will generate an event. |
-| bool | do_not_clear | if False the element will be cleared any time the Window.read call returns |
-| str or int or tuple or object | key | Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element |
-| str or int or tuple or object | k | Same as the Key. You can use either k or key. Which ever is set will be used. |
-| bool | write_only | If True then no entry will be added to the values dictionary when the window is read |
-| bool | auto_refresh | If True then anytime the element is updated, the window will be refreshed so that the change is immediately displayed |
-| bool | reroute_stdout | If True then all output to stdout will be output to this element |
-| bool | reroute_stderr | If True then all output to stderr will be output to this element |
-| bool | reroute_cprint | If True your cprint calls will output to this element. It's the same as you calling cprint_set_output_destination |
-| bool | echo_stdout_stderr | If True then output to stdout and stderr will be output to this element AND also to the normal console location |
-| bool | focus | if True initial focus will go to this element |
-| (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 |
-| (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 |
-| str | tooltip | text, that will appear when mouse hovers over the element |
-| str | justification | text justification. left, right, center. Can use single characters l, r, c. |
-| bool | no_scrollbar | If False then a vertical scrollbar will be shown (the default) |
-| bool | wrap_lines | If True, the lines will be wrapped automatically. Other parms affect this setting, but this one will override them all. Default is it does nothing and uses previous settings for wrapping. |
-| str | sbar_trough_color | Scrollbar color of the trough |
-| str | sbar_background_color | Scrollbar color of the background of the arrow buttons at the ends AND the color of the "thumb" (the thing you grab and slide). Switches to arrow color when mouse is over |
-| str | sbar_arrow_color | Scrollbar color of the arrow at the ends of the scrollbar (it looks like a button). Switches to background color when mouse is over |
-| int | sbar_width | Scrollbar width in pixels |
-| int | sbar_arrow_width | Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar |
-| str | sbar_frame_color | Scrollbar Color of frame around scrollbar (available only on some ttk themes) |
-| str | sbar_relief | Scrollbar relief that will be used for the "thumb" of the scrollbar (the thing you grab that slides). Should be a constant that is defined at starting with "RELIEF_" - RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID |
-| bool | expand_x | If True the element will automatically expand in the X direction to fill available space |
-| bool | expand_y | If True the element will automatically expand in the Y direction to fill available space |
-| bool | rstrip | If True the value returned in will have whitespace stripped from the right side |
-| List[List[ List[str] or str ]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. |
-| bool | visible | set visibility state of the element |
-| Any | metadata | User metadata that can be set to ANYTHING |
+| Any | default_text | Initial text to show |
+| bool | enter_submits | if True, the Window.read call will return is enter key is pressed in this element |
+| bool | disabled | set disable state |
+| bool | autoscroll | If True the contents of the element will automatically scroll as more data added to the end |
+| int | border_width | width of border around element in pixels |
+| (int, int) or (None, None) or int | size | (w, h) w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
+| (int, int) or (None, None) or int | 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 |
+| bool | auto_size_text | if True will size the element to match the length of the text |
+| str | background_color | color of background |
+| str | text_color | color of the text |
+| str | selected_text_color | Color of text when it is selected (using mouse or control+A, etc) |
+| str | selected_background_color | Color of background when it is selected (using mouse or control+A, etc) |
+| bool | horizontal_scroll | Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical |
+| bool | change_submits | DO NOT USE. Only listed for backwards compat - Use enable_events instead |
+| bool | enable_events | If True then any key press that happens when the element has focus will generate an event. |
+| bool | do_not_clear | if False the element will be cleared any time the Window.read call returns |
+| str or int or tuple or object | key | Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element |
+| str or int or tuple or object | k | Same as the Key. You can use either k or key. Which ever is set will be used. |
+| bool | write_only | If True then no entry will be added to the values dictionary when the window is read |
+| bool | auto_refresh | If True then anytime the element is updated, the window will be refreshed so that the change is immediately displayed |
+| bool | reroute_stdout | If True then all output to stdout will be output to this element |
+| bool | reroute_stderr | If True then all output to stderr will be output to this element |
+| bool | reroute_cprint | If True your cprint calls will output to this element. It's the same as you calling cprint_set_output_destination |
+| bool | echo_stdout_stderr | If True then output to stdout and stderr will be output to this element AND also to the normal console location |
+| bool | focus | if True initial focus will go to this element |
+| (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 |
+| (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 |
+| str | tooltip | text, that will appear when mouse hovers over the element |
+| str | justification | text justification. left, right, center. Can use single characters l, r, c. |
+| bool | no_scrollbar | If False then a vertical scrollbar will be shown (the default) |
+| bool | wrap_lines | If True, the lines will be wrapped automatically. Other parms affect this setting, but this one will override them all. Default is it does nothing and uses previous settings for wrapping. |
+| str | sbar_trough_color | Scrollbar color of the trough |
+| str | sbar_background_color | Scrollbar color of the background of the arrow buttons at the ends AND the color of the "thumb" (the thing you grab and slide). Switches to arrow color when mouse is over |
+| str | sbar_arrow_color | Scrollbar color of the arrow at the ends of the scrollbar (it looks like a button). Switches to background color when mouse is over |
+| int | sbar_width | Scrollbar width in pixels |
+| int | sbar_arrow_width | Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar |
+| str | sbar_frame_color | Scrollbar Color of frame around scrollbar (available only on some ttk themes) |
+| str | sbar_relief | Scrollbar relief that will be used for the "thumb" of the scrollbar (the thing you grab that slides). Should be a constant that is defined at starting with "RELIEF_" - RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID |
+| bool | expand_x | If True the element will automatically expand in the X direction to fill available space |
+| bool | expand_y | If True the element will automatically expand in the Y direction to fill available space |
+| bool | rstrip | If True the value returned in will have whitespace stripped from the right side |
+| List[List[ List[str] or str ]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. |
+| bool | visible | set visibility state of the element |
+| Any | metadata | User metadata that can be set to ANYTHING |
### bind
@@ -9616,7 +9624,7 @@ Parameter Descriptions:
| (int, int) or (None, None) or int | size | (w, h) w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
| (int, int) or (None, None) or int | 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 |
| bool | auto_size_text | if True will size the element to match the length of the text |
-| bool | bind_return_key | If True, then the return key will cause a the element to generate an event |
+| bool | bind_return_key | If True, then the return key will cause a the element to generate an event when return key is pressed |
| (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 | background_color | color of background |
| str | text_color | color of the text |
@@ -14907,7 +14915,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -14960,7 +14968,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15018,7 +15026,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
| (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 | bind_return_key | If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | Determines if initial focus should go to this element. |
| (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 |
@@ -15069,7 +15077,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| (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 | tooltip | text, that will appear when mouse hovers over the element |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15131,7 +15139,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -15176,7 +15184,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15429,7 +15437,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| (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 | tooltip | text, that will appear when mouse hovers over the element |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15517,7 +15525,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15562,7 +15570,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15607,7 +15615,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15654,7 +15662,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -15709,7 +15717,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -15751,7 +15759,7 @@ Parameter Descriptions:
| (int, int) or (None, None) or int | 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 |
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
@@ -15849,7 +15857,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15896,7 +15904,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15953,7 +15961,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
@@ -16006,7 +16014,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
@@ -16064,7 +16072,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
@@ -16121,7 +16129,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index ad33251c..77b324bb 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -126,7 +126,7 @@ Parameter Descriptions:
| (str, str) or str | mouseover_colors | Important difference between Linux & Windows! Linux - Colors when mouse moved over button. Windows - colors when button is pressed. The default is to switch the text and background colors (an inverse effect) |
| bool | use_ttk_buttons | True = use ttk buttons. False = do not use ttk buttons. None (Default) = use ttk buttons only if on a Mac and not with button images |
| (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 | bind_return_key | If True the return key will cause this button to be pressed |
+| bool | bind_return_key | If True then pressing the return key in an Input or Multiline Element will cause this button to appear to be clicked (generates event with this button's key |
| bool | focus | if True, initial focus will be put on this button |
| (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 |
@@ -2214,7 +2214,7 @@ Parameter Descriptions:
| str | text_color | color of the text |
| str | button_background_color | The color of the background of the button on the combo box |
| str | button_arrow_color | The color of the arrow on the button on the combo box |
-| bool | bind_return_key | If True, then the return key will cause a the Combo to generate an event |
+| bool | bind_return_key | If True, then the return key will cause a the Combo to generate an event when return key is pressed |
| bool | change_submits | DEPRICATED DO NOT USE. Use `enable_events` instead |
| bool | enable_events | Turns on the element specific events. Combo event is when a choice is made |
| bool | enable_per_char_events | Enables generation of events for every character that's input. This is like the Input element's events |
@@ -4881,6 +4881,8 @@ Input(default_text = "",
readonly = False,
disabled_readonly_background_color = None,
disabled_readonly_text_color = None,
+ selected_text_color = None,
+ selected_background_color = None,
expand_x = False,
expand_y = False,
right_click_menu = None,
@@ -4915,6 +4917,8 @@ Parameter Descriptions:
| bool | readonly | If True tkinter state set to 'readonly'. Use this in place of use_readonly_for_disable as another way of achieving readonly. Note cannot set BOTH readonly and disabled as tkinter only supplies a single flag |
| str | disabled_readonly_background_color | If state is set to readonly or disabled, the color to use for the background |
| str | disabled_readonly_text_color | If state is set to readonly or disabled, the color to use for the text |
+| str | selected_text_color | Color of text when it is selected (using mouse or control+A, etc) |
+| str | selected_background_color | Color of background when it is selected (using mouse or control+A, etc) |
| bool | expand_x | If True the element will automatically expand in the X direction to fill available space |
| bool | expand_y | If True the element will automatically expand in the Y direction to fill available space |
| List[List[ List[str] or str ]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. |
@@ -5359,7 +5363,7 @@ Parameter Descriptions:
| [enum] | select_mode | Select modes are used to determine if only 1 item can be selected or multiple and how they can be selected. Valid choices begin with "LISTBOX_SELECT_MODE_" and include: LISTBOX_SELECT_MODE_SINGLE LISTBOX_SELECT_MODE_MULTIPLE LISTBOX_SELECT_MODE_BROWSE LISTBOX_SELECT_MODE_EXTENDED |
| bool | change_submits | DO NOT USE. Only listed for backwards compat - Use enable_events instead |
| bool | enable_events | Turns on the element specific events. Listbox generates events when an item is clicked |
-| bool | bind_return_key | If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | If True, then the return key will cause a the Listbox to generate an event when return key is pressed |
| (int, int) or (int, None) or int | size | w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
| (int, int) or (None, None) or int | 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 |
| bool | disabled | set disable state for element |
@@ -6250,6 +6254,8 @@ Multiline(default_text = "",
auto_size_text = None,
background_color = None,
text_color = None,
+ selected_text_color = None,
+ selected_background_color = None,
horizontal_scroll = False,
change_submits = False,
enable_events = False,
@@ -6289,49 +6295,51 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| Any | default_text | Initial text to show |
-| bool | enter_submits | if True, the Window.read call will return is enter key is pressed in this element |
-| bool | disabled | set disable state |
-| bool | autoscroll | If True the contents of the element will automatically scroll as more data added to the end |
-| int | border_width | width of border around element in pixels |
-| (int, int) or (None, None) or int | size | (w, h) w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
-| (int, int) or (None, None) or int | 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 |
-| bool | auto_size_text | if True will size the element to match the length of the text |
-| str | background_color | color of background |
-| str | text_color | color of the text |
-| bool | horizontal_scroll | Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical |
-| bool | change_submits | DO NOT USE. Only listed for backwards compat - Use enable_events instead |
-| bool | enable_events | If True then any key press that happens when the element has focus will generate an event. |
-| bool | do_not_clear | if False the element will be cleared any time the Window.read call returns |
-| str or int or tuple or object | key | Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element |
-| str or int or tuple or object | k | Same as the Key. You can use either k or key. Which ever is set will be used. |
-| bool | write_only | If True then no entry will be added to the values dictionary when the window is read |
-| bool | auto_refresh | If True then anytime the element is updated, the window will be refreshed so that the change is immediately displayed |
-| bool | reroute_stdout | If True then all output to stdout will be output to this element |
-| bool | reroute_stderr | If True then all output to stderr will be output to this element |
-| bool | reroute_cprint | If True your cprint calls will output to this element. It's the same as you calling cprint_set_output_destination |
-| bool | echo_stdout_stderr | If True then output to stdout and stderr will be output to this element AND also to the normal console location |
-| bool | focus | if True initial focus will go to this element |
-| (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 |
-| (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 |
-| str | tooltip | text, that will appear when mouse hovers over the element |
-| str | justification | text justification. left, right, center. Can use single characters l, r, c. |
-| bool | no_scrollbar | If False then a vertical scrollbar will be shown (the default) |
-| bool | wrap_lines | If True, the lines will be wrapped automatically. Other parms affect this setting, but this one will override them all. Default is it does nothing and uses previous settings for wrapping. |
-| str | sbar_trough_color | Scrollbar color of the trough |
-| str | sbar_background_color | Scrollbar color of the background of the arrow buttons at the ends AND the color of the "thumb" (the thing you grab and slide). Switches to arrow color when mouse is over |
-| str | sbar_arrow_color | Scrollbar color of the arrow at the ends of the scrollbar (it looks like a button). Switches to background color when mouse is over |
-| int | sbar_width | Scrollbar width in pixels |
-| int | sbar_arrow_width | Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar |
-| str | sbar_frame_color | Scrollbar Color of frame around scrollbar (available only on some ttk themes) |
-| str | sbar_relief | Scrollbar relief that will be used for the "thumb" of the scrollbar (the thing you grab that slides). Should be a constant that is defined at starting with "RELIEF_" - RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID |
-| bool | expand_x | If True the element will automatically expand in the X direction to fill available space |
-| bool | expand_y | If True the element will automatically expand in the Y direction to fill available space |
-| bool | rstrip | If True the value returned in will have whitespace stripped from the right side |
-| List[List[ List[str] or str ]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. |
-| bool | visible | set visibility state of the element |
-| Any | metadata | User metadata that can be set to ANYTHING |
+| Any | default_text | Initial text to show |
+| bool | enter_submits | if True, the Window.read call will return is enter key is pressed in this element |
+| bool | disabled | set disable state |
+| bool | autoscroll | If True the contents of the element will automatically scroll as more data added to the end |
+| int | border_width | width of border around element in pixels |
+| (int, int) or (None, None) or int | size | (w, h) w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
+| (int, int) or (None, None) or int | 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 |
+| bool | auto_size_text | if True will size the element to match the length of the text |
+| str | background_color | color of background |
+| str | text_color | color of the text |
+| str | selected_text_color | Color of text when it is selected (using mouse or control+A, etc) |
+| str | selected_background_color | Color of background when it is selected (using mouse or control+A, etc) |
+| bool | horizontal_scroll | Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical |
+| bool | change_submits | DO NOT USE. Only listed for backwards compat - Use enable_events instead |
+| bool | enable_events | If True then any key press that happens when the element has focus will generate an event. |
+| bool | do_not_clear | if False the element will be cleared any time the Window.read call returns |
+| str or int or tuple or object | key | Used with window.find_element and with return values to uniquely identify this element to uniquely identify this element |
+| str or int or tuple or object | k | Same as the Key. You can use either k or key. Which ever is set will be used. |
+| bool | write_only | If True then no entry will be added to the values dictionary when the window is read |
+| bool | auto_refresh | If True then anytime the element is updated, the window will be refreshed so that the change is immediately displayed |
+| bool | reroute_stdout | If True then all output to stdout will be output to this element |
+| bool | reroute_stderr | If True then all output to stderr will be output to this element |
+| bool | reroute_cprint | If True your cprint calls will output to this element. It's the same as you calling cprint_set_output_destination |
+| bool | echo_stdout_stderr | If True then output to stdout and stderr will be output to this element AND also to the normal console location |
+| bool | focus | if True initial focus will go to this element |
+| (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 |
+| (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 |
+| str | tooltip | text, that will appear when mouse hovers over the element |
+| str | justification | text justification. left, right, center. Can use single characters l, r, c. |
+| bool | no_scrollbar | If False then a vertical scrollbar will be shown (the default) |
+| bool | wrap_lines | If True, the lines will be wrapped automatically. Other parms affect this setting, but this one will override them all. Default is it does nothing and uses previous settings for wrapping. |
+| str | sbar_trough_color | Scrollbar color of the trough |
+| str | sbar_background_color | Scrollbar color of the background of the arrow buttons at the ends AND the color of the "thumb" (the thing you grab and slide). Switches to arrow color when mouse is over |
+| str | sbar_arrow_color | Scrollbar color of the arrow at the ends of the scrollbar (it looks like a button). Switches to background color when mouse is over |
+| int | sbar_width | Scrollbar width in pixels |
+| int | sbar_arrow_width | Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar |
+| str | sbar_frame_color | Scrollbar Color of frame around scrollbar (available only on some ttk themes) |
+| str | sbar_relief | Scrollbar relief that will be used for the "thumb" of the scrollbar (the thing you grab that slides). Should be a constant that is defined at starting with "RELIEF_" - RELIEF_RAISED, RELIEF_SUNKEN, RELIEF_FLAT, RELIEF_RIDGE, RELIEF_GROOVE, RELIEF_SOLID |
+| bool | expand_x | If True the element will automatically expand in the X direction to fill available space |
+| bool | expand_y | If True the element will automatically expand in the Y direction to fill available space |
+| bool | rstrip | If True the value returned in will have whitespace stripped from the right side |
+| List[List[ List[str] or str ]] | right_click_menu | A list of lists of Menu items to show when this element is right clicked. See user docs for exact format. |
+| bool | visible | set visibility state of the element |
+| Any | metadata | User metadata that can be set to ANYTHING |
### bind
@@ -9616,7 +9624,7 @@ Parameter Descriptions:
| (int, int) or (None, None) or int | size | (w, h) w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1 |
| (int, int) or (None, None) or int | 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 |
| bool | auto_size_text | if True will size the element to match the length of the text |
-| bool | bind_return_key | If True, then the return key will cause a the element to generate an event |
+| bool | bind_return_key | If True, then the return key will cause a the element to generate an event when return key is pressed |
| (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 | background_color | color of background |
| str | text_color | color of the text |
@@ -14907,7 +14915,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -14960,7 +14968,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15018,7 +15026,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
| (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 | bind_return_key | If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | Determines if initial focus should go to this element. |
| (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 |
@@ -15069,7 +15077,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| (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 | tooltip | text, that will appear when mouse hovers over the element |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15131,7 +15139,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -15176,7 +15184,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15429,7 +15437,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| (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 | tooltip | text, that will appear when mouse hovers over the element |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15517,7 +15525,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15562,7 +15570,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15607,7 +15615,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15654,7 +15662,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -15709,7 +15717,7 @@ Parameter Descriptions:
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | focus | if focus should be set to this |
| (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 |
@@ -15751,7 +15759,7 @@ Parameter Descriptions:
| (int, int) or (None, None) or int | 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 |
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
@@ -15849,7 +15857,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| bool | disabled | set disable state for element (Default = False) |
-| bool | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 |
| idk_yetReally | focus | if focus should be set to this |
@@ -15896,7 +15904,7 @@ Parameter Descriptions:
| bool | disabled | set disable state for element (Default = False) |
| str | tooltip | text, that will appear when mouse hovers over the element |
| (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 | bind_return_key | (Default = True) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = True) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| | focus | if focus should be set to this |
| (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 |
@@ -15953,7 +15961,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
@@ -16006,7 +16014,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
@@ -16064,7 +16072,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
@@ -16121,7 +16129,7 @@ Parameter Descriptions:
| bool | auto_size_button | True if button size is determined by button text |
| (str, str) or str | button_color | button color (foreground, background) |
| (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 | bind_return_key | (Default = False) If True, then the return key will cause a the Listbox to generate an event |
+| bool | bind_return_key | (Default = False) If True, this button will appear to be clicked when return key is pressed in other elements such as Input and elements with return key options |
| bool | disabled | set disable state for element (Default = False) |
| idk_yetReally | focus | if focus should be set to this |
| (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) |
From de383504e0e1d3b0b42d87fc1b647f2a42b988c2 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Wed, 25 Jan 2023 07:57:50 -0500
Subject: [PATCH 020/145] Error handling for when no editor has been
configured
---
...rowser_START_HERE_Demo_Programs_Browser.py | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/DemoPrograms/Browser_START_HERE_Demo_Programs_Browser.py b/DemoPrograms/Browser_START_HERE_Demo_Programs_Browser.py
index 60150ca8..f7c4a84d 100644
--- a/DemoPrograms/Browser_START_HERE_Demo_Programs_Browser.py
+++ b/DemoPrograms/Browser_START_HERE_Demo_Programs_Browser.py
@@ -5,7 +5,7 @@ import warnings
import PySimpleGUI as sg
-__version__ = '1.12.0'
+__version__ = '1.12.2'
"""
PySimpleGUI Demo Program Browser
@@ -36,7 +36,7 @@ __version__ = '1.12.0'
Versions:
1.8.0 - Addition of option to show ALL file types, not just Python files
1.12.0 - Fix for problem with spaces in filename and using an editor specified in the demo program settings
-
+ 1.12.2 - Better error handling for no editor configured
Copyright 2021, 2022 PySimpleGUI.org
"""
@@ -577,16 +577,16 @@ def main():
sg.cprint(f'Editing using {editor_program}', c='white on red', end='')
sg.cprint('')
sg.cprint(f'{full_filename}', c='white on purple')
- # if line != 1:
- if using_local_editor():
- sg.execute_command_subprocess(editor_program, f'"{full_filename}"')
+ if not get_editor():
+ sg.popup_error_with_traceback('No editor has been configured', 'You need to configure an editor in order to use this feature', 'You can configure the editor in the Demo Brower Settings or the PySimpleGUI Global Settings')
else:
- try:
- sg.execute_editor(full_filename, line_number=int(line))
- except:
+ if using_local_editor():
sg.execute_command_subprocess(editor_program, f'"{full_filename}"')
- # else:
- # sg.execute_editor(full_filename)
+ else:
+ try:
+ sg.execute_editor(full_filename, line_number=int(line))
+ except:
+ sg.execute_command_subprocess(editor_program, f'"{full_filename}"')
else:
sg.cprint('Editing canceled')
elif event == 'Run':
From 5b0f6950a32392b9f2db751abc085a709d3ccad9 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sat, 28 Jan 2023 18:30:26 +0000
Subject: [PATCH 021/145] Automated Update!
---
docs/Screens.md | 7 +++++++
docs/Screens2.md | 10 ++++++++++
2 files changed, 17 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 04c74418..34cf4847 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,10 @@
+[eagleEggs](https://github.com/eagleEggs) 2023-01-28T02:30:37Z
+
+
+
+
+-----------
+
[hseera](https://github.com/hseera) 2023-01-04T23:30:35Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index cdef5da7..c78cf81c 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,13 @@
+[eagleEggs](https://github.com/eagleEggs) 2023-01-28T02:30:37Z
+PSG WOOOHOOOO. Super fast implementation of this thanks to PSG. We were able to jump straight into core code, and add new things on the fly in minutes. This is a vulnerability management / parser, scanner... and moreeeee.
+
+
+
+
+Thanks again PSG <3
+
+-----------
+
[hseera](https://github.com/hseera) 2023-01-04T23:30:35Z
Using PySimpleGUI framework, I built an opernsource tool called "CloudWatch Dashboard Builder" for SRE, Performance Engineers and Operations teams, who work with AWS services. It gives them capability to build CloudWatch Dashboard from different Namespace templates. The tool lets you modify the template too.
From 16aea9c37fe1ab6c2cc56e237bc51ebf24dc6b47 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sun, 29 Jan 2023 18:30:26 +0000
Subject: [PATCH 022/145] Automated Update!
---
docs/Screens.md | 7 +++++++
docs/Screens2.md | 14 ++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 34cf4847..86ba1e2e 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,10 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-01-29T15:31:26Z
+
+
+
+
+-----------
+
[eagleEggs](https://github.com/eagleEggs) 2023-01-28T02:30:37Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index c78cf81c..adb9f019 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,17 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-01-29T15:31:26Z
+@eagleEggs I briefly saw a version of this GUI and then it disappeared. I'm THRILLED you've posted it. 
+
+Thank you so very much for sharing your talent in using PySimpleGUI. You're such an expert now and I SO appreciate you being here since the early days.
+
+That's a beautiful window.... just plain beautiful!
+
+Your support and encouragement have been really appreciated.
+
+
+
+
+-----------
+
[eagleEggs](https://github.com/eagleEggs) 2023-01-28T02:30:37Z
PSG WOOOHOOOO. Super fast implementation of this thanks to PSG. We were able to jump straight into core code, and add new things on the fly in minutes. This is a vulnerability management / parser, scanner... and moreeeee.
From 2af2d59c4d3f04a4d3a745bf177e4d05a4e7bc08 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Mon, 30 Jan 2023 18:30:24 +0000
Subject: [PATCH 023/145] Automated Update!
---
docs/Screens.md | 9 +++++++++
docs/Screens2.md | 21 +++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 86ba1e2e..73bcad6a 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,12 @@
+[J-Josu](https://github.com/J-Josu) 2023-01-30T13:20:08Z
+
+
+
+
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-01-29T15:31:26Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index adb9f019..3d2651bb 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,24 @@
+[J-Josu](https://github.com/J-Josu) 2023-01-30T13:20:08Z
+Hi! I'm a stundent of Computer Science in Argentina and i`ve had to do a Final project for my Python Course. The project its about a card game where you can choose between availible themes to try to guess the correct option. The data is automtically loaded from cvs.
+
+Here are some screenshoots of the final result:
+
+
+
+
+
+
+
+
+
+And other pages...
+
+All the ui its in spanish, but the code all written in english.
+The project includes a mini-framework to build pages easly and some cli utilities.
+Also the code have all the corresponding typing annotations and more interesting stuff.
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-01-29T15:31:26Z
@eagleEggs I briefly saw a version of this GUI and then it disappeared. I'm THRILLED you've posted it. 
From e764cc07b8a609ce717b6da460e6dd6433f732d5 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sat, 4 Feb 2023 17:45:33 -0500
Subject: [PATCH 024/145] New Demo Program - automatically save and load Input
element values using User Settings API
---
.../Demo_User_Settings_Auto_Load_and_Save.py | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py
diff --git a/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py b/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py
new file mode 100644
index 00000000..d5e1ff32
--- /dev/null
+++ b/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py
@@ -0,0 +1,55 @@
+import PySimpleGUI as sg
+
+"""
+ Demo - User Setting API to automatically save and load Input Elements
+
+ This Demo Program shows an easy way to add saving and loading of Input elements.
+
+ The variable keys_to_save is used to determine which elements will be saved to the user settings file.
+
+ The function make_key returns a dictionary that's used as keyword parameters that are passed to the Input elements. Using this technique allows the Input elements in the layout to benefit from the docstrings provided by PySimpleGUI. Another approach could be to use a function that returns an Input element, but that limits the flexibility for configuring Input elements.
+
+ Copyright 2023 PySimpleGUI
+"""
+
+keys_to_save = ('-IN1-', '-IN2-', '-IN3-', '-IN4-')
+
+def make_key(key):
+ """
+ Returns a dictionary that is used to pass parameters to an Input element.
+ Another approach could be to return an Input element. The downside to that approach is
+ the lack of parameters and associated docstrings when creating the layout.
+
+ :param key:
+ :return: Dict(
+ """
+ return {'default_text':sg.user_settings_get_entry(key, ''), 'key':key}
+
+
+def main():
+ layout = [ [sg.Text('Automatically Load and Save Of Inputs', font='_ 15')],
+ [sg.Text('Input 1'), sg.Input(**make_key('-IN1-'))],
+ [sg.Text('Input 2'), sg.Input(**make_key('-IN2-'), background_color='green')],
+ [sg.Text('Input 3'), sg.Input(**make_key('-IN3-'), text_color='blue')],
+ [sg.Text('Input 4'), sg.Input(**make_key('-IN4-'), size=5)],
+ [sg.Button('Exit (and save)', key='-EXIT SAVE-'), sg.Button('Exit without save')] ]
+
+ window = sg.Window('Save / Load Inputs Using User Settings API', layout)
+
+ while True: # Event Loop
+ event, values = window.read()
+ print(event, values)
+ if event == sg.WIN_CLOSED or event == 'Exit without save':
+ sg.popup_quick_message('Exiting without save', text_color='white', background_color='red', font='_ 20')
+
+ break
+ elif event == '-EXIT SAVE-':
+ sg.popup_quick_message('Saving settings & Exiting', text_color='white', background_color='red', font='_ 20')
+ for key in keys_to_save:
+ sg.user_settings_set_entry(key, values[key])
+ break
+
+ window.close()
+
+if __name__ == '__main__':
+ main()
From 078fc3b1d486c8d0b06fd4c7fdc04161c4e5ee95 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 5 Feb 2023 06:16:23 -0500
Subject: [PATCH 025/145] Hacked the version numbering (again... sorry!) to try
to mediate the confusion about what's posted to PyPI.
---
PySimpleGUI.py | 314 +++++++++++++++++++++++++------------------------
1 file changed, 159 insertions(+), 155 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 43ddf381..819751dd 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,362 +1,364 @@
#!/usr/bin/python3
-version = __version__ = "4.60.4.145 Unreleased"
+version = __version__ = "4.61.0.145 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
- 4.60.0.1
+ 4.61.0.1
main_open_github_issue - prefill the "Details" using the platform module (thank you macdeport!)
Fills Mac, Windows and Linux with details
- 4.60.0.2
+ 4.61.0.2
Fix for the "jumping window problem on Linux". Major credit to Chr0nic for his amazing "stick with it" work on this problem!
- 4.60.0.3
+ 4.61.0.3
Removed the previous fix attempt for jumping window on linux
Added ability for Mac users to specify file_type in Browse and popup_get_file
This feature must be ENABLED by the user in the Mac control panel that can be found in the PySimpleGUI Global Settings
The default is this feature is OFF
- 4.60.0.4
+ 4.61.0.4
New location parameter option for Windows. Setting location=None tells PySimpleGUI to not set any location when window is created. It's up to the OS to decide.
The docstring for Window has been changed, but not all the other places (like popup). Want to make sure this works before making all those changes.
- 4.60.0.5
+ 4.61.0.5
Added check for None invalid values parm when creating a Listbox element
- 4.60.0.6
+ 4.61.0.6
Column docstring changed to add reminder to call contents_changed if changing the contents of a scrollable column
- 4.60.0.7
+ 4.61.0.7
Fixed crash when horizontal_scroll=True for Listbox element
- 4.60.0.8
+ 4.61.0.8
Added readonly to Input.update
- 4.60.0.9
+ 4.61.0.9
Added Window.set_resizable - can change the X and Y axis resizing after window is created
- 4.60.0.10
+ 4.61.0.10
Added wrap parameter to Spin element - if True, wraps back to the first value when at the end
Temp test code added for a new verification feature
- 4.60.0.11
+ 4.61.0.11
Fixed Spin Element docstring - readonly was not correct
- 4.60.0.12
+ 4.61.0.12
Output element - addition of wrap_lines and horizontal_scroll parameters
Multiline element - addition of wrap_lines parameter
- 4.60.0.13
+ 4.61.0.13
Added Window.unbind
- 4.60.0.14
+ 4.61.0.14
Added (None, None) to the Window docstring
- 4.60.0.15
+ 4.61.0.15
Fix for continuous Graph element mouse up events when reading with a timeout=0. Big thank you to @davesmivers (THANKS DAVE!!) for finding and fixing
- 4.60.0.16
+ 4.61.0.16
Added platform (Windows, Mac, Linux) and platform version information to the get_versions function
- 4.60.0.17
+ 4.61.0.17
Added a fix for the file_types Mac problem that doesn't require the system settings to be used... let's give it a go!
- 4.60.0.18
+ 4.61.0.18
Added ubiquitious Edit Me to the right click menu
- 4.60.0.19
+ 4.61.0.19
PySimpleGUI Anniversary sale on Udemy course coupon
- 4.60.0.20
+ 4.61.0.20
Fix for bind_return_key - if a button has been disabled, then the event shouldn't be generated for the return key being pressed
- 4.60.0.21
+ 4.61.0.21
Added cols_justification for Table element - list or tuple of strings that indicates how each column should be justified
- 4.60.0.22
+ 4.61.0.22
Better error handling for table element's new justification list. If a bad value is found, will use the default value
- 4.60.0.23
+ 4.61.0.23
Additional mac filetype testing.... added more combinations that specify
- 4.60.0.24
+ 4.61.0.24
Added * *.* to the Mac filetypes to check for
- 4.60.0.25
+ 4.61.0.25
New logic for checking for the * case for Mac filetypes
- 4.60.0.26
+ 4.61.0.26
Docstring update - TabGroup visible parameter marked as deprecated . Use a Column element to make a TabGroup invisible
- 4.60.0.27
+ 4.61.0.27
Docstring update for the pin helper function that describes the shrinking of the container that it helps provide.
Also added explanation that it's the elements you want to make visible/invisible that are what you want to pin
- 4.60.0.28
+ 4.61.0.28
Applied same Mac file_types fix to popup_get_file
Removed filetypes setting from Mac Feature Control Panel
- 4.60.0.29
+ 4.61.0.29
Addition of enable_window_config_events to the Window object. This will cause a EVENT_WIMDOW_CONFIG event to be returned
if the window is moved or resized.
- 4.60.0.30
+ 4.61.0.30
Made upgrade from GitHub window resizable so can screencapture the entire session
- 4.60.0.31
+ 4.61.0.31
Added new constant TKINTER_CURSORS which contains a list of the standard tkinter cursor names
- 4.60.0.32
+ 4.61.0.32
Added erase_all parameter to cprint (like the Debug Print already has)
- 4.60.0.33
+ 4.61.0.33
Fix popup_scrolled - was only adding the Sizegrip when there was no titlebar. It should be added to all windows
unless the no_sizegrip parameter is set.
popup_scrolled - added no_buttons option. If True then there will not be a row at the bottom where the buttons normally are.
User will have to close the window with the "X"
- 4.60.0.34
+ 4.61.0.34
popup_scrolled - added button_justification parameter. Wanted to make scrolled popups consistent with other popups which have left justified
buttons. But since they've been right justified in the past, want to give users the ability to retain that look.
Since the Sizegrip works correctly now, it increases the changes of accidently clicking a button if it's right justified.
- 4.60.0.35
+ 4.61.0.35
Added default_color to ColorChooser button
- 4.60.0.36
+ 4.61.0.36
Added to Button element error message that images must be in PNG or GIF format
- 4.60.0.37
+ 4.61.0.37
Added exapnd_x and expand_y to all of the "lazy buttons" and Chooser buttons
- 4.60.0.38
+ 4.61.0.38
Column element - added horizontal_scroll_only parameter (fingers crossed on this one....)
- 4.60.0.39
+ 4.61.0.39
New signature testing
- 4.60.0.40
+ 4.61.0.40
Exposed the Table Element's ttk style using member variable TABLE.table_ttk_style_name
- 4.60.0.41
+ 4.61.0.41
New signature format
- 4.60.0.42
- Backed out the changes from 4.60.0.38 (horizontal_scroll_only parameter). Those changes broke code in the scrollable columns. Need to make time to work on this feature more.
- 4.60.0.43
+ 4.61.0.42
+ Backed out the changes from 4.61.0.38 (horizontal_scroll_only parameter). Those changes broke code in the scrollable columns. Need to make time to work on this feature more.
+ 4.61.0.43
Added a print if get an exception trying to set the alpha channel after a window is created (troubleshooting a Mac problem)
- 4.60.0.44
+ 4.61.0.44
Updated Menubar docstring to clarify the Menubar iself cannot have colors changed, only the submenus. Use MenubarCustom if you want full control
Format of file-signature changed
- 4.60.0.45
+ 4.61.0.45
Further refinement of Menubar docstring
- 4.60.0.46
+ 4.61.0.46
Added suggestion of using the Demo Browser to the checklist item of "Look for Demo Programs similar to your problem"
- 4.60.0.47
+ 4.61.0.47
Testing some importing methods
Delay rerouting stdout and stderr in Output and Multiline elements until window is being built instead of when element is initialized
- 4.60.0.48
+ 4.61.0.48
Additional window movement capability. If Control+Mouse movement feature is enabled, then Control+Arrow key will move the window 1 pixel
in the indicated direction
- 4.60.0.49
+ 4.61.0.49
Added Window.set_size to match the other settings that are performed through method calls. There is also the Window.size property, but
since PySimpleGUI rarely uses properties, it makes sense to include a method as well as a property
- 4.60.0.50
+ 4.61.0.50
Fix for ColorChooser button filling in a None value when cancel from color choise dialog box. Nothing will be filled in target if dialog cancelled
- 4.60.0.51
+ 4.61.0.51
vtop, vcenter, vbottom helper functions gets background_color parameter
vcenter and vbottom - added USING the expand_x and expand_y parms that were already defined. (HOPE NOTHING BREAKS!)
- 4.60.0.52
+ 4.61.0.52
justification parameter added to Listbox (default is left.. can be right and center now too)
- 4.60.0.53
+ 4.61.0.53
Made settings dictionary multiline in test harness write-only. New coupon code
- 4.60.0.54
+ 4.61.0.54
alpha_channel added to set_options. This sets the default value for the alpha_channel for all windows both user generated and PySimpleGUI generated (such as popups).
- 4.60.0.55
+ 4.61.0.55
Allow Browse/Chooser buttons (that have a target) to indicate a target key that is a tuple.
- 4.60.1.55
+ 4.61.0.55
While not actually correct.... 4.60.1 was released in the middle of the development above... I'm changing the version to look as
if this release is based on 4.60.1. This code DOES have the same code that's in 4.60.1 so it's more a matter of symantics.
Hoping this clears up confusion. Sorry for the dot-release causing so much confusion.
- 4.60.1.56
+ 4.61.0.56
Fix for Window.extend_layout. Was not picking up the background color of the container that the rows were being added to.
- 4.60.1.57
+ 4.61.0.57
Fixed Text element's update method docstring to indicate that value can be "Any" type not just strings
- 4.60.1.58
+ 4.61.0.58
Addition of without_titlebar paramter to Window.current_location. Defaults to False. If True, then the location of the main portion of the window
will be returned (i.e. will not have the titlebar)
- 4.60.1.59
+ 4.61.0.59
Fix for crash if COLOR_SYSTEM_DEFAULT specified in parameter disabled_readonly_background_color or disabled_readonly_text_color for Input Element.
Also applied similar fix for Tab element's focus color
- 4.60.1.60
+ 4.61.0.60
Addition of set_option parameter hide_window_when_creating. If set to False then window will not be hidden while creating and moving
- 4.60.1.61
+ 4.61.0.61
Changed the documentation location to PySimpleGUI.org (updated some comments as well as the SDK Reference Window's links)
New coupon code. Make the Udemy button in the test harness now include the coupon code automatically
- 4.60.1.62
+ 4.61.0.62
Removed the "NOT avoilable on the MAC" from file_types parameter in the docstrings
Use Withdraw to hide window during creation
- 4.60.1.63
+ 4.61.0.63
Addition of checklist item when logging new issue to GitHub - upgraded to latest version of PySimpleGUI on PyPI
Listbox justification parameter found to not be implemented on some early verions of tkinter so had to protect this situation. This new feature crached on the Pi for example
- 4.60.1.64
+ 4.61.0.64
Allow set_options(window_location=None) to indicate the OS should provide the window location.
This will stop the Alpha channel being set to 0 when the window is created
- 4.60.1.65
+ 4.61.0.65
Addition of new Mac Control Panel option and emergency patch for MacOS version 12.3+
If MacOS version 12.3 or greater than option is ON by default
When ON, the default Alpha channel for all windows is set to 0.99.
This can either be turned off, or can be overridden by calling set_options in your application
- 4.60.2.65
+ 4.61.0.65
Bumping version number to avoid confusion. An emergency 4.60.2 release was posted to PyPI. This change was added to this current GitHub version of PySimpleGUI.
- 4.60.3.66
+ 4.61.0.66
Fixed bug in checking Mac OS version number that is being released as 4.60.3
- 4.60.3.67
+ 4.61.0.67
Correctly check for Mac 12.3+ AND 13+ this time.
- 4.60.3.68
+ 4.61.0.68
Roll in the changes being released to PyPI as 4.60.3
- 4.60.3.69
+ 4.61.0.69
Test to see if the additional pack of Notebook in Tab code was causing expansion problems
- 4.60.3.70
+ 4.61.0.70
Debug Print - fix for bug caused by no_button being set with non_blocking... a lesson in thorough testing... assumption was either blocking OR no_button (or else app would
close without seeing the output... unless something else blocked. (DOH)
- 4.60.3.71
+ 4.61.0.71
"Window closed" check added to update methods for elements. This will prevent a crash and instead show an error popup
Will be helpful for users that forget to check for closed window event in their event loop and try to call update after window closed.
- 4.60.3.72
+ 4.61.0.72
Output element now automatically sets auto_refresh to True. Should this not be desired, switch to using the Multiline element. There will likely be
no impact to this change as it seems like the windows are alredy refreshing OK, but adding it just to be sure.
- 4.60.3.73
+ 4.61.0.73
Addition of Window.key_is_good(key) method. Returns True if key is used in the window. Saves from having to understand the window's key dictionary.
Makes for easier code completion versus writing "if key in window.key_dict"
- 4.60.3.74
+ 4.61.0.74
Combo - if readonly, then set the select colors to be "transparent" (text=text color, background=background color)
- 4.60.3.75
+ 4.61.0.75
Better description of bar_color parm for the ProgressMeter element and the one_line_progress_meter function
Combo element - addition of select parameter to enable easier selection of the contents of clearing of the selection of the contents.
- 4.60.3.76
+ 4.61.0.76
Changed the _this_elements_window_closed to use a flag "quick_check" for cheking is the window is closed. Found that calling tkinter.update takes over 500ms sometimes!
For appllications that call update frequently, this caused a catestrophic slowdown for complex windows.
- 4.60.3.77
+ 4.61.0.77
New Window method - get_scaling - gets the scaling value from tkinter. Returns DEFAULT_SCALING if error.
- 4.60.3.78
+ 4.61.0.78
Custom Titlebar - Support added to Window.minimize, Window.maximize, and Window.normal
- 4.60.3.79
+ 4.61.0.79
Fix for Mulitline showing constant error messages after a Window is closed.
Fix for correctly restoring stdout, stderr after they've been rerouted. THIS CODE IS NOT YET COMPLETE! Shooting for this weekend to get it done!
Image element - more speicific with tkinter when chaning to a new image so that pypy would stop crashing due to garbage collect not running.
This change didn't fix the pypy problem but it also didn't hurt the code to have it
- 4.60.3.80
+ 4.61.0.80
Quick and dirty addition of Alt-shortcuts for Buttons (like exists for Menus)
For backward compatablity, must be enabled using set_options with use_button_shortcuts=True
Fixed docstring errors in set_options docstring
- 4.60.3.81
+ 4.61.0.81
Completed restoration of stdout & stderr
If an Output Element is used or a Multline element to reroute stdout and/or stderr, then this hasn't worked quite right in the past
Hopefuly now, it does. A LIFO list (stack) is used to keep track of the current output device and is scrubbed for closed windows and restored if one is closed
- 4.60.3.82
+ 4.61.0.82
Addition of Style Names for horizontaland vertical ttk scrollbars - hsb_style_name and vsb_style_name so that scrollbar colors can be changed in user code
- 4.60.3.83
+ 4.61.0.83
Output element - now automatically reroutes cprint to here as well. Assumption is that you want stuff to go here without
needing to specify each thing. If want more control, then use the Multiline directly
- 4.60.3.84
+ 4.61.0.84
Output element - updated docstring
- 4.60.3.85
+ 4.61.0.85
Combo Element - new parameter enable_per_char_events. When True will get an event when individual characters are entered.
- 4.60.3.86
+ 4.61.0.86
Added path to the interpreter to the get_versions information for better debugging
- 4.60.3.87
+ 4.61.0.87
Dark Gray 16 theme added
- 4.60.3.88
+ 4.61.0.88
New batch of Emojis!
- 4.60.3.89
+ 4.61.0.89
Addition of TITLEBAR_TEXT_KEY to provide access to custom titlebar titles
- 4.60.3.90
+ 4.61.0.90
Implemented the visible parameter for TabGroup. Was not being honored when creating element. Added TabGroup.update so it can be made visible.
- 4.60.3.91
+ 4.61.0.91
Added support for Custom Titlebar to the Window.set_title method
- 4.60.3.92
+ 4.61.0.92
Addition of starting_row_number parameter to the Table element. Sets the value for the first row in the table.
- 4.60.3.93
+ 4.61.0.93
Added 2 parameters to popup - drop_whitespace is passed to the wraptext.fill method. right_justify_buttons will "push" buttons to
the right side if set to True
- 4.60.3.94
+ 4.61.0.94
Added Element.save_element_screenshot_to_disk - uses the same PIL integration that the save window screenshot to disk uses but applied to a single element
- 4.60.3.95
+ 4.61.0.95
Changed popup again - replaced right_justify_buttons with button_justification. Also removed the extra padding that was being added to the buttons. This
matches a changed made to popup_scrolled earlier
- 4.60.3.96
+ 4.61.0.96
More emojis? Yes... more emojis...
- 4.60.3.97
+ 4.61.0.97
The main test harness now shows the python interpreter used to launch the test harness to make clearer what's running
- 4.60.3.98
+ 4.61.0.98
Better alignment of text in test harness
Fixed mispelling in SystemTray.show_message - crashed if an int was passed in as the time value
- 4.60.3.99
+ 4.61.0.99
popup_get_text - Addition of history feature to bring up to same level as other popup_get_ functions.
- 4.60.3.100
+ 4.61.0.100
Set the "Active" foreground and background colors for Menu and ButtonMenu items. Automatically uses the swapped foreground and background colors.
This impacts both inside the menus themseleves as well as the ButtonMenus so that when they are used in a MenubarCustom they mouseover nicely now.
- 4.60.3.101
+ 4.61.0.101
Added Window.is_hidden method. Returns True if the window is currently hidden
- 4.60.3.102
+ 4.61.0.102
Fixed error in the main test harness "not modal" popup test. Was setting the "Force Modal" setting to true after the popup test.
- 4.60.3.103
+ 4.61.0.103
Trinket is detected using a new mechansim now. The previous one was waayyy too simnple and as a result has broken in the past week.
- 4.60.4.104
+ 4.61.0.104
Version bump to keep up with the PyPI emergency 4.60.4 release
- 4.60.4.105
+ 4.61.0.105
Added SYMBOL_BULLET character
- 4.60.4.106
+ 4.61.0.106
Neon Green, Blue, Yellow themes... was writing some tests using them and thought why not start a new theme color category... "neon"
- 4.60.4.107
+ 4.61.0.107
Fixed an unreported problem perhaps... Added saving new menu into the Menu.Widget memeber variable in the Menu.update method.
- 4.60.4.108
+ 4.61.0.108
Added drop_whitespace to the docstring for popup. Parm has been in the code for quite some time but forgot the docstring so it's not in the SDK reference.
- 4.60.4.109
+ 4.61.0.109
Changed error message in error window when an element reuse has been detected in a layout. Previous message wasn't clear why there was an error.
- 4.60.4.110
+ 4.61.0.110
Added very detailed information to popup_error_with_traceback if the Exception information is passed in as one of the arguments
- 4.60.4.111
+ 4.61.0.111
Menu Element - delete all items in existing Menu widget rather than making a new one when the Menu definition changes
- 4.60.4.112
+ 4.61.0.112
Input.update - added font parameter
- 4.60.4.113
+ 4.61.0.113
Dark Blue 18 theme, a materially kinda theme, added - tip - experiment like PySimpleGUI does when "computing" colors. Grab a color of a part of a theme and use it as a background or a secondary button color. In other words, mix and match since the colors should all work together by design.
- 4.60.4.114
+ 4.61.0.114
Added execute_py_get_running_interpreter to differentiate between the one in the settings file versus currently running interpreter
- 4.60.4.115
+ 4.61.0.115
Image Element... added Zooooooooommmmm parameter
- 4.60.4.116
+ 4.61.0.116
Proliferiation/infection of the zoom parameter to more elements with images - Button, ButtonMenu
Note that zoom and subsample can BOTH be used. This enables fractional scaling. Want 2/3 the size of the image? subsample=3, zoom=2
Tab is the remaining element this is being added to
The Buttons implemented as functions need this addition as well
Addition of the image_source parameter to Button and Button.update. This way of specifying images is commonly used in other elements
Fixed ButtonMenu bug - subsample was not being applied to initial image in the layout
- 4.60.4.117
+ 4.61.0.117
Fix for set_vscroll_position not working correctly for a scrollable Column
- 4.60.4.118
+ 4.61.0.118
Completed addition of zoom options for images by adding image_zoom parameter to Tab element
- 4.60.4.119
+ 4.61.0.119
Fixed Neon Yellow theme. Had an extra "#" in a color.
- 4.60.4.120
+ 4.61.0.120
New coupon code
- 4.60.4.121
+ 4.61.0.121
New Jedi emoji
- 4.60.4.122
+ 4.61.0.122
Swapped Push and Stretch, VPush and VStretch. Made Push and VPush the function and Stratch and VStresth the aliases. Did this because
Push is used almost universally, not Stretch.
- 4.60.4.123
+ 4.61.0.123
Fix for incorrect values for Element.ttk_style and Element.ttk_style_name. Some elements had values overwritten if a scrollbar, etc, was used
Changed a number of the ttk elements (Button for example) to use the base name as the parm to creating the custom style to achieve
a more predictable naming style (relies on the formula used in the create style function rather than ad hoc adding "custom" onto name)
- 4.60.4.124
+ 4.61.0.124
Multiline Element docstring fixes
- 4.60.4.125
+ 4.61.0.125
Addition of 2 overrides to Window.find_element so that more control is available to applications wishing to perform special key lookups
- 4.60.4.126
+ 4.61.0.126
Made button_color parameter's docstring value consistent across all calls. Now set to - (str, str) | str
- 4.60.4.127
+ 4.61.0.127
User settings delete calls - aded silent_on_error option so deletes of non-existant entries can uappen silently if desired.
popup_quick_message - now defaults to keep-on-top to True
- 4.60.4.128
+ 4.61.0.128
Cleaned up User Settings API code for porting
- 4.60.4.129
+ 4.61.0.129
button_color parm added to ButtonMenu.update
- 4.60.4.130
+ 4.61.0.130
New coupon
- 4.60.4.131
+ 4.61.0.131
Window timers feature added. Get a single or repeating timer events for your Window by calling window.timer_start
- 4.60.4.132
+ 4.61.0.132
Added the Window.stop_all method to stop all timers for a window
- 4.60.4.133
+ 4.61.0.133
Added Window.timer_get_active_timers to get a list of the active timers for the window
- 4.60.4.134
+ 4.61.0.134
popup_get_date - exposed the fonts as parameters so that the user code and modify them (specifically to get around a Mac font bug)
- 4.60.4.135
+ 4.61.0.135
Renamed QuickMeter to _QuickMeter so that it's clear that it's not an object meant to be used by users
- 4.60.4.136
+ 4.61.0.136
Tree element - if headings is set to None, no headings area is shown
- 4.60.4.137
+ 4.61.0.137
"Take me to error" button is disabled in error traceback popup if not editor is configured. Also adds instructions if no editor.
- 4.60.4.138
+ 4.61.0.138
Added begin_at_sunday_plus to the CalendarButton docstring
- 4.60.4.139
+ 4.61.0.139
Moved debugger constants to inside of the debugger class. Simplified the locals and globals popups.
- 4.60.4.140
+ 4.61.0.140
Experimental change.... Table.get now returns the values from the widget's selection method
- 4.60.4.141
+ 4.61.0.141
Made the Debugger's use of popups change the theme to the same dark gray theme used in the rest of the debugger windows.
- 4.60.4.142
+ 4.61.0.142
Added selected_text_color & selected_background_color to Input element. Will override the default values
- 4.60.4.143
+ 4.61.0.143
Fixed bug in Combo.update - the width of the element wasn't getting updated to match new values
- 4.60.4.144
+ 4.61.0.144
Added selected_text_color & selected_background_color to Multiline element. Will override the default values
- 4.60.4.145
+ 4.61.0.145
Fixed bind_return_key docstrings in the pre-defined buttons. Made the Button bind_return_key docstring more descriptive
+ 4.61.0.146
+ Changed version numbers to 4.61.0 to try and fix the confusion about what's been released to PyPI.
"""
@@ -10836,8 +10838,11 @@ class Window:
# self.TKroot.protocol("WM_DESTROY_WINDOW", self._OnClosingCallback)
# self.TKroot.protocol("WM_DELETE_WINDOW", self._OnClosingCallback)
Window._window_running_mainloop = self
- Window._root_running_mainloop.mainloop()
-
+ try:
+ Window._root_running_mainloop.mainloop()
+ except:
+ print('**** EXITING ****')
+ exit(-1)
# print('Out main')
self.CurrentlyRunningMainloop = False
# if self.LastButtonClicked != TIMEOUT_KEY:
@@ -22243,7 +22248,7 @@ def _error_popup_with_code(title, filename, line_num, *args, emoji=None):
:param emoji: An optional BASE64 Encoded image to shows in the error window
:type emoji: bytes
"""
- editor_filename = _get_editor()
+ editor_filename = execute_get_editor()
emoji_data = emoji if emoji is not None else _random_error_emoji()
layout = [[Text('ERROR'), Text(title)],
[Image(data=emoji_data)]]
@@ -22260,7 +22265,6 @@ def _error_popup_with_code(title, filename, line_num, *args, emoji=None):
max_line_len = max(max_line_len, max([len(s) for s in line]))
layout += [[Text(''.join(line), size=(min(max_line_len, 90), None))] for line in lines]
-
layout += [[Button('Close'), Button('Take me to error', disabled=True if not editor_filename else False), Button('Kill Application', button_color='white on red')]]
if not editor_filename:
layout += [[Text('Configure editor in the Global settings to enable "Take me to error" feature')]]
@@ -23526,7 +23530,7 @@ def _create_full_editor_command(file_to_edit, line_number, edit_format_string):
return command
-def _get_editor():
+def execute_get_editor():
"""
Get the path to the editor based on user settings or on PySimpleGUI's global settings
@@ -26288,4 +26292,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#40e80a71aea2a1b41dfdcba9263cffd1ea8d8dba433feb55ec28f46041ead94584c0357919f99c17c0f55cc1270b5f742f90a6cb967060d420598da884b48952987be0aa687b06556ac829c34bf84d705ef76b6a11eefc2fd3bc808e968f6fe4aca40d643643ec2906f4a8420af6d4fce3ca585591591cce1bf067c77edd7a555f5977205bd8ed1ea55ce615dd47e1f138c54f6fe23dc14764563c00d158164c9b7daab5c5b772c90ad040133a441a45e39b66567f4b957b5db188a8155e2fe72d0c06ba927c55260d1c2e4199a86d69765872b059f5b167202fcebed340c6fd91da8d7831f7ced36886e0a5a51947aeba24f62e8a5675ec01ee0e122983bc8cc9d9c7dfc77d78708f8e889ba91676b3b183aaf8cae3ed0cf79051561a2cd692f933b5f40a17b987644978c59962ead7011f369580e30d665fd5f4860411df8fea4d1027e653da3b2e7baff69c5035a311143efba8609383af517ed23e363af68fa1a1f95a1ef3c7991b79f55634787e14e32a0c32442feaf4df13a0212754c207cb27a129fc702d206d50d90bfbd4d10d10ede5fba0dedf3ec2c0d66e4741c30033356bc5911de8395977214646517e6e94e8130b32330d0e63fb13ec8eeaee673a68e94151ed9ecb92a506e184df9c53b798277c5cb10acec0e3f2a1dafba2510687d9eaad97a79d729ce2a33b2e9229f03289c111f8f3774e89e329e76c4e
\ No newline at end of file
+#66c76f34d425350d8350621578fe72d8a9882f2a50c36658fd108cdaaf0c8e7d367bf50f46bb3ea2c68f490c918ad05501b46cec335066934ffdb1d97b2d5108bc8a4970ec8912c810315755aca1412410b93e98154544e374a7d72a5f71ab89eddea51281d7e8eccc02703de5632c084f77a0304cf69db30c16348524cd2d72555cba024011f8f1c0bed7a4301c53295d36cad6f49bcdc2fbaaad4f457d8e7eb9e8f7113a5424fdfe3fa4014deee5e44ad1a68916c710a21d270f8940b0d763927369c8a4b8b6f1495a884d8a1af05e4d74808e306e749279c4219b72820d9d6f87cb3065cc1a0b5e9668d776627179d3a75b9592327eaf14b31e457c5f37173a5b8a06dd9677011da86a5d40142f3249cc243e67a0060b1f0ab67128014c92d24e0798f5b90b734f325331d39c265136f8d7ae6de03a934b4e173551660415627651788b23a8784bf66264857ea27bd551950961c8a657d548324781820217e3e49f39b6177a29689d587cbda05a9a89dc1098427ec9862daafb2f5e64e16b5e6af0359c3a8f2044da1685529c271d9ffc84a8bb8fdba87557a3d4bdd1fe6855564a43d8e375e5d0b311d52fe40423bdcc466351af2b7efef19b32a17271132fbc6e565e7d3899a36dafda9cf6d81468df85af00e76f6cd73324eca2812009bc09ff10e656b16d8b004de50e6aac49e10beeac0ba054370878e71eaa3dd3ef
\ No newline at end of file
From 7da029ebf862722b4b780cc354b04d3284099661 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 6 Feb 2023 11:43:54 -0500
Subject: [PATCH 026/145] Fixed typo in docstring
---
DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py b/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py
index d5e1ff32..4a16fbd6 100644
--- a/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py
+++ b/DemoPrograms/Demo_User_Settings_Auto_Load_and_Save.py
@@ -21,7 +21,7 @@ def make_key(key):
the lack of parameters and associated docstrings when creating the layout.
:param key:
- :return: Dict(
+ :return: Dict
"""
return {'default_text':sg.user_settings_get_entry(key, ''), 'key':key}
From f3270e00ecd4e3a21c6add112bdbb99848b32025 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Tue, 7 Feb 2023 07:17:07 -0500
Subject: [PATCH 027/145] And updated version of the "Edit Me" right menu
design pattern
---
DemoPrograms/Demo_Edit_Me_Option.py | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/DemoPrograms/Demo_Edit_Me_Option.py b/DemoPrograms/Demo_Edit_Me_Option.py
index c05130f1..b5e4be90 100644
--- a/DemoPrograms/Demo_Edit_Me_Option.py
+++ b/DemoPrograms/Demo_Edit_Me_Option.py
@@ -1,7 +1,7 @@
import PySimpleGUI as sg
"""
- Demo "Edit Me"
+ Demo "Edit Me" (and Version)
More and more of these Demos are getting an "Edit me" option added.
@@ -12,26 +12,26 @@ import PySimpleGUI as sg
You can add this capability to your program by adding a right click menu to your window and calling the
editor that you set up in the global PySimpleGUI options.
- You need to do 2 things to make this work:
- 1. Add a right click menu - requires you to add 1 parameter to your Window creation
- 2. Add 1 if statement to your event loop.
-
+ A constant MENU_RIGHT_CLICK_EDITME_VER_EXIT, when set at the right click menu shows a "Version" and "Edit Me" meny item.
+
You will need to have first set up your editor by using the menu in sg.main()
- Copyright 2021 PySimpleGUI.org
+ Copyright 2021, 2022, 2023 PySimpleGUI.org
"""
layout = [[sg.Text('Edit this program by right clicking and choosing "Edit me"')],
[sg.Button('Exit')]]
-window = sg.Window('Edit Me Right Click Menu Demo', layout, right_click_menu=[[''], ['Edit Me', 'Exit',]])
+window = sg.Window('Edit Me Right Click Menu Demo', layout, right_click_menu=sg.MENU_RIGHT_CLICK_EDITME_VER_EXIT)
while True: # Event Loop
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Edit Me':
- sg.execute_editor(__file__)
+ sg.execute_editor(__file__)
+ elif event == 'Version':
+ sg.popup_scrolled(__file__, sg.get_versions(), location=window.current_location(), keep_on_top=True, non_blocking=True)
window.close()
From 517262690fd009ad5cce9e0a394eef49d0d57a86 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Tue, 7 Feb 2023 11:37:05 -0500
Subject: [PATCH 028/145] New Demo Program Custom Images Dark Theme
---
...rk_Custom_Elements_Check_Toggle_Buttons.py | 96 +++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 DemoPrograms/Demo_Theme_Dark_Custom_Elements_Check_Toggle_Buttons.py
diff --git a/DemoPrograms/Demo_Theme_Dark_Custom_Elements_Check_Toggle_Buttons.py b/DemoPrograms/Demo_Theme_Dark_Custom_Elements_Check_Toggle_Buttons.py
new file mode 100644
index 00000000..9292e17e
--- /dev/null
+++ b/DemoPrograms/Demo_Theme_Dark_Custom_Elements_Check_Toggle_Buttons.py
@@ -0,0 +1,96 @@
+
+import PySimpleGUI as sg
+
+
+DarkGreyFig = {'BACKGROUND': '#232429',
+ 'TEXT': '#828692',
+ 'INPUT': '#333742',
+ 'TEXT_INPUT': '#f7fbff',
+ 'SCROLL': '#505F69',
+ 'BUTTON': ('#fafdff', '#1d5ffe'),
+ 'PROGRESS': ('#505F69', '#32414B'),
+ 'BORDER': 1, 'SLIDER_DEPTH': 0, 'PROGRESS_DEPTH': 0,
+ }
+
+# Add your dictionary to the PySimpleGUI themes
+sg.theme_add_new('DarkGreyFig', DarkGreyFig)
+
+# Switch your theme to use the newly added one
+sg.theme('Dark GreyFig')
+
+
+def Check(state=None, key=None):
+ return sg.Image(state, key=key, metadata=state, enable_events=True)
+
+def Toggle(state=None, key=None):
+ return sg.Image(state, key=key, metadata=state, enable_events=True)
+
+def DarkButton(state=None, key=None):
+ return sg.Image(state, key=key, metadata=state, enable_events=True)
+
+def main():
+ gray_bg= '#333742'
+
+ col_cb_layout = [ [Check(cb_blank, ('-CB-', 0)), sg.Text('Label')],
+ [Check(cb_check, ('-CB-', 1)), sg.Text('Label')],
+ [Check(cb_minus, ('-CB-', 2)), sg.Text('Label')],
+ [sg.Text(s=(1,2))],
+ [Toggle(toggle_light, ('-TOGGLE-', 0)), sg.Text('Light')],
+ [Toggle(toggle_dark, ('-TOGGLE-', 1)), sg.Text('Dark')],
+ ]
+
+ col_left_layout = [ [sg.Text('Label')],
+ [sg.Input(key='-IN-', border_width=0, s=30)],
+ [sg.Frame('Tags', [[sg.Image(button_green_keyword, background_color=gray_bg), sg.Image(button_orange_keyword,background_color=gray_bg)]], background_color=gray_bg, border_width=0)],
+ [sg.Frame('', [[DarkButton(button_dark, key=('-DARK BUTTON-', 0)), DarkButton(button_darker, key=('-DARK BUTTON-', 1)), DarkButton(button_darker, key=('-DARK BUTTON-', 2))]])],
+ [sg.Image(submit_button) ] ]
+
+
+ layout = [[sg.Column(col_left_layout), sg.Col(col_cb_layout)]]
+ window = sg.Window('Dark Custom Mockup', layout, font='_ 16', border_depth=0, element_padding=(10,10),use_custom_titlebar=True, titlebar_background_color=sg.theme_input_background_color())
+
+ while True: # Event Loop
+ event, values = window.read()
+ print(event, values)
+ if event == sg.WIN_CLOSED or event == 'Exit':
+ break
+
+ if event[0].startswith('-CB-'):
+ if window[event].metadata == cb_blank:
+ window[event].update(cb_check)
+ window[event].metadata = cb_check
+ elif window[event].metadata == cb_check:
+ window[event].update(cb_minus)
+ window[event].metadata = cb_minus
+ elif window[event].metadata == cb_minus:
+ window[event].update(cb_blank)
+ window[event].metadata = cb_blank
+ elif event[0].startswith('-TOGGLE-'):
+ if window[event].metadata == toggle_dark:
+ window[event].update(toggle_light)
+ window[event].metadata = toggle_light
+ elif window[event].metadata == toggle_light:
+ window[event].update(toggle_dark)
+ window[event].metadata = toggle_dark
+ elif event[0].startswith('-DARK BUTTON-'):
+ [window[('-DARK BUTTON-', i)].update(button_darker) for i in range(3)]
+ window[event].update(button_dark)
+
+ window.close()
+
+if __name__ == '__main__':
+ button_green_keyword = b'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'
+ button_orange_keyword = b'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'
+
+ cb_blank = b'iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAD+UlEQVR4nM2Y328bRRDHP7O354tTXYpLfsG/UMkIUNWWIiHEG38w4oEn0qoIgdqo/RPSR5vgNBfbt7vDw96eL46bGBqsfKWVvXt3u9+ZnZ2ZHeEDePToe83zDGt7FEWOtT1UPdb2gACYK78BMMYAoKqEEGJTRwgBVaWqKqbTKa//fC6r1r00+HD4WPf3DimKgiyzOFfjfQCUEBTnaozJAG0+Xf4F7z0qICKICAbBGFn0jaHX6+Gc4/TvMb+9+EVWEhp++UT39w+xWY/pdEZVVYQQEImvJGlvgmQGVV30NZGL/SzLEBF6vR5lWeK95927d7w5fiEANn24v39InueMxn/hfVSviKBoS8z28htJJQG6pACUON/c1YgI0/mManrB7u4uh59/xpvj+J4BePrtD7q9vc1oNKKu65ZMUnGSynt/o4ZU9QqZNO69J89zVJWiKHDOMR6PyfOcZ9/9qAD24fCxPniwy+npKSGE1ihBm8m70sfx/4IkoHOOLMuo6xprLc7Nef9+wmBwP2rIWouq4pxbKdn/BRFptelcPIXDr5+qLYoiDtYBDYJkNxvux6GxTV2sU9c13nu2t7cxRVEQQsB73xik+fBct0mr2Q0Radcven1snucEDyEo1mYE9CNJLWv48lwioCqoCiIGY6RxKWCtxWRmcZRFNqed5B66YyaeatMSuh2jNkttmQyANMJLVGgAUUHIMMnab4/QeuhGgO66JvkdEZCV4e62iUD0cTFGGmvAgNfoNDdjNGtCJdwtQrApp7MGkh3dGUIJd4ZQOnV3hlDC3SOU0g9jzEYcY3LEXceYciVVxayTJ98mluNYN1KISCTUHdwksUSiC5PyoE0RWhXpu8+M9x5jTLuPm8Klq1Kztvce45xrCW0aXQM3xlDXdSS0Se0sn7L0P8synHObP2XL6Bq39x5zcX7OvX4fo3IlhU3XlH9j8KoeCIho2yCg6lH1bXaa7oCqSp7nAFRVhXn16kicc5RlyWw2g7DY09TSzXUdYinhaysfDYEsy7DWkuc51tr2thFCaJ+9/uNILMBkcsrOzicU57Eq4ZtLY7KtbrtZQ0LMmbtaBu+VmCn6lnhSRFmWjMfjOA4wGo24uLjg08GgZZ8MLfW70l9PaGETaY5V2oZ47dnZ2QHg5dHPi+rH27e/i7Xf6N7eHgcHB1RVRVVVsfDgA9JsQV27NUg1FRMNl0OCWWg4z+LWDQYD5vM5Jycnna87GA6f6L3yPmVZsrW1hXOO2Wy2KM00VbHrEMJlDS1afG6Mod/v45xjMpnw/NefVheslvHFV8+0KAr6/T5FUQCxOra1tXUtIaMLDSYBnHN47/He49ycs7Mzjo9frlz7HzLiWEBTYnmBAAAAAElFTkSuQmCC'
+
+ cb_check = b'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'
+ cb_minus = b'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'
+ toggle_light = b'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'
+ toggle_dark = b'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'
+ submit_button = b'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'
+
+ button_dark = b'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'
+
+ button_darker = b'iVBORw0KGgoAAAANSUhEUgAAAGsAAAA2CAMAAAD3cZcXAAACuFBMVEUfIiscHSEkJy4gIyohJCsjKC4kJjIeISghJC0jJi0gIywjJi9FSVRKTllMUFt8f4tydIBzdoJrbnl6fIh4e4Z9gIuDhpB8f4pucXwiJjF7fop/go2ChY97fodsb3p4eoV6fYh/gYyChY58fYdRVWBWWWROUlxsb3mFiJFVVmBcXWdUVWBSUl1aW2ROT1gdISp8foloa3R7fYhpbHVucXt1d4NWWWNdYGp7fYlgYWokKDF8f4l3eoR3eoVfYm1sbnlhY207PURSVF1tbngiJi9ZXGZhY24+P0YmJy0nKC4lJyxAQUdHSlVucXpiY246O0IoKS8pKzEyMzlMTVYvMDZJS1R7foh1eYI/QUc9PkVdYGtvcXs8PkMkJSpoaXN6fIZBQkl3eIJ9f4oeHyMfICQpKi9maHJtcHl2eINLS1MrLDI2Nz2Fh5EkJzBPUVc9PkNGR05BQ0pmaXNucHo7PUNNTVVoaXRISVBnaHOHiJOChI55e4VAQUhnanQ+QEc6PEJRUlqGh5J+f4lzdX8xMjgsLjQhIic8PURGR09MTlVnaHJTVmBYW2VYWmZXWWRZWmNfX2lHSlIiJS6Ago19foiFh5I6O0FkZ3IjJCl1d4JIS1NdYGmDho96e4UnJy81Nz0sLTJvcnwnKS55e4Z7fol9f4liZ21+gYyBhI5sbHZvcX1tcXttcXpwdH5pbHd4eYMwMjdlaHRtcHssLjNJTVdWWGNNUFhqb3iHiZNeYGx6fIdvcn1zdYFhZG50eIIcIyuBhI9maXGDhY6EhY+DhI+EhpJKTFh5e4d5fIZ2eoGAg4xLT1pTV2B/goxzd4B0doFOUV1VWGOHiZSGiZNdYmpfZm5/g41kZ3EhIy8gJSseIykfIywjJzBMT1ofJCpKTVdOUVtISlQdJCwlKC8fIikkJCwdICkAAACsCdXOAAAA6HRSTlP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8Asi2gugAAAwJJREFUeJzdmAdTE1EQx7OJSonlrxRRo2KvWFAsIAqWE1tERQRRQcWKWLGhYhcVFAWxgdjF3rBi7xV7x240X8P37iCEGaIzN8kbx525293bffebN2/fldWYi0VDjhGtzkJQVDkHgYpEZ8VyLIlJeQvL4SgmRSwRKA5jrApiWE6cJQbFJqYxOwtkiUKRk0CWi0AWaVz/U5awMmQsvUCWONQ/w6poK1DJ9pjK6lhVULXsQDW42RrjDg9VLE9ULzvgBdgYUqMmaqliGVC77EAd1LU1xhv1VLHqo0Epv2GjxorRBE2JmjVvURJq6dNK1q3b2IXV1heAdztutmcsP+b5dVBCHTsxx7czs/wD7MHqAkW8ZFZgoOJ15aFuCAruHhyEHkQ97TGvXpB6h/Tp209Cf6IBgHFg6KDBRmAIkQ+CwlhGWBCGknO4PeY1LEJWkRhOFAWM4M5II0YRRSNSDsVgNNEYlSxDqfUay47YcRLGE02AMVa+FoGJNAmYLDtxmELxvnZhTZ02fYbElmgm0ayimVAC22izgTlzuczDfHJVu16J1qwFvBSkhRIWcVaScnExYy2BRZaSXm0dJmKZxV7OamPFylWUzFlRxfOKAFavAdampK5bn5a2YSOlByBDFcuATRY7E5tlnYwtvOaNW2UvCdtoO5BleQf6q31uZGNHTglrJ1e7JM7aDcRwb48RWUR7sU9O2Z95gCgcuapYB5Fx6HDUkaPHjhOdgHQyNCSBFccpotNsfyXl5cWx/XWGKAVwO0vn2GY/T6S2Ni5YFv0iUb5suAMMfAm4rARSed6VoqyrRNc8cF0V68bNW7fvGLKzPXPvMi86H/fu04OHj4geFzyhp/zuz5TE576ZL14WvOLm6zdvVbFIp9O/S3//ofAjd7T0iavP/FTIji9fv5U15vsf7vevfG/YnfVDIEsrkBUvkCXyG1vkv4PAQhT4X6kVyNJpzDl/z7KPCO6lmAXtZpO43pde6bOZRLDE9SrJqgf707Ekk3W/12z+5eqgp7CLqRjxG7LsF9Z68qMOAAAAAElFTkSuQmCC'
+ main()
From e047ffe684e51ddd0e6da8d4ca5a0d5ca1b83e87 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Tue, 7 Feb 2023 18:32:38 -0500
Subject: [PATCH 029/145] New Udemy Coupon Code
---
docs/cookbook.md | 4 ++--
docs/index.md | 4 ++--
docs/readme.md | 4 ++--
readme.md | 4 ++--
readme_creator/markdown input files/1_HEADER_top_part.md | 4 ++--
readme_creator/output/index.md | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/docs/cookbook.md b/docs/cookbook.md
index 2205af6e..53b73cc3 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 266B9C51C90B3728782E
+ 07860559FF2298EF51E7
-
diff --git a/readme_creator/markdown input files/1_HEADER_top_part.md b/readme_creator/markdown input files/1_HEADER_top_part.md
index 35b757c7..dc06797a 100644
--- a/readme_creator/markdown input files/1_HEADER_top_part.md
+++ b/readme_creator/markdown input files/1_HEADER_top_part.md
@@ -27,8 +27,8 @@ HOW DO I INSERT IMAGES ???
-
-
Python GUIs for Humans
+
+
Python GUIs for HumansTM
From 884d49a14f0a8db03e1ea092888881a3365466e9 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sun, 25 Jun 2023 17:30:19 +0000
Subject: [PATCH 101/145] Automated Update!
---
docs/Screens.md | 6 ++++++
docs/Screens2.md | 22 ++++++++++++++++++++++
2 files changed, 28 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 4a3c93fc..d2c5e36d 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,9 @@
+[luisegarduno](https://github.com/luisegarduno) 2023-06-25T05:18:40Z
+
+
+
+-----------
+
[mrtnbm](https://github.com/mrtnbm) 2023-05-25T16:24:22Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index ad705c3d..f2b1b736 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,25 @@
+[luisegarduno](https://github.com/luisegarduno) 2023-06-25T05:18:40Z
+**Chess (updated!)**
+
+Originally added/created by @MikeTheWatchGuy, the chess demos (player vs. player & player vs. Ai) were included in PySimpleGUI ([see here](https://github.com/PySimpleGUI/PySimpleGUI/tree/8b23740fca08b7f5bad3f0d32760f42a5202d3e1/Chess)), but were removed from the main branch towards the end of 2022.
+
+In terms of the changes that I made to the original code (see #5052):
+
+I updated **requirements.txt** to include the latest versions:
+```
+PySimpleGUI==4.60.5
+python-chess==1.999
+```
+I then made changes within both of the demo files to remove any outdated or deprecated code causing errors. I also added compatibility for Linux, allowing users to import files that do not end in ".exe".
+
+Both chess demos have only been tested on Ubuntu 20.04 but should also work on Windows since not much was changed from the original code. Lastly, for the engine, I resulted in having to use Stockfish 13, since there was several issues when trying to use Stockfish 14 or Stockfish 15.
+
+https://github.com/luisegarduno/ChessGUI
+
+
+
+-----------
+
[mrtnbm](https://github.com/mrtnbm) 2023-05-25T16:24:22Z
Thanks to PSG, I've created the nicest GUI I've ever made that I'm now using for my own little naive prompt lib.
From d97777b2626c0125bd596b95711d579b9da98e54 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 3 Jul 2023 18:47:04 -0400
Subject: [PATCH 102/145] Corrected the Table.get docstring to reflect that it
returns a list of ints
---
PySimpleGUI.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index e695c4f8..d8fd3889 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.186 Unreleased"
+version = __version__ = "4.61.0.187 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -442,6 +442,8 @@ _change_log = """
Fix for crash when no headings specified for a table by casting values into strings
4.61.0.186
Fix for popup_get_file when using no_window=True. Now returns None if cancelled or window closed
+ 4.61.0.187
+ Corrected the Table.get docstring to reflect that it returns a list of ints
"""
@@ -9575,11 +9577,12 @@ class Table(Element):
def get(self):
"""
- Get the selected rows using tktiner's selection method. Experimenting with this change....
+ Get the selected rows using tktiner's selection method. Returns a list of the selected rows.
:return: the current table values
- :rtype: List[List[Any]]
+ :rtype: List[int]
"""
+
selections = self.TKTreeview.selection()
selected_rows = [int(x) - 1 for x in selections]
return selected_rows
From 3de64e7d99ba36100bfb487472160e5e3a36d3d8 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 3 Jul 2023 18:49:55 -0400
Subject: [PATCH 103/145] Another try at correcting the Table.get docstring
---
PySimpleGUI.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index d8fd3889..afa86641 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.187 Unreleased"
+version = __version__ = "4.61.0.188 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -444,6 +444,8 @@ _change_log = """
Fix for popup_get_file when using no_window=True. Now returns None if cancelled or window closed
4.61.0.187
Corrected the Table.get docstring to reflect that it returns a list of ints
+ 4.61.0.188
+ Finished correcting the Table.get docstring.... think I got it right this time....
"""
@@ -9579,7 +9581,7 @@ class Table(Element):
"""
Get the selected rows using tktiner's selection method. Returns a list of the selected rows.
- :return: the current table values
+ :return: a list of the index of the selected rows (a list of ints)
:rtype: List[int]
"""
From 2ce3c7f75e6344ad13048c416ceda7b414eba6d4 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Tue, 4 Jul 2023 08:50:08 -0400
Subject: [PATCH 104/145] Changed Table click events to be generated on Button
Release instead of Button (down)
---
PySimpleGUI.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index afa86641..840a3e06 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.188 Unreleased"
+version = __version__ = "4.61.0.189 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -446,6 +446,9 @@ _change_log = """
Corrected the Table.get docstring to reflect that it returns a list of ints
4.61.0.188
Finished correcting the Table.get docstring.... think I got it right this time....
+ 4.61.0.189
+ Changed Table click events to be generated on Button Release instead of Button (down). Was not getting the
+ correct selected rows in the values dictionary when the click event was generated using down. Now the selected rows is correct
"""
@@ -9566,7 +9569,7 @@ class Table(Element):
self.TKTreeview.selection_set(selections)
# print(selections)
self.SelectedRows = [int(x) - 1 for x in selections]
- # print('The new selected rows = ', self.SelectedRows)
+ # print('The new selected rows = ', self.SelectedRows, 'selections =', selections)
if self.enable_click_events is True:
if self.Key is not None:
self.ParentForm.LastButtonClicked = (self.Key, TABLE_CLICKED_INDICATOR, (row, column))
@@ -17767,7 +17770,7 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
treeview.configure(style=style_name)
# scrollable_frame.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1], expand=True, fill='both')
if element.enable_click_events is True:
- treeview.bind('', element._table_clicked)
+ treeview.bind('', element._table_clicked)
if element.right_click_selects:
if running_mac():
treeview.bind('', element._table_clicked)
From aaf391508ccb3fd61275bc83aa0a2ca8df30d62e Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Wed, 12 Jul 2023 17:20:56 -0400
Subject: [PATCH 105/145] New tagline. Updated call reference using newest
docstrings
---
docs/call reference.md | 8 ++++----
docs/cookbook.md | 4 ++--
docs/index.md | 6 +++---
docs/readme.md | 4 ++--
readme.md | 4 ++--
readme_creator/markdown input files/1_HEADER_top_part.md | 6 +++---
readme_creator/output/call reference.md | 8 ++++----
readme_creator/output/index.md | 6 +++---
8 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/docs/call reference.md b/docs/call reference.md
index 90b18ab3..b004ccac 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -11490,13 +11490,13 @@ Parameter Descriptions:
### get
-Get the selected rows using tktiner's selection method. Experimenting with this change....
+Get the selected rows using tktiner's selection method. Returns a list of the selected rows.
`get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values |
+|List[int]| **return** | a list of the index of the selected rows (a list of ints) |
### get_next_focus
@@ -11720,13 +11720,13 @@ The following methods are here for backwards compatibility reference. You will
### Get
-Get the selected rows using tktiner's selection method. Experimenting with this change....
+Get the selected rows using tktiner's selection method. Returns a list of the selected rows.
`Get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values |
+|List[int]| **return** | a list of the index of the selected rows (a list of ints) |
### SetFocus
diff --git a/docs/cookbook.md b/docs/cookbook.md
index c99da19d..98473f4c 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -1,7 +1,7 @@
diff --git a/readme_creator/markdown input files/1_HEADER_top_part.md b/readme_creator/markdown input files/1_HEADER_top_part.md
index dc06797a..320a4997 100644
--- a/readme_creator/markdown input files/1_HEADER_top_part.md
+++ b/readme_creator/markdown input files/1_HEADER_top_part.md
@@ -27,8 +27,8 @@ HOW DO I INSERT IMAGES ???
-
-
Python GUIs for HumansTM
+
+
User Interfaces for HumansTM
@@ -96,7 +96,7 @@ HOW DO I INSERT IMAGES ???
# PySimpleGUI User's Manual
-## Python GUI For Humans - Transforms tkinter, Qt, Remi, WxPython into portable people-friendly Pythonic interfaces
+## User Interfaces for Humans - Transforms tkinter, Qt, Remi, WxPython into portable people-friendly Pythonic interfaces
## The Call Reference Section Moved to here
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index 90b18ab3..b004ccac 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -11490,13 +11490,13 @@ Parameter Descriptions:
### get
-Get the selected rows using tktiner's selection method. Experimenting with this change....
+Get the selected rows using tktiner's selection method. Returns a list of the selected rows.
`get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values |
+|List[int]| **return** | a list of the index of the selected rows (a list of ints) |
### get_next_focus
@@ -11720,13 +11720,13 @@ The following methods are here for backwards compatibility reference. You will
### Get
-Get the selected rows using tktiner's selection method. Experimenting with this change....
+Get the selected rows using tktiner's selection method. Returns a list of the selected rows.
`Get()`
|Type|Name|Meaning|
|---|---|---|
-|List[List[Any]]| **return** | the current table values |
+|List[int]| **return** | a list of the index of the selected rows (a list of ints) |
### SetFocus
diff --git a/readme_creator/output/index.md b/readme_creator/output/index.md
index ec2aba76..11810190 100644
--- a/readme_creator/output/index.md
+++ b/readme_creator/output/index.md
@@ -1,7 +1,7 @@
-
-
Python GUIs for Humans
+
+
User Interfaces for HumansTM
@@ -57,7 +57,7 @@
# PySimpleGUI User's Manual
-## Python GUI For Humans - Transforms tkinter, Qt, Remi, WxPython into portable people-friendly Pythonic interfaces
+## User Interfaces for Humans - Transforms tkinter, Qt, Remi, WxPython into portable people-friendly Pythonic interfaces
## The Call Reference Section Moved to here
From 5035d24f2c17e056e402e05fc5669cfcc323a71d Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 31 Jul 2023 12:31:59 -0400
Subject: [PATCH 106/145] Addition of black2 theme, Fix typo of text in
_widget_was_created
---
PySimpleGUI.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 840a3e06..8d0107b1 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.189 Unreleased"
+version = __version__ = "4.61.0.190 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -449,6 +449,9 @@ _change_log = """
4.61.0.189
Changed Table click events to be generated on Button Release instead of Button (down). Was not getting the
correct selected rows in the values dictionary when the click event was generated using down. Now the selected rows is correct
+ 4.61.0.190
+ Addition of black2 theme
+ Fix typo of text in _widget_was_created
"""
@@ -2186,7 +2189,7 @@ class Element():
if SUPPRESS_WIDGET_NOT_FINALIZED_WARNINGS:
return False
- warnings.warn('You cannot Update element with key = {} until the window.read() is called or finalized=True when creating window'.format(self.Key), UserWarning)
+ warnings.warn('You cannot Update element with key = {} until the window.read() is called or set finalize=True when creating window'.format(self.Key), UserWarning)
if not SUPPRESS_ERROR_POPUPS:
_error_popup_with_traceback('Unable to complete operation on element with key {}'.format(self.Key),
'You cannot perform operations (such as calling update) on an Element until:',
@@ -19713,6 +19716,8 @@ LOOK_AND_FEEL_TABLE = {
"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, },
"Black": {"BACKGROUND": "#000000", "TEXT": "#FFFFFF", "INPUT": "#4D4D4D", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#707070", "BUTTON": ("#000000", "#FFFFFF"),
"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, },
+ "Black2": {"BACKGROUND": "#000000", "TEXT": "#FFFFFF", "INPUT": "#000000", "TEXT_INPUT": "#FFFFFF", "SCROLL": "#FFFFFF", "BUTTON": ("#000000", "#FFFFFF"),
+ "PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, },
"Tan": {"BACKGROUND": "#fdf6e3", "TEXT": "#268bd1", "INPUT": "#eee8d5", "TEXT_INPUT": "#6c71c3", "SCROLL": "#eee8d5", "BUTTON": ("#FFFFFF", "#063542"),
"PROGRESS": DEFAULT_PROGRESS_BAR_COMPUTE, "BORDER": 1, "SLIDER_DEPTH": 0, "PROGRESS_DEPTH": 0, },
"TanBlue": {"BACKGROUND": "#e5dece", "TEXT": "#063289", "INPUT": "#f9f8f4", "TEXT_INPUT": "#242834", "SCROLL": "#eee8d5", "BUTTON": ("#FFFFFF", "#063289"),
From 854bdccdd33a75bf6b6a57b16b2be7dee0588940 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 10 Aug 2023 12:44:33 -0400
Subject: [PATCH 107/145] Allow window resizing when in single photo mode.
Updated the PIL resizing to much more recent resizing code.
---
...mo_Desktop_Widget_Digital_Picture_Frame.py | 160 ++++++++++++++----
1 file changed, 123 insertions(+), 37 deletions(-)
diff --git a/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py b/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py
index 8ee2c959..8aec989c 100644
--- a/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py
+++ b/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py
@@ -1,8 +1,12 @@
import PySimpleGUI as sg
import datetime
-import PIL.Image, PIL.ImageTk
+import PIL
+from PIL import Image
import random
import os
+import io
+import base64
+
"""
Another simple Desktop Widget using PySimpleGUI
@@ -16,17 +20,76 @@ import os
* How long to show the image and if you wnt this time to vary semi-randomly
* Folder containing your images
- Copyright 2021 PySimpleGUI
+ Copyright 2021, 2023 PySimpleGUI
"""
ALPHA = 0.9 # Initial alpha until user changes
refresh_font = sg.user_settings_get_entry('-refresh font-', 'Courier 8')
-def convert_to_bytes(file_or_bytes, resize=None):
- image = PIL.Image.open(file_or_bytes)
- image.thumbnail(resize)
- photo_img = PIL.ImageTk.PhotoImage(image)
- return photo_img
+
+def make_square(im, fill_color=(0, 0, 0, 0)):
+ x, y = im.size
+ size = max(x, y)
+ new_im = Image.new('RGBA', (size, size), fill_color)
+ new_im.paste(im, (int((size - x) / 2), int((size - y) / 2)))
+ return new_im
+
+def get_image_size(source):
+ if isinstance(source, str):
+ image = PIL.Image.open(source)
+ elif isinstance(source, bytes):
+ image = PIL.Image.open(io.BytesIO(base64.b64decode(source)))
+ else:
+ image = PIL.Image.open(io.BytesIO(source))
+
+ width, height = image.size
+ return (width, height)
+
+def convert_to_bytes(source, size=(None, None), subsample=None, zoom=None, fill=False):
+ """
+ Will convert into bytes and optionally resize an image that is a file or a base64 bytes object.
+ Turns into PNG format in the process so that can be displayed by tkinter
+ :param source: either a string filename or a bytes base64 image object
+ :type source: (Union[str, bytes])
+ :param size: optional new size (width, height)
+ :type size: (Tuple[int, int] or None)
+ :param subsample: change the size by multiplying width and height by 1/subsample
+ :type subsample: (int)
+ :param zoom: change the size by multiplying width and height by zoom
+ :type zoom: (int)
+ :param fill: If True then the image is filled/padded so that the image is square
+ :type fill: (bool)
+ :return: (bytes) a byte-string object
+ :rtype: (bytes)
+ """
+ # print(f'converting {source} {size}')
+ if isinstance(source, str):
+ image = PIL.Image.open(source)
+ elif isinstance(source, bytes):
+ image = PIL.Image.open(io.BytesIO(base64.b64decode(source)))
+ else:
+ image = PIL.Image.open(io.BytesIO(source))
+
+ width, height = image.size
+
+ scale = None
+ if size != (None, None):
+ new_width, new_height = size
+ scale = min(new_height/height, new_width/width)
+ elif subsample is not None:
+ scale = 1/subsample
+ elif zoom is not None:
+ scale = zoom
+
+ resized_image = image.resize((int(width * scale), int(height * scale)), Image.ANTIALIAS) if scale is not None else image
+ if fill and scale is not None:
+ resized_image = make_square(resized_image)
+ # encode a PNG formatted version of image into BASE64
+ with io.BytesIO() as bio:
+ resized_image.save(bio, format="PNG")
+ contents = bio.getvalue()
+ encoded = base64.b64encode(contents)
+ return encoded
def choose_theme(location):
@@ -43,6 +106,15 @@ def choose_theme(location):
else:
return None
+def reset_settings():
+ sg.user_settings_set_entry('-time per image-', 60)
+ sg.user_settings_set_entry('-random time-', False)
+ sg.user_settings_set_entry('-image size-', (None, None))
+ sg.user_settings_set_entry('-image_folder-', None)
+ sg.user_settings_set_entry('-location-', (None, None))
+ sg.user_settings_set_entry('-single image-', None)
+ sg.user_settings_set_entry('-alpha-', ALPHA)
+
def make_window(location):
alpha = sg.user_settings_get_entry('-alpha-', ALPHA)
@@ -61,7 +133,7 @@ def make_window(location):
layout = [[sg.Image(k='-IMAGE-', enable_events=True)],
[sg.pin(sg.Column(refresh_info, key='-REFRESH INFO-', element_justification='c', visible=sg.user_settings_get_entry('-show refresh-', True)))]]
- window = sg.Window('Photo Frame', layout, location=location, no_titlebar=True, grab_anywhere=True, margins=(0, 0), element_justification='c', element_padding=(0, 0), alpha_channel=alpha, finalize=True, right_click_menu=right_click_menu, keep_on_top=True, enable_close_attempted_event=True)
+ window = sg.Window('Photo Frame', layout, location=location, no_titlebar=True, grab_anywhere=True, margins=(0, 0), element_justification='c', element_padding=(0, 0), alpha_channel=alpha, finalize=True, right_click_menu=right_click_menu, keep_on_top=True, enable_close_attempted_event=True, enable_window_config_events=True)
return window
@@ -69,11 +141,10 @@ def make_window(location):
def main():
loc = sg.user_settings_get_entry('-location-', (None, None))
sg.theme(sg.user_settings_get_entry('-theme-', None))
- window = make_window(loc)
time_per_image = sg.user_settings_get_entry('-time per image-', 60)
vary_randomly = sg.user_settings_get_entry('-random time-', False)
- width, height = sg.user_settings_get_entry('-image size-', (400,300))
+ width, height = sg.user_settings_get_entry('-image size-', (None, None))
image_folder = sg.user_settings_get_entry('-image_folder-', None)
try:
@@ -82,36 +153,26 @@ def main():
image_folder = None
sg.user_settings_set_entry('-image_folder-', None)
- single_image = sg.user_settings_get_entry('-single image-', None)
+ image_name = single_image = sg.user_settings_get_entry('-single image-', None)
if image_folder is None and single_image is None:
- while True:
- images = None
- image_folder = sg.popup_get_folder('Choose location of your images', location=window.current_location(), keep_on_top=True)
- if image_folder is not None:
- sg.user_settings_set_entry('-image_folder-', image_folder)
- break
- else:
- if sg.popup_yes_no('No folder entered','Go you want to exit the program entirely?', keep_on_top=True) == 'Yes':
- exit()
- elif single_image is None:
+ image_name = single_image = sg.popup_get_file('Choose a starting image', keep_on_top=True)
+ if not single_image:
+ if sg.popup_yes_no('No folder entered','Go you want to exit the program entirely?', keep_on_top=True) == 'Yes':
+ exit()
+ if image_folder is not None and single_image is None:
images = os.listdir(image_folder)
images = [i for i in images if i.lower().endswith(('.png', '.jpg', '.gif'))]
+ image_name = os.path.join(image_folder, random.choice(images))
else: # means single image is not none
images = None
+ image_name = single_image
+ window = make_window(loc)
+
+ window_size = window.size
+ image_data = convert_to_bytes(image_name, (width, height))
+
while True: # Event Loop
- # First update the status information
- # for debugging show the last update date time
- if single_image is None:
- image_name =random.choice(images)
- image_data = convert_to_bytes(os.path.join(image_folder, image_name), (width, height))
- window['-FOLDER-'].update(image_folder)
- else:
- image_name = single_image
- image_data = convert_to_bytes(single_image, (width, height))
- window['-FILENAME-'].update(image_name)
- window['-IMAGE-'].update(data=image_data)
- window['-REFRESHED-'].update(datetime.datetime.now().strftime("%m/%d/%Y %I:%M:%S %p"))
# -------------- Start of normal event loop --------------
timeout = time_per_image * 1000 + (random.randint(int(-time_per_image * 500), int(time_per_image * 500)) if vary_randomly else 0) if single_image is None else None
event, values = window.read(timeout=timeout)
@@ -120,6 +181,28 @@ def main():
elif event in (sg.WIN_CLOSE_ATTEMPTED_EVENT, 'Exit'):
sg.user_settings_set_entry('-location-', window.current_location()) # The line of code to save the position before exiting
break
+ # First update the status information
+ # for debugging show the last update date time
+ if event == sg.TIMEOUT_EVENT:
+ if single_image is None:
+ image_name =random.choice(images)
+ image_data = convert_to_bytes(os.path.join(image_folder, image_name))
+ window['-FOLDER-'].update(image_folder)
+ else:
+ image_name = single_image
+ image_data = convert_to_bytes(single_image, (width, height))
+ window['-FILENAME-'].update(image_name)
+ window['-IMAGE-'].update(data=image_data)
+ window['-REFRESHED-'].update(datetime.datetime.now().strftime("%m/%d/%Y %I:%M:%S %p"))
+ if event == sg.WINDOW_CONFIG_EVENT:
+ new_size = window.size
+ if new_size != window_size:
+ print(f'resizing {new_size}')
+ (width, height) = new_size
+ image_data = convert_to_bytes(image_data, (width, height))
+ window['-IMAGE-'].update(data=image_data)
+ window.size = get_image_size(image_data)
+ window_size = window.size
if event == 'Edit Me':
sg.execute_editor(__file__)
elif event == 'Choose Image Folder':
@@ -175,12 +258,15 @@ def main():
window.close()
window = make_window(loc)
elif event == 'Choose Single Image':
- single_image = sg.popup_get_file('Choose single image to show', history=True)
+ image_name = single_image = sg.popup_get_file('Choose single image to show', history=True)
sg.user_settings_set_entry('-single image-', single_image)
-
-
-
+ (width, height) = get_image_size(single_image)
+ sg.user_settings_set_entry('-image size-', (width, height))
+ image_data = convert_to_bytes(image_name, (width, height))
+ window['-IMAGE-'].update(data=image_data)
+ window.size = window_size = (width, height)
window.close()
if __name__ == '__main__':
+ # reset_settings() # if get corrupted problems, uncomment this
main()
\ No newline at end of file
From f292d757def83efd0432f7a250b547c8c9e898e1 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 13 Aug 2023 11:47:16 -0400
Subject: [PATCH 108/145] Fixed bug in Button.update. Was setting the
activeforeground and activebackground which broke the mouseover or mouse
press colors
---
PySimpleGUI.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 8d0107b1..8b5a6467 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.190 Unreleased"
+version = __version__ = "4.61.0.191 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -452,6 +452,8 @@ _change_log = """
4.61.0.190
Addition of black2 theme
Fix typo of text in _widget_was_created
+ 4.61.0.191
+ Fixed bug in Button.update. Was setting the activeforeground and activebackground which broke the mouseover or mouse press colors
"""
@@ -5574,9 +5576,11 @@ class Button(Element):
button_style.configure(style_name, background=bc[1])
else:
if bc[0] not in (None, COLOR_SYSTEM_DEFAULT):
- self.TKButton.config(foreground=bc[0], activeforeground=bc[0])
+ # self.TKButton.config(foreground=bc[0], activeforeground=bc[0]) # Removed 13-Aug-2023. Was causing mouseover to not work
+ self.TKButton.config(foreground=bc[0])
if bc[1] not in (None, COLOR_SYSTEM_DEFAULT):
- self.TKButton.config(background=bc[1], activebackground=bc[1])
+ # self.TKButton.config(background=bc[1], activebackground=bc[1]) # Removed 13-Aug-2023. Was causing mouseover to not work
+ self.TKButton.config(background=bc[1])
self.ButtonColor = bc
if disabled is True:
self.TKButton['state'] = 'disabled'
From c51d6709563a9474663a7e6d98397b5cc9516433 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 14 Aug 2023 12:22:12 -0400
Subject: [PATCH 109/145] Fixed bug in Button.update. Corrected when
activeforeground and activebackground are set. Removing them in version
above was a mistake
---
PySimpleGUI.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 8b5a6467..d7b845b9 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.191 Unreleased"
+version = __version__ = "4.61.0.192 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -454,6 +454,8 @@ _change_log = """
Fix typo of text in _widget_was_created
4.61.0.191
Fixed bug in Button.update. Was setting the activeforeground and activebackground which broke the mouseover or mouse press colors
+ 4.61.0.192
+ Fixed bug in Button.update. Corrected when activeforeground and activebackground are set. Removing them in version above was a mistake
"""
@@ -5576,11 +5578,9 @@ class Button(Element):
button_style.configure(style_name, background=bc[1])
else:
if bc[0] not in (None, COLOR_SYSTEM_DEFAULT):
- # self.TKButton.config(foreground=bc[0], activeforeground=bc[0]) # Removed 13-Aug-2023. Was causing mouseover to not work
- self.TKButton.config(foreground=bc[0])
+ self.TKButton.config(foreground=bc[0], activebackground=bc[0])
if bc[1] not in (None, COLOR_SYSTEM_DEFAULT):
- # self.TKButton.config(background=bc[1], activebackground=bc[1]) # Removed 13-Aug-2023. Was causing mouseover to not work
- self.TKButton.config(background=bc[1])
+ self.TKButton.config(background=bc[1], activeforeground=bc[1])
self.ButtonColor = bc
if disabled is True:
self.TKButton['state'] = 'disabled'
From 1d3126f8848e88a53e13380225efc1507eb27ab2 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Wed, 16 Aug 2023 09:34:58 -0400
Subject: [PATCH 110/145] Fixed spelling errors... resuse should have been
reuse
---
PySimpleGUI.py | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index d7b845b9..82960a7e 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.192 Unreleased"
+version = __version__ = "4.61.0.193 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -456,6 +456,8 @@ _change_log = """
Fixed bug in Button.update. Was setting the activeforeground and activebackground which broke the mouseover or mouse press colors
4.61.0.192
Fixed bug in Button.update. Corrected when activeforeground and activebackground are set. Removing them in version above was a mistake
+ 4.61.0.193
+ Fixed spelling errors... resuse should have been reuse
"""
@@ -7358,7 +7360,7 @@ class Frame(Element):
continue
if element.ParentContainer is not None:
warnings.warn(
- '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
+ '*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
UserWarning)
_error_popup_with_traceback('Error creating Frame layout',
'The layout specified has already been used',
@@ -7694,7 +7696,7 @@ class Tab(Element):
continue
if element.ParentContainer is not None:
warnings.warn(
- '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
+ '*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
UserWarning)
popup_error_with_traceback('Error creating Tab layout',
'The layout specified has already been used',
@@ -7953,7 +7955,7 @@ class TabGroup(Element):
continue
if element.ParentContainer is not None:
warnings.warn(
- '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
+ '*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
UserWarning)
PopupError('Error creating Tab layout',
'The layout specified has already been used',
@@ -8614,7 +8616,7 @@ class Column(Element):
continue
if element.ParentContainer is not None:
warnings.warn(
- '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
+ '*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
UserWarning)
PopupError('Error creating Column layout',
'The layout specified has already been used',
@@ -10655,10 +10657,10 @@ class Window:
continue
if element.ParentContainer is not None:
warnings.warn(
- '*** YOU ARE ATTEMPTING TO RESUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
+ '*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
UserWarning)
_error_popup_with_traceback('Error detected in layout - Contains an element that has already been used.',
- 'You have attempted to resuse an element in your layout.',
+ 'You have attempted to reuse an element in your layout.',
"The layout specified has an element that's already been used.",
'You MUST start with a "clean", unused layout every time you create a window',
'The offensive Element = ',
From 2ece7d4ad565bd3beb7487f644da526fccd0c6ff Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sat, 19 Aug 2023 11:53:08 -0400
Subject: [PATCH 111/145] Added Listbox.select_index and
Listbox.set_index_color
---
PySimpleGUI.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 77 insertions(+), 1 deletion(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 82960a7e..6b00923d 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.193 Unreleased"
+version = __version__ = "4.61.0.194 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -458,6 +458,8 @@ _change_log = """
Fixed bug in Button.update. Corrected when activeforeground and activebackground are set. Removing them in version above was a mistake
4.61.0.193
Fixed spelling errors... resuse should have been reuse
+ 4.61.0.194
+ Added Listbox.select_index and Listbox.set_index_color
"""
@@ -3327,6 +3329,80 @@ class Listbox(Element):
value = []
return value
+
+
+ def select_index(self, index, highlight_text_color=None, highlight_background_color=None):
+ """
+ Selects an index while providing capability to setting the selected color for the index to specific text/background color
+
+ :param index: specifies which item to change. index starts at 0 and goes to length of values list minus one
+ :type index: (int)
+ :param highlight_text_color: color of the text when this item is selected.
+ :type highlight_text_color: (str)
+ :param highlight_background_color: color of the background when this item is selected
+ :type highlight_background_color: (str)
+ """
+
+ if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
+ return
+
+ if self._this_elements_window_closed():
+ _error_popup_with_traceback('Error in Listbox.select_item - The window was closed')
+ return
+
+ if index >= len(self.Values):
+ _error_popup_with_traceback('Index {} is out of range for Listbox.select_index. Max allowed index is {}.'.format(index, len(self.Values)-1))
+ return
+
+ self.TKListbox.selection_set(index, index)
+
+ if highlight_text_color is not None:
+ text_color = highlight_text_color
+ else:
+ text_color = None
+
+ if highlight_background_color is not None:
+ background_color = highlight_background_color
+ else:
+ background_color = None
+
+ if text_color is not None:
+ self.widget.itemconfig(index, selectforeground=text_color)
+ if background_color is not None:
+ self.widget.itemconfig(index, selectbackground=background_color)
+
+
+ def set_index_color(self, index, text_color=None, background_color=None):
+ """
+ Sets the color of a specific item without selecting it
+
+ :param index: specifies which item to change. index starts at 0 and goes to length of values list minus one
+ :type index: (int)
+ :param text_color: color of the text for this item
+ :type text_color: (str)
+ :param background_color: color of the background for this item
+ :type background_color: (str)
+ """
+
+ if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
+ return
+
+ if self._this_elements_window_closed():
+ _error_popup_with_traceback('Error in Listbox.set_item_color - The window was closed')
+ return
+
+ if index >= len(self.Values):
+ _error_popup_with_traceback('Index {} is out of range for Listbox.set_index_color. Max allowed index is {}.'.format(index, len(self.Values)-1))
+ return
+
+
+ if text_color is not None:
+ self.widget.itemconfig(index, fg=text_color)
+ if background_color is not None:
+ self.widget.itemconfig(index, bg=background_color)
+
+
+
GetIndexes = get_indexes
GetListValues = get_list_values
SetValue = set_value
From 393050c1ae085fa66b773410a685d4ffac8b4758 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 20 Aug 2023 17:20:05 -0400
Subject: [PATCH 112/145] New Udemy Coupon. Added Listbox.set_index_color and
Listbox.select_index to the SDK Call Reference
---
PySimpleGUI.py | 8 ++--
docs/call reference.md | 40 ++++++++++++++++++-
docs/cookbook.md | 4 +-
docs/index.md | 4 +-
docs/readme.md | 4 +-
.../markdown input files/1_HEADER_top_part.md | 4 +-
.../markdown input files/5_call_reference.md | 10 ++++-
readme_creator/output/call reference.md | 40 ++++++++++++++++++-
readme_creator/output/index.md | 4 +-
9 files changed, 99 insertions(+), 19 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 6b00923d..a91f9845 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.194 Unreleased"
+version = __version__ = "4.61.0.195 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -460,6 +460,8 @@ _change_log = """
Fixed spelling errors... resuse should have been reuse
4.61.0.194
Added Listbox.select_index and Listbox.set_index_color
+ 4.61.0.195
+ New Udemy Coupon
"""
@@ -26779,7 +26781,7 @@ def main():
elif event == 'Get Text':
popup_scrolled('Returned:', popup_get_text('Enter some text', keep_on_top=True))
elif event.startswith('-UDEMY-'):
- webbrowser.open_new_tab(r'https://www.udemy.com/course/pysimplegui/?couponCode=9AF99B123C49D51EB547')
+ webbrowser.open_new_tab(r'https://www.udemy.com/course/pysimplegui/?couponCode=62A4C02AB0A3DAB34388')
elif event.startswith('-SPONSOR-'):
if webbrowser_available:
webbrowser.open_new_tab(r'https://www.paypal.me/pythongui')
@@ -26787,7 +26789,7 @@ def main():
if webbrowser_available:
webbrowser.open_new_tab(r'https://www.buymeacoffee.com/PySimpleGUI')
elif event in ('-EMOJI-HEARTS-', '-HEART-', '-PYTHON HEARTS-'):
- popup_scrolled("Oh look! It's a Udemy discount coupon!", '9AF99B123C49D51EB547',
+ popup_scrolled("Oh look! It's a Udemy discount coupon!", '62A4C02AB0A3DAB34388',
'A personal message from Mike -- thank you so very much for supporting PySimpleGUI!', title='Udemy Coupon', image=EMOJI_BASE64_MIKE, keep_on_top=True)
elif event == 'Themes':
search_string = popup_get_text('Enter a search term or leave blank for all themes', 'Show Available Themes', keep_on_top=True)
diff --git a/docs/call reference.md b/docs/call reference.md
index b004ccac..37b27a5b 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 9AF99B123C49D51EB547.
+ 62A4C02AB0A3DAB34388.
-
+
click here to visit course page
@@ -5583,6 +5583,24 @@ Metadata is an Element property that you can use at any time to hold any value
|---|---|---|
|(Any)| **return** | the current metadata value |
+### select_index
+
+Selects an index while providing capability to setting the selected color for the index to specific text/background color
+
+```
+select_index(index,
+ highlight_text_color = None,
+ highlight_background_color = None)
+```
+
+Parameter Descriptions:
+
+|Type|Name|Meaning|
+|--|--|--|
+| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
+| str | highlight_text_color | color of the text when this item is selected. |
+| str | highlight_background_color | color of the background when this item is selected |
+
### set_cursor
Sets the cursor for the current Element.
@@ -5616,6 +5634,24 @@ Parameter Descriptions:
|--|--|--|
| bool | force | if True will call focus_force otherwise calls focus_set |
+### set_index_color
+
+Sets the color of a specific item without selecting it
+
+```
+set_index_color(index,
+ text_color = None,
+ background_color = None)
+```
+
+Parameter Descriptions:
+
+|Type|Name|Meaning|
+|--|--|--|
+| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
+| str | text_color | color of the text for this item |
+| str | background_color | color of the background for this item |
+
### set_size
Changes the size of an element to a specific size.
diff --git a/docs/cookbook.md b/docs/cookbook.md
index 98473f4c..4281f426 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- F988F082A3D18483B1C5
+ 62A4C02AB0A3DAB34388
diff --git a/readme_creator/markdown input files/1_HEADER_top_part.md b/readme_creator/markdown input files/1_HEADER_top_part.md
index 320a4997..926f75f5 100644
--- a/readme_creator/markdown input files/1_HEADER_top_part.md
+++ b/readme_creator/markdown input files/1_HEADER_top_part.md
@@ -52,9 +52,9 @@ HOW DO I INSERT IMAGES ???
apply coupon for discount:
- 9AF99B123C49D51EB547
+ 62A4C02AB0A3DAB34388
-
+
click here to visit course page
diff --git a/readme_creator/markdown input files/5_call_reference.md b/readme_creator/markdown input files/5_call_reference.md
index 1f690a41..07fdb13a 100644
--- a/readme_creator/markdown input files/5_call_reference.md
+++ b/readme_creator/markdown input files/5_call_reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 9AF99B123C49D51EB547.
+ 62A4C02AB0A3DAB34388.
-
+
click here to visit course page
@@ -1207,12 +1207,18 @@ The following methods are here for backwards compatibility reference. You will
### metadata
+### select_index
+
+
### set_cursor
### set_focus
+### set_index_color
+
+
### set_size
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index b004ccac..37b27a5b 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 9AF99B123C49D51EB547.
+ 62A4C02AB0A3DAB34388.
-
+
click here to visit course page
@@ -5583,6 +5583,24 @@ Metadata is an Element property that you can use at any time to hold any value
|---|---|---|
|(Any)| **return** | the current metadata value |
+### select_index
+
+Selects an index while providing capability to setting the selected color for the index to specific text/background color
+
+```
+select_index(index,
+ highlight_text_color = None,
+ highlight_background_color = None)
+```
+
+Parameter Descriptions:
+
+|Type|Name|Meaning|
+|--|--|--|
+| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
+| str | highlight_text_color | color of the text when this item is selected. |
+| str | highlight_background_color | color of the background when this item is selected |
+
### set_cursor
Sets the cursor for the current Element.
@@ -5616,6 +5634,24 @@ Parameter Descriptions:
|--|--|--|
| bool | force | if True will call focus_force otherwise calls focus_set |
+### set_index_color
+
+Sets the color of a specific item without selecting it
+
+```
+set_index_color(index,
+ text_color = None,
+ background_color = None)
+```
+
+Parameter Descriptions:
+
+|Type|Name|Meaning|
+|--|--|--|
+| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
+| str | text_color | color of the text for this item |
+| str | background_color | color of the background for this item |
+
### set_size
Changes the size of an element to a specific size.
diff --git a/readme_creator/output/index.md b/readme_creator/output/index.md
index 11810190..a7ddf342 100644
--- a/readme_creator/output/index.md
+++ b/readme_creator/output/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 9AF99B123C49D51EB547
+ 62A4C02AB0A3DAB34388
-
+
click here to visit course page
From 77ea65b8de11685f0c68ec662250c461af8a1c37 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 21 Aug 2023 17:31:08 -0400
Subject: [PATCH 113/145] Added highlight colors to the set_index_color method.
Parms highlight_text_color & highlight_background_color control changing the
highlight colors
---
PySimpleGUI.py | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index a91f9845..ed42523a 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.195 Unreleased"
+version = __version__ = "4.61.0.196 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -462,6 +462,9 @@ _change_log = """
Added Listbox.select_index and Listbox.set_index_color
4.61.0.195
New Udemy Coupon
+ 4.61.0.196
+ Added highlight colors to the set_index_color method. Parms highlight_text_color & highlight_background_color control changing the highlight colors
+
"""
@@ -3332,7 +3335,6 @@ class Listbox(Element):
return value
-
def select_index(self, index, highlight_text_color=None, highlight_background_color=None):
"""
Selects an index while providing capability to setting the selected color for the index to specific text/background color
@@ -3359,31 +3361,25 @@ class Listbox(Element):
self.TKListbox.selection_set(index, index)
if highlight_text_color is not None:
- text_color = highlight_text_color
- else:
- text_color = None
-
+ self.widget.itemconfig(index, selectforeground=highlight_text_color)
if highlight_background_color is not None:
- background_color = highlight_background_color
- else:
- background_color = None
-
- if text_color is not None:
- self.widget.itemconfig(index, selectforeground=text_color)
- if background_color is not None:
- self.widget.itemconfig(index, selectbackground=background_color)
+ self.widget.itemconfig(index, selectbackground=highlight_background_color)
- def set_index_color(self, index, text_color=None, background_color=None):
+ def set_index_color(self, index, text_color=None, background_color=None, highlight_text_color=None, highlight_background_color=None):
"""
Sets the color of a specific item without selecting it
- :param index: specifies which item to change. index starts at 0 and goes to length of values list minus one
- :type index: (int)
- :param text_color: color of the text for this item
- :type text_color: (str)
- :param background_color: color of the background for this item
- :type background_color: (str)
+ :param index: specifies which item to change. index starts at 0 and goes to length of values list minus one
+ :type index: (int)
+ :param text_color: color of the text for this item
+ :type text_color: (str)
+ :param background_color: color of the background for this item
+ :type background_color: (str)
+ :param highlight_text_color: color of the text when this item is selected.
+ :type highlight_text_color: (str)
+ :param highlight_background_color: color of the background when this item is selected
+ :type highlight_background_color: (str)
"""
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
@@ -3397,11 +3393,15 @@ class Listbox(Element):
_error_popup_with_traceback('Index {} is out of range for Listbox.set_index_color. Max allowed index is {}.'.format(index, len(self.Values)-1))
return
-
if text_color is not None:
self.widget.itemconfig(index, fg=text_color)
if background_color is not None:
self.widget.itemconfig(index, bg=background_color)
+ if highlight_text_color is not None:
+ self.widget.itemconfig(index, selectforeground=highlight_text_color)
+ if highlight_background_color is not None:
+ self.widget.itemconfig(index, selectbackground=highlight_background_color)
+
From 0b6eb6d5b3c5c2c9cf98c70679b79aef703507d7 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 21 Aug 2023 17:33:27 -0400
Subject: [PATCH 114/145] Rebuilt the call reference based on new
set_index_color parms
---
docs/call reference.md | 12 ++++++++----
readme_creator/output/call reference.md | 12 ++++++++----
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/docs/call reference.md b/docs/call reference.md
index 37b27a5b..cc0bd9ef 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -5641,16 +5641,20 @@ Sets the color of a specific item without selecting it
```
set_index_color(index,
text_color = None,
- background_color = None)
+ background_color = None,
+ highlight_text_color = None,
+ highlight_background_color = None)
```
Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
-| str | text_color | color of the text for this item |
-| str | background_color | color of the background for this item |
+| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
+| str | text_color | color of the text for this item |
+| str | background_color | color of the background for this item |
+| str | highlight_text_color | color of the text when this item is selected. |
+| str | highlight_background_color | color of the background when this item is selected |
### set_size
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index 37b27a5b..cc0bd9ef 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -5641,16 +5641,20 @@ Sets the color of a specific item without selecting it
```
set_index_color(index,
text_color = None,
- background_color = None)
+ background_color = None,
+ highlight_text_color = None,
+ highlight_background_color = None)
```
Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
-| str | text_color | color of the text for this item |
-| str | background_color | color of the background for this item |
+| int | index | specifies which item to change. index starts at 0 and goes to length of values list minus one |
+| str | text_color | color of the text for this item |
+| str | background_color | color of the background for this item |
+| str | highlight_text_color | color of the text when this item is selected. |
+| str | highlight_background_color | color of the background when this item is selected |
### set_size
From cf3345303d72360f379597ce9ca4c58123fdc88c Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sat, 26 Aug 2023 17:30:18 +0000
Subject: [PATCH 115/145] Automated Update!
---
docs/Screens.md | 7 +++++++
docs/Screens2.md | 9 +++++++++
2 files changed, 16 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index d2c5e36d..6353ed9c 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,10 @@
+[definite-d](https://github.com/definite-d) 2023-08-26T16:34:23Z
+
+
+
+
+-----------
+
[luisegarduno](https://github.com/luisegarduno) 2023-06-25T05:18:40Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index f2b1b736..2f5c4952 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,12 @@
+[definite-d](https://github.com/definite-d) 2023-08-26T16:34:23Z
+[Themera](https://github.com/definite-d/Themera) v2.1.0 has been released (available [here](https://github.com/definite-d/Themera/releases/tag/v2.1.0)). I'd like to share screenshots and point out that with Windows 11, the color of the "built-in" titlebar can be customized. I accomplished it within Themera with a bit of a non-standard solution, but it's proof of concept.
+
+
+
+
+
+-----------
+
[luisegarduno](https://github.com/luisegarduno) 2023-06-25T05:18:40Z
**Chess (updated!)**
From 0459adac698f3c0c682270a936474991622b1c75 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 28 Aug 2023 07:09:38 -0400
Subject: [PATCH 116/145] Made Table Element Header mouse-over and clicked be
the inverse of the normal header colors. Makes for a much nicer experience
---
PySimpleGUI.py | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index ed42523a..862cef08 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.196 Unreleased"
+version = __version__ = "4.61.0.197 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -464,6 +464,8 @@ _change_log = """
New Udemy Coupon
4.61.0.196
Added highlight colors to the set_index_color method. Parms highlight_text_color & highlight_background_color control changing the highlight colors
+ 4.61.0.197
+ Made Table Element Header mouse-over and clicked be the inverse of the normal header colors. Makes for a much nicer experience
"""
@@ -17854,6 +17856,13 @@ def PackFormIntoFrame(form, containing_frame, toplevel_form):
table_style.configure(style_name, font=font)
if element.BorderWidth is not None:
table_style.configure(style_name, borderwidth=element.BorderWidth)
+
+ if element.HeaderBackgroundColor not in (None, COLOR_SYSTEM_DEFAULT) and element.HeaderTextColor not in (None, COLOR_SYSTEM_DEFAULT):
+ table_style.map(style_name + ".Heading", background=[('pressed', '!focus', element.HeaderBackgroundColor),
+ ('active', element.HeaderTextColor),])
+ table_style.map(style_name + ".Heading", foreground=[('pressed', '!focus', element.HeaderTextColor),
+ ('active', element.HeaderBackgroundColor),])
+
treeview.configure(style=style_name)
# scrollable_frame.pack(side=tk.LEFT, padx=elementpad[0], pady=elementpad[1], expand=True, fill='both')
if element.enable_click_events is True:
From 3907e7636e199a3097c3d28671a536deea5fc676 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 31 Aug 2023 12:18:43 -0400
Subject: [PATCH 117/145] Added Added no_buffering option to popup_animated
---
PySimpleGUI.py | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 862cef08..dbcb1c82 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.197 Unreleased"
+version = __version__ = "4.61.0.198 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -466,6 +466,8 @@ _change_log = """
Added highlight colors to the set_index_color method. Parms highlight_text_color & highlight_background_color control changing the highlight colors
4.61.0.197
Made Table Element Header mouse-over and clicked be the inverse of the normal header colors. Makes for a much nicer experience
+ 4.61.0.198
+ Added no_buffering option to popup_animated
"""
@@ -22435,7 +22437,7 @@ def popup_get_date(start_mon=None, start_day=None, start_year=None, begin_at_sun
# --------------------------- PopupAnimated ---------------------------
def popup_animated(image_source, message=None, background_color=None, text_color=None, font=None, no_titlebar=True, grab_anywhere=True, keep_on_top=True,
- location=(None, None), relative_location=(None, None), alpha_channel=None, time_between_frames=0, transparent_color=None, title='', icon=None):
+ location=(None, None), relative_location=(None, None), alpha_channel=None, time_between_frames=0, transparent_color=None, title='', icon=None, no_buffering=False):
"""
Show animation one frame at a time. This function has its own internal clocking meaning you can call it at any frequency
and the rate the frames of video is shown remains constant. Maybe your frames update every 30 ms but your
@@ -22472,6 +22474,8 @@ def popup_animated(image_source, message=None, background_color=None, text_color
:type title: (str)
:param icon: Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO
:type icon: str | bytes
+ :param no_buffering: If True then no buffering will be used for the GIF. May work better if you have a large animation
+ :type no_buffering: (str)
:return: True if the window updated OK. False if the window was closed
:rtype: bool
"""
@@ -22497,7 +22501,10 @@ def popup_animated(image_source, message=None, background_color=None, text_color
Window._animated_popup_dict[image_source] = window
else:
window = Window._animated_popup_dict[image_source]
- window['-IMAGE-'].update_animation(image_source, time_between_frames=time_between_frames)
+ if no_buffering:
+ window['-IMAGE-'].update_animation_no_buffering(image_source, time_between_frames=time_between_frames)
+ else:
+ window['-IMAGE-'].update_animation(image_source, time_between_frames=time_between_frames)
event, values = window.read(1)
if event == WIN_CLOSED:
return False
From ed128a36f565c8c1c2ca7113fb86d73755ec454a Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 31 Aug 2023 12:24:21 -0400
Subject: [PATCH 118/145] fixed bool instead of string in doctring
---
PySimpleGUI.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index dbcb1c82..6550b58f 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -22475,7 +22475,7 @@ def popup_animated(image_source, message=None, background_color=None, text_color
:param icon: Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO
:type icon: str | bytes
:param no_buffering: If True then no buffering will be used for the GIF. May work better if you have a large animation
- :type no_buffering: (str)
+ :type no_buffering: (bool)
:return: True if the window updated OK. False if the window was closed
:rtype: bool
"""
From 48c7b673c192e4f4a2d9236c7ecb268cc4f89746 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Wed, 6 Sep 2023 17:30:28 +0000
Subject: [PATCH 119/145] Automated Update!
---
docs/Screens.md | 6 ++++++
docs/Screens2.md | 12 ++++++++++++
2 files changed, 18 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 6353ed9c..b144cc08 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,9 @@
+[onyx-and-iris](https://github.com/onyx-and-iris) 2023-09-06T00:00:13Z
+
+
+
+-----------
+
[definite-d](https://github.com/definite-d) 2023-08-26T16:34:23Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index 2f5c4952..e95633b4 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,15 @@
+[onyx-and-iris](https://github.com/onyx-and-iris) 2023-09-06T00:00:13Z
+A small remote utility for Voicemeeter, designed to work with the NVDA screen reader.
+
+
+https://github.com/onyx-and-iris/nvda-voicemeeter
+
+Thanks for creating PYSimpleGUI, first time using but very impressed!
+
+
+
+-----------
+
[definite-d](https://github.com/definite-d) 2023-08-26T16:34:23Z
[Themera](https://github.com/definite-d/Themera) v2.1.0 has been released (available [here](https://github.com/definite-d/Themera/releases/tag/v2.1.0)). I'd like to share screenshots and point out that with Windows 11, the color of the "built-in" titlebar can be customized. I accomplished it within Themera with a bit of a non-standard solution, but it's proof of concept.
From ce32fe3814e3850f8781ca8494404a635de89b20 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sat, 9 Sep 2023 17:30:27 +0000
Subject: [PATCH 120/145] Automated Update!
---
docs/Screens.md | 12 ++++++------
docs/Screens2.md | 14 +++++++-------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/docs/Screens.md b/docs/Screens.md
index b144cc08..b8b9d02c 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -695,7 +695,7 @@
-----------
-[vohe](https://github.com/vohe) 2022-01-23T13:53:09Z
+[ghost](https://github.com/ghost) 2022-01-23T13:53:09Z

@@ -1191,13 +1191,13 @@
-----------
-[vohe](https://github.com/vohe) 2020-08-08T11:11:29Z
+[ghost](https://github.com/ghost) 2020-08-08T11:11:29Z

-----------
-[vohe](https://github.com/vohe) 2020-08-05T13:31:05Z
+[ghost](https://github.com/ghost) 2020-08-05T13:31:05Z


@@ -1210,13 +1210,13 @@
-----------
-[vohe](https://github.com/vohe) 2020-08-02T17:28:23Z
+[ghost](https://github.com/ghost) 2020-08-02T17:28:23Z

-----------
-[vohe](https://github.com/vohe) 2020-07-05T16:45:42Z
+[ghost](https://github.com/ghost) 2020-07-05T16:45:42Z


@@ -1224,7 +1224,7 @@
-----------
-[vohe](https://github.com/vohe) 2020-07-04T15:43:31Z
+[ghost](https://github.com/ghost) 2020-07-04T15:43:31Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index e95633b4..a5cc70d1 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -2384,7 +2384,7 @@ Obviously the GUI was the easy part!
-----------
-[vohe](https://github.com/vohe) 2022-01-23T13:53:09Z
+[ghost](https://github.com/ghost) 2022-01-23T13:53:09Z
The Januar Version is ready to go.
I manged it , finally, to work without lastfm. For everyone who can use this:
Audiorecorder,, records (e.g.) spotify web player - with free account.
@@ -4507,7 +4507,7 @@ GitHub.com/MOABdali/megaCheckers if anyone wants to try it. Please keep in mind
-----------
-[vohe](https://github.com/vohe) 2020-08-08T11:11:29Z
+[ghost](https://github.com/ghost) 2020-08-08T11:11:29Z
Ready to go,
I found that putting move than 3000 elements in a sg.treedata() structure works, but as i close that there'll be a huge garbage collection of tkinter under the hood.
So my directory popup window isn't usable for a 'normal' user directory, especially if the show hidden files option is active.
@@ -4521,7 +4521,7 @@ Have Fun, stay healthy.
-----------
-[vohe](https://github.com/vohe) 2020-08-05T13:31:05Z
+[ghost](https://github.com/ghost) 2020-08-05T13:31:05Z
In addition to get a Folder Browser running , which does not
- show hidden files,
- throws errors on Permissions
@@ -4544,7 +4544,7 @@ The bars for each color have the color of the original image and the other-color
-----------
-[vohe](https://github.com/vohe) 2020-08-02T17:28:23Z
+[ghost](https://github.com/ghost) 2020-08-02T17:28:23Z
Hi folks,
here is another one i playing with....
The TreeElement is not as flexible as i want it. But many things are possible.
@@ -4554,7 +4554,7 @@ I got the functionallity i want, but the interface isn't that what i like to get
-----------
-[vohe](https://github.com/vohe) 2020-07-05T16:45:42Z
+[ghost](https://github.com/ghost) 2020-07-05T16:45:42Z
Thank you,
first of all i got it as i like (but not so elegant) First of all it works.

@@ -4579,7 +4579,7 @@ https://github.com/PySimpleGUI/PySimpleGUI/issues/new?assignees=&labels=&templat
-----------
-[vohe](https://github.com/vohe) 2020-07-04T21:28:44Z
+[ghost](https://github.com/ghost) 2020-07-04T21:28:44Z
> Very nice @vohe ! Thanks for posting it!
> I like they use of tabs. Great , simple layout. I might have to use that idea for settings sometime. It's never dawned on me before to put them into a tab like that.
@@ -4596,7 +4596,7 @@ I like they use of tabs. Great , simple layout. I might have to use that idea
-----------
-[vohe](https://github.com/vohe) 2020-07-04T15:43:31Z
+[ghost](https://github.com/ghost) 2020-07-04T15:43:31Z

A little Programm, that records files form a webside (actually open.spotify) store them as mp3, tag them, sort them into directorys , notify the user when a new song is beginning.
From 4504ea77c3be661e1cad3dcb73febb4b1f8c3eda Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 21 Sep 2023 16:09:33 -0400
Subject: [PATCH 121/145] New Udemy Coupon
---
docs/call reference.md | 12 ++++++++----
docs/cookbook.md | 4 ++--
docs/index.md | 8 +++++---
docs/readme.md | 4 ++--
readme.md | 4 ++--
.../markdown input files/1_HEADER_top_part.md | 4 ++--
.../markdown input files/5_call_reference.md | 4 ++--
readme_creator/output/call reference.md | 12 ++++++++----
readme_creator/output/index.md | 8 +++++---
9 files changed, 36 insertions(+), 24 deletions(-)
diff --git a/docs/call reference.md b/docs/call reference.md
index cc0bd9ef..08ca758c 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 62A4C02AB0A3DAB34388.
+ 2F6C6BE01B8940D3E457.
-
+
click here to visit course page
@@ -16903,7 +16903,8 @@ popup_animated(image_source,
time_between_frames = 0,
transparent_color = None,
title = "",
- icon = None)
+ icon = None,
+ no_buffering = False)
```
Parameter Descriptions:
@@ -16925,6 +16926,7 @@ Parameter Descriptions:
| str | transparent_color | This color will be completely see-through in your window. Can even click through |
| str | title | Title that will be shown on the window |
| str or bytes | icon | Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO |
+| bool | no_buffering | If True then no buffering will be used for the GIF. May work better if you have a large animation |
| bool | **RETURN** | True if the window updated OK. False if the window was closed
Popup that closes itself after some time period
@@ -17987,7 +17989,8 @@ PopupAnimated(image_source,
time_between_frames = 0,
transparent_color = None,
title = "",
- icon = None)
+ icon = None,
+ no_buffering = False)
```
Parameter Descriptions:
@@ -18009,6 +18012,7 @@ Parameter Descriptions:
| str | transparent_color | This color will be completely see-through in your window. Can even click through |
| str | title | Title that will be shown on the window |
| str or bytes | icon | Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO |
+| bool | no_buffering | If True then no buffering will be used for the GIF. May work better if you have a large animation |
| bool | **RETURN** | True if the window updated OK. False if the window was closed
Display a Popup without a titlebar. Enables grab anywhere so you can move it
diff --git a/docs/cookbook.md b/docs/cookbook.md
index 4281f426..3637ddd3 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 62A4C02AB0A3DAB34388
+ 2F6C6BE01B8940D3E457
-
+
click here to visit course page
diff --git a/docs/index.md b/docs/index.md
index a7ddf342..6c855457 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 62A4C02AB0A3DAB34388
+ 2F6C6BE01B8940D3E457
-
+
click here to visit course page
@@ -2028,7 +2028,8 @@ popup_animated(image_source,
time_between_frames = 0,
transparent_color = None,
title = "",
- icon = None)
+ icon = None,
+ no_buffering = False)
```
Parameter Descriptions:
@@ -2050,6 +2051,7 @@ Parameter Descriptions:
| str | transparent_color | This color will be completely see-through in your window. Can even click through |
| str | title | Title that will be shown on the window |
| str or bytes | icon | Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO |
+| bool | no_buffering | If True then no buffering will be used for the GIF. May work better if you have a large animation |
| bool | **RETURN** | True if the window updated OK. False if the window was closed
***To close animated popups***, call PopupAnimated with `image_source=None`. This will close all of the currently open PopupAnimated windows.
diff --git a/docs/readme.md b/docs/readme.md
index 7233b9b7..e73b6075 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -9,8 +9,8 @@
diff --git a/readme_creator/markdown input files/1_HEADER_top_part.md b/readme_creator/markdown input files/1_HEADER_top_part.md
index 926f75f5..ca75d9e5 100644
--- a/readme_creator/markdown input files/1_HEADER_top_part.md
+++ b/readme_creator/markdown input files/1_HEADER_top_part.md
@@ -52,9 +52,9 @@ HOW DO I INSERT IMAGES ???
apply coupon for discount:
- 62A4C02AB0A3DAB34388
+ 2F6C6BE01B8940D3E457
-
+
click here to visit course page
diff --git a/readme_creator/markdown input files/5_call_reference.md b/readme_creator/markdown input files/5_call_reference.md
index 07fdb13a..7b223866 100644
--- a/readme_creator/markdown input files/5_call_reference.md
+++ b/readme_creator/markdown input files/5_call_reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 62A4C02AB0A3DAB34388.
+ 2F6C6BE01B8940D3E457.
-
+
click here to visit course page
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index cc0bd9ef..08ca758c 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 62A4C02AB0A3DAB34388.
+ 2F6C6BE01B8940D3E457.
-
+
click here to visit course page
@@ -16903,7 +16903,8 @@ popup_animated(image_source,
time_between_frames = 0,
transparent_color = None,
title = "",
- icon = None)
+ icon = None,
+ no_buffering = False)
```
Parameter Descriptions:
@@ -16925,6 +16926,7 @@ Parameter Descriptions:
| str | transparent_color | This color will be completely see-through in your window. Can even click through |
| str | title | Title that will be shown on the window |
| str or bytes | icon | Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO |
+| bool | no_buffering | If True then no buffering will be used for the GIF. May work better if you have a large animation |
| bool | **RETURN** | True if the window updated OK. False if the window was closed
Popup that closes itself after some time period
@@ -17987,7 +17989,8 @@ PopupAnimated(image_source,
time_between_frames = 0,
transparent_color = None,
title = "",
- icon = None)
+ icon = None,
+ no_buffering = False)
```
Parameter Descriptions:
@@ -18009,6 +18012,7 @@ Parameter Descriptions:
| str | transparent_color | This color will be completely see-through in your window. Can even click through |
| str | title | Title that will be shown on the window |
| str or bytes | icon | Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO |
+| bool | no_buffering | If True then no buffering will be used for the GIF. May work better if you have a large animation |
| bool | **RETURN** | True if the window updated OK. False if the window was closed
Display a Popup without a titlebar. Enables grab anywhere so you can move it
diff --git a/readme_creator/output/index.md b/readme_creator/output/index.md
index a7ddf342..6c855457 100644
--- a/readme_creator/output/index.md
+++ b/readme_creator/output/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 62A4C02AB0A3DAB34388
+ 2F6C6BE01B8940D3E457
-
+
click here to visit course page
@@ -2028,7 +2028,8 @@ popup_animated(image_source,
time_between_frames = 0,
transparent_color = None,
title = "",
- icon = None)
+ icon = None,
+ no_buffering = False)
```
Parameter Descriptions:
@@ -2050,6 +2051,7 @@ Parameter Descriptions:
| str | transparent_color | This color will be completely see-through in your window. Can even click through |
| str | title | Title that will be shown on the window |
| str or bytes | icon | Same as Window icon parameter. Can be either a filename or Base64 byte string. For Windows if filename, it MUST be ICO format. For Linux, must NOT be ICO |
+| bool | no_buffering | If True then no buffering will be used for the GIF. May work better if you have a large animation |
| bool | **RETURN** | True if the window updated OK. False if the window was closed
***To close animated popups***, call PopupAnimated with `image_source=None`. This will close all of the currently open PopupAnimated windows.
From 2470d10afc797e34688cb356c76060fa6d4c90e4 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 2 Oct 2023 09:52:10 -0400
Subject: [PATCH 122/145] New Udemy coupons... added earlier but forgot to post
to GitHub
---
PySimpleGUI.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 6550b58f..97c3835c 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.198 Unreleased"
+version = __version__ = "4.61.0.199 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -468,7 +468,8 @@ _change_log = """
Made Table Element Header mouse-over and clicked be the inverse of the normal header colors. Makes for a much nicer experience
4.61.0.198
Added no_buffering option to popup_animated
-
+ 4.61.0.199
+ Updated Udemy coupon code
"""
@@ -26797,7 +26798,7 @@ def main():
elif event == 'Get Text':
popup_scrolled('Returned:', popup_get_text('Enter some text', keep_on_top=True))
elif event.startswith('-UDEMY-'):
- webbrowser.open_new_tab(r'https://www.udemy.com/course/pysimplegui/?couponCode=62A4C02AB0A3DAB34388')
+ webbrowser.open_new_tab(r'https://www.udemy.com/course/pysimplegui/?couponCode=2F6C6BE01B8940D3E457')
elif event.startswith('-SPONSOR-'):
if webbrowser_available:
webbrowser.open_new_tab(r'https://www.paypal.me/pythongui')
@@ -26805,7 +26806,7 @@ def main():
if webbrowser_available:
webbrowser.open_new_tab(r'https://www.buymeacoffee.com/PySimpleGUI')
elif event in ('-EMOJI-HEARTS-', '-HEART-', '-PYTHON HEARTS-'):
- popup_scrolled("Oh look! It's a Udemy discount coupon!", '62A4C02AB0A3DAB34388',
+ popup_scrolled("Oh look! It's a Udemy discount coupon!", '2F6C6BE01B8940D3E457',
'A personal message from Mike -- thank you so very much for supporting PySimpleGUI!', title='Udemy Coupon', image=EMOJI_BASE64_MIKE, keep_on_top=True)
elif event == 'Themes':
search_string = popup_get_text('Enter a search term or leave blank for all themes', 'Show Available Themes', keep_on_top=True)
From 5f8735d1f3268a161e7f3b2e54d0668a1dd26e2e Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 2 Oct 2023 13:12:48 -0400
Subject: [PATCH 123/145] Fix for grab anywhere window movement and
control+left_mouse_drag. Window move smoother, including the
Move-All-Windows feature. Thank you JASON for the help!
---
PySimpleGUI.py | 78 ++++++++++++++++++++++++--------------------------
1 file changed, 38 insertions(+), 40 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 97c3835c..1bc733af 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.199 Unreleased"
+version = __version__ = "4.61.0.200 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -470,6 +470,8 @@ _change_log = """
Added no_buffering option to popup_animated
4.61.0.199
Updated Udemy coupon code
+ 4.61.0.200
+ Fix for grab anywhere window movement and control+left_mouse_drag. Window move smoother, including the Move-All-Windows feature. Thank you JASON for the help!
"""
@@ -11745,8 +11747,8 @@ class Window:
:param event: event information passed in by tkinter. Contains x,y position of mouse
:type event: (event)
"""
-
- self._StartMove(event)
+ self._start_move_save_offset(event)
+ return
def _StartMoveGrabAnywhere(self, event):
@@ -11760,31 +11762,11 @@ class Window:
if (isinstance(event.widget, GRAB_ANYWHERE_IGNORE_THESE_WIDGETS) or event.widget in self._grab_anywhere_ignore_these_list) and event.widget not in self._grab_anywhere_include_these_list:
# print('Found widget to ignore in grab anywhere...')
return
-
- self._StartMove(event)
-
+ self._start_move_save_offset(event)
def _StartMove(self, event):
- try:
- geometry = self.TKroot.geometry()
- location = geometry[geometry.find('+')+1:].split('+')
- self._startx = int(location[0])
- self._starty = int(location[1])
- self._mousex = event.x + event.widget.winfo_rootx()
- self._mousey = event.y + event.widget.winfo_rooty()
- # print(self._startx, self._starty)
- # print(self._mousex, self._mousey)
- # print(self.TKroot.geometry())
- except:
- pass
- # print('Start move {},{} widget {}'.format(event.x,event.y, event.widget))
-
- if Window._move_all_windows:
- for window in Window._active_windows:
- window._offsetx = event.x + event.widget.winfo_rootx() - window.TKroot.winfo_rootx()
- window._offsety = event.y + event.widget.winfo_rooty() - window.TKroot.winfo_rooty()
-
-
+ self._start_move_save_offset(event)
+ return
def _StopMove(self, event):
"""
@@ -11795,6 +11777,28 @@ class Window:
"""
return
+ def _start_move_save_offset(self, event):
+ self._mousex = event.x + event.widget.winfo_rootx()
+ self._mousey = event.y + event.widget.winfo_rooty()
+ geometry = self.TKroot.geometry()
+ location = geometry[geometry.find('+') + 1:].split('+')
+ self._startx = int(location[0])
+ self._starty = int(location[1])
+ self._mouse_offset_x = self._mousex - self._startx
+ self._mouse_offset_y = self._mousey - self._starty
+ # ------ Move All Windows code ------
+ if Window._move_all_windows:
+ # print('Moving all')
+ for win in Window._active_windows:
+ if win == self:
+ continue
+ geometry = win.TKroot.geometry()
+ location = geometry[geometry.find('+') + 1:].split('+')
+ _startx = int(location[0])
+ _starty = int(location[1])
+ win._mouse_offset_x = event.x_root - _startx
+ win._mouse_offset_y = event.y_root - _starty
+
def _OnMotionUsingControlKey(self, event):
self._OnMotion(event)
@@ -11815,22 +11819,16 @@ class Window:
def _OnMotion(self, event):
- try:
- _mousex = event.x + event.widget.winfo_rootx()
- _mousey = event.y + event.widget.winfo_rooty()
- deltax = _mousex - self._mousex
- deltay = _mousey - self._mousey
- x = self._startx + deltax
- y = self._starty + deltay
- self.TKroot.geometry("+%s+%s" % (x, y)) # this is what really moves the window
+ self.TKroot.geometry(f"+{event.x_root-self._mouse_offset_x}+{event.y_root-self._mouse_offset_y}")
+ # print(f"+{event.x_root}+{event.y_root}")
+ # ------ Move All Windows code ------
+ try:
if Window._move_all_windows:
- for window in Window._active_windows:
- deltax = window._offsetx
- deltay = window._offsety
- x = window.TKroot.winfo_pointerx() - deltax
- y = window.TKroot.winfo_pointery() - deltay
- window.TKroot.geometry("+%s+%s" % (x, y)) # this is what really moves the window
+ for win in Window._active_windows:
+ if win == self:
+ continue
+ win.TKroot.geometry(f"+{event.x_root-win._mouse_offset_x}+{event.y_root-win._mouse_offset_y}")
except Exception as e:
print('on motion error', e)
From ddebd7a5c603a027fae70eaba20a6eff5dcedae0 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 5 Oct 2023 15:03:52 -0400
Subject: [PATCH 124/145] Added init for _mouse_offset_x and y in case tkinter
doesn't call the mouse down callback
---
PySimpleGUI.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 1bc733af..c6cf892a 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.200 Unreleased"
+version = __version__ = "4.61.0.201 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -472,6 +472,8 @@ _change_log = """
Updated Udemy coupon code
4.61.0.200
Fix for grab anywhere window movement and control+left_mouse_drag. Window move smoother, including the Move-All-Windows feature. Thank you JASON for the help!
+ 4.61.0.201
+ Added init for _mouse_offset_x and y in case tkinter doesn't call the mouse down callback
"""
@@ -10618,6 +10620,7 @@ class Window:
if self.use_custom_titlebar:
self.Margins = (0, 0)
self.NoTitleBar = True
+ self._mouse_offset_x = self._mouse_offset_y = 0
if watermark is True:
Window._watermark_temp_forced = True
@@ -26985,4 +26988,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#8191dd5d8352d3c13f89bde32cdd01d664da2f4cabeff579ec281e413131545b6aafe489020f8f73c96477dbdf9e86e0013c01759cae8c5837d9d7ea44c7fc75f9af3fb5bce6270b0254f6f6f2d966abc5257991792b3d83880d7690a85e8f4b59e4051b0ff2f7ac1a5fa27d5630c2365d70398b22cda91c1a988c4f19379c4575afb6f6c86e873e0bcda2ed4fc65879a8c4c7a297437742b1ac070de6d04019ffc5e350d6030ce97965d0414ef48ea670ba21bb359319f1c8be7e6da2ff46c727ea82f54eb30d3a74728b5aa20e1412b6812750cfb8cb6122b3e720f0a2c0106d7ddb0eba9313ed763aa3f404221e0d4ffe9bb324a56ebb410e5cd6f45f6b985db5c39369d1fe201fc2ee7c9e8017e8eb7a9e08edafa15ad8a89f6214b75b8e183e2dde4c67350975999d7f74572f0f17d422a9ca430c928f80e2ffee4dd376ce916999b7a263b39783ddf54242b1341e70240c6875832525d87100c9a733d09969465e38226d80ead49508692eb9851eaa4fba26ca5069cb2c6ee88647c79683860d9b12fa598a1d452015d80295a1b59236c38f8fb42edf1aa897db653f8c20ce79836641cc64c1e5975b8400edc98854ab5c26de57241ce8b89979173b84f9cf3e5dd455a63721545001b06af63a8b11ed7889a4e53af7a1527bbd3e14ae6e6a16eb569c79d7213d52e7f276f1a59423fb3a519adc122b73128196aec80a
\ No newline at end of file
+#5550034f4202b0dde48a8ff1a870d871f1759f6e59b3a92f40150e8c42204e1b06eaafbe206994c7f0ff811df9f61018269480e40a91fe781b16dac2c81dfe0c0977090f8557e435b97d4d8e7c5ec1c91f2be19033b9dc2f5a8f16e0b5d1cab1e692d998dbb4f5fc26b551befa483142430c1cadee39363aba10ed19675867ed15ef534fd40fcdf38c811e3431751de160dd6eb567091160b936a580305902387dca997ce20b90f80984644e8289882eabf1809b3f54f98a80ea80f2c5a644ebeac34413cf68b4c8cf2c7d69072abee5fddd075e7daae6f7644e4eba3deaa228cc4d4dbcb59cdc62c73c2c830f630653cc10646d314eeba1736f43a8a603c57221eb9977f2ad6a05692f87f161238e8514b317d20fcaec1e84faead09e0e8c9ecac402c38a021b490086fd3d07d3f2777627f21946f0ff1b4b0e66d28e1b0484a21b9d61f4929bfd9ca58c48ec1e7bd764cbfe21cc827ae7239d544ee324a0f4a1d9d4aa75d5e76a0fed5f8540ba275fdc3684d2d7b722028cabee2d3d7aa469ab4c9cf5c3c66cb7dbcc749b57991988e726c5191ac02224d345d87ba6eb5b209f5f755fa1318f10034de6c828aead47f333f80de385ae13e0a0be2a8c76cfa9162c24c6ff9dc55c0031af42464adaf2ccb95bebbd17f24cfd2938140c3538109491bea1f409c7358dde3a2466f4788a68cd3c3bb45cbd33589475a149617549
\ No newline at end of file
From 377673070981329149108f9e088da0ed305ce835 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 5 Oct 2023 16:11:51 -0400
Subject: [PATCH 125/145] Replaced PIL's deprecated constant ANTIALIAS with
LANCZOS
---
DemoPrograms/Demo_Buttons_Nice_Graphics.py | 2 +-
DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py | 2 +-
DemoPrograms/Demo_Emoji_Toolbar_PIL.py | 2 +-
DemoPrograms/Demo_Graph_Elem_Image_Album.py | 2 +-
DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py | 2 +-
DemoPrograms/Demo_Image_Resize_and_Base64_Encode.pyw | 2 +-
DemoPrograms/Demo_Image_Viewer_Thumbnails.py | 2 +-
DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py | 2 +-
DemoPrograms/Demo_Nice_Buttons.py | 2 +-
DemoPrograms/Demo_PIL_Use.py | 2 +-
DemoPrograms/Demo_PNG_Thumbnail_Viewer.py | 6 +++---
DemoPrograms/Demo_System_Tray_Reminder.py | 2 +-
docs/cookbook.md | 4 ++--
13 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/DemoPrograms/Demo_Buttons_Nice_Graphics.py b/DemoPrograms/Demo_Buttons_Nice_Graphics.py
index 3d372416..45b3c915 100644
--- a/DemoPrograms/Demo_Buttons_Nice_Graphics.py
+++ b/DemoPrograms/Demo_Buttons_Nice_Graphics.py
@@ -26,7 +26,7 @@ def resize_base64_image(image64, size):
'''
image_file = io.BytesIO(base64.b64decode(image64))
img = Image.open(image_file)
- img.thumbnail(size, Image.ANTIALIAS)
+ img.thumbnail(size, Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format='PNG')
imgbytes = bio.getvalue()
diff --git a/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py b/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py
index 8aec989c..2e5f6bb0 100644
--- a/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py
+++ b/DemoPrograms/Demo_Desktop_Widget_Digital_Picture_Frame.py
@@ -81,7 +81,7 @@ def convert_to_bytes(source, size=(None, None), subsample=None, zoom=None, fill=
elif zoom is not None:
scale = zoom
- resized_image = image.resize((int(width * scale), int(height * scale)), Image.ANTIALIAS) if scale is not None else image
+ resized_image = image.resize((int(width * scale), int(height * scale)), Image.LANCZOS) if scale is not None else image
if fill and scale is not None:
resized_image = make_square(resized_image)
# encode a PNG formatted version of image into BASE64
diff --git a/DemoPrograms/Demo_Emoji_Toolbar_PIL.py b/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
index 0ff22ce9..ee4b84b5 100644
--- a/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
+++ b/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
@@ -92,7 +92,7 @@ def convert_to_bytes(file_or_bytes, resize=None, fill=False):
if resize:
new_width, new_height = resize
scale = min(new_height / cur_height, new_width / cur_width)
- img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL. Image.LANCZOS)
if fill:
if resize is not None:
img = make_square(img, resize[0])
diff --git a/DemoPrograms/Demo_Graph_Elem_Image_Album.py b/DemoPrograms/Demo_Graph_Elem_Image_Album.py
index 115f72c5..90f2770e 100644
--- a/DemoPrograms/Demo_Graph_Elem_Image_Album.py
+++ b/DemoPrograms/Demo_Graph_Elem_Image_Album.py
@@ -44,7 +44,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
diff --git a/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py b/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py
index 715bb351..9cb05b8c 100644
--- a/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py
+++ b/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py
@@ -45,7 +45,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
with io.BytesIO() as bio:
img.save(bio, format="PNG")
del img
diff --git a/DemoPrograms/Demo_Image_Resize_and_Base64_Encode.pyw b/DemoPrograms/Demo_Image_Resize_and_Base64_Encode.pyw
index 12e880be..f1a00789 100644
--- a/DemoPrograms/Demo_Image_Resize_and_Base64_Encode.pyw
+++ b/DemoPrograms/Demo_Image_Resize_and_Base64_Encode.pyw
@@ -55,7 +55,7 @@ def resize(input_file, size, output_file=None, encode_format='PNG'):
new_width, new_height = size
if new_width != width or new_height != height: # if the requested size is different than original size
scale = min(new_height / height, new_width / width)
- resized_image = image.resize((int(width * scale), int(height * scale)), Image.ANTIALIAS)
+ resized_image = image.resize((int(width * scale), int(height * scale)), Image.LANCZOS)
else:
resized_image = image
diff --git a/DemoPrograms/Demo_Image_Viewer_Thumbnails.py b/DemoPrograms/Demo_Image_Viewer_Thumbnails.py
index c766fed2..43742cc8 100644
--- a/DemoPrograms/Demo_Image_Viewer_Thumbnails.py
+++ b/DemoPrograms/Demo_Image_Viewer_Thumbnails.py
@@ -56,7 +56,7 @@ def convert_to_bytes(file_or_bytes, resize=None, fill=False):
if resize:
new_width, new_height = resize
scale = min(new_height / cur_height, new_width / cur_width)
- img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL. Image.LANCZOS)
if fill:
img = make_square(img, THUMBNAIL_SIZE[0])
with io.BytesIO() as bio:
diff --git a/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py b/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py
index f42f26ee..fb253de3 100644
--- a/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py
+++ b/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py
@@ -890,7 +890,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
with io.BytesIO() as bio:
img.save(bio, format="PNG")
del img
diff --git a/DemoPrograms/Demo_Nice_Buttons.py b/DemoPrograms/Demo_Nice_Buttons.py
index a1cefe13..9e782d11 100644
--- a/DemoPrograms/Demo_Nice_Buttons.py
+++ b/DemoPrograms/Demo_Nice_Buttons.py
@@ -15,7 +15,7 @@ button64 = 'iVBORw0KGgoAAAANSUhEUgAAAoAAAAFACAMAAAAbEz04AAAABGdBTUEAALGPC/xhBQAA
def image_file_to_bytes(image64, size):
image_file = io.BytesIO(base64.b64decode(image64))
img = Image.open(image_file)
- img.thumbnail(size, Image.ANTIALIAS)
+ img.thumbnail(size, Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format='PNG')
imgbytes = bio.getvalue()
diff --git a/DemoPrograms/Demo_PIL_Use.py b/DemoPrograms/Demo_PIL_Use.py
index ca7a37a4..0854e242 100644
--- a/DemoPrograms/Demo_PIL_Use.py
+++ b/DemoPrograms/Demo_PIL_Use.py
@@ -60,7 +60,7 @@ def convert_to_bytes(source, size=(None, None), subsample=None, zoom=None, fill=
elif zoom is not None:
scale = zoom
- resized_image = image.resize((int(width * scale), int(height * scale)), Image.ANTIALIAS) if scale is not None else image
+ resized_image = image.resize((int(width * scale), int(height * scale)), Image.LANCZOS) if scale is not None else image
if fill and scale is not None:
resized_image = make_square(resized_image)
# encode a PNG formatted version of image into BASE64
diff --git a/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py b/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py
index 36e1d8c6..3056c3ad 100644
--- a/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py
+++ b/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py
@@ -59,7 +59,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height / cur_height, new_width / cur_width)
- img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL. Image.LANCZOS)
with io.BytesIO() as bio:
img.save(bio, format="PNG")
del img
@@ -69,7 +69,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
# def image_file_to_bytes(filename, size):
# try:
# image = Image.open(filename)
-# image.thumbnail(size, Image.ANTIALIAS)
+# image.thumbnail(size, Image.LANCZOS)
# bio = io.BytesIO() # a binary memory resident stream
# image.save(bio, format='PNG') # save image as png to it
# imgbytes = bio.getvalue()
@@ -80,7 +80,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
def set_image_to_blank(key):
img = PIL.Image.new('RGB', (100, 100), (255, 255, 255))
- img.thumbnail((1, 1), PIL.Image.ANTIALIAS)
+ img.thumbnail((1, 1), PIL. Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format='PNG')
imgbytes = bio.getvalue()
diff --git a/DemoPrograms/Demo_System_Tray_Reminder.py b/DemoPrograms/Demo_System_Tray_Reminder.py
index b93d883e..94bba7cb 100644
--- a/DemoPrograms/Demo_System_Tray_Reminder.py
+++ b/DemoPrograms/Demo_System_Tray_Reminder.py
@@ -29,7 +29,7 @@ def resize_base64_image(image64, size):
"""
image_file = io.BytesIO(base64.b64decode(image64))
img = Image.open(image_file)
- img.thumbnail(size, Image.ANTIALIAS)
+ img.thumbnail(size, Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format='PNG')
imgbytes = bio.getvalue()
diff --git a/docs/cookbook.md b/docs/cookbook.md
index 3637ddd3..cc8789b6 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -2664,7 +2664,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
@@ -2747,7 +2747,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
From 7f485c5f78f29cd961cd96cff5d3fefa41c49623 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 5 Oct 2023 16:26:20 -0400
Subject: [PATCH 126/145] Remove extra space accidently added (learned you can
put spaces after periods in Python?)
---
DemoPrograms/Demo_Emoji_Toolbar_PIL.py | 2 +-
DemoPrograms/Demo_Graph_Elem_Image_Album.py | 2 +-
DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py | 2 +-
DemoPrograms/Demo_Image_Viewer_Thumbnails.py | 2 +-
DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py | 2 +-
DemoPrograms/Demo_PNG_Thumbnail_Viewer.py | 4 ++--
docs/cookbook.md | 4 ++--
7 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/DemoPrograms/Demo_Emoji_Toolbar_PIL.py b/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
index ee4b84b5..dd0cecee 100644
--- a/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
+++ b/DemoPrograms/Demo_Emoji_Toolbar_PIL.py
@@ -92,7 +92,7 @@ def convert_to_bytes(file_or_bytes, resize=None, fill=False):
if resize:
new_width, new_height = resize
scale = min(new_height / cur_height, new_width / cur_width)
- img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.LANCZOS)
if fill:
if resize is not None:
img = make_square(img, resize[0])
diff --git a/DemoPrograms/Demo_Graph_Elem_Image_Album.py b/DemoPrograms/Demo_Graph_Elem_Image_Album.py
index 90f2770e..4a38454f 100644
--- a/DemoPrograms/Demo_Graph_Elem_Image_Album.py
+++ b/DemoPrograms/Demo_Graph_Elem_Image_Album.py
@@ -44,7 +44,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
diff --git a/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py b/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py
index 9cb05b8c..9585b96c 100644
--- a/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py
+++ b/DemoPrograms/Demo_Image_Elem_Image_Viewer_PIL_Based.py
@@ -45,7 +45,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
with io.BytesIO() as bio:
img.save(bio, format="PNG")
del img
diff --git a/DemoPrograms/Demo_Image_Viewer_Thumbnails.py b/DemoPrograms/Demo_Image_Viewer_Thumbnails.py
index 43742cc8..d7f77498 100644
--- a/DemoPrograms/Demo_Image_Viewer_Thumbnails.py
+++ b/DemoPrograms/Demo_Image_Viewer_Thumbnails.py
@@ -56,7 +56,7 @@ def convert_to_bytes(file_or_bytes, resize=None, fill=False):
if resize:
new_width, new_height = resize
scale = min(new_height / cur_height, new_width / cur_width)
- img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.LANCZOS)
if fill:
img = make_square(img, THUMBNAIL_SIZE[0])
with io.BytesIO() as bio:
diff --git a/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py b/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py
index fb253de3..09097450 100644
--- a/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py
+++ b/DemoPrograms/Demo_Matplotlib_Grid_of_Graphs_Using_PIL.py
@@ -890,7 +890,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
with io.BytesIO() as bio:
img.save(bio, format="PNG")
del img
diff --git a/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py b/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py
index 3056c3ad..9b400da0 100644
--- a/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py
+++ b/DemoPrograms/Demo_PNG_Thumbnail_Viewer.py
@@ -59,7 +59,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height / cur_height, new_width / cur_width)
- img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width * scale), int(cur_height * scale)), PIL.Image.LANCZOS)
with io.BytesIO() as bio:
img.save(bio, format="PNG")
del img
@@ -80,7 +80,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
def set_image_to_blank(key):
img = PIL.Image.new('RGB', (100, 100), (255, 255, 255))
- img.thumbnail((1, 1), PIL. Image.LANCZOS)
+ img.thumbnail((1, 1), PIL.Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format='PNG')
imgbytes = bio.getvalue()
diff --git a/docs/cookbook.md b/docs/cookbook.md
index cc8789b6..5a2b26a2 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -2664,7 +2664,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
@@ -2747,7 +2747,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL. Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
From fe31a0a7ed3dc60dfe3c59f15ec2c406335a978f Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 16 Oct 2023 08:57:47 -0400
Subject: [PATCH 127/145] Fixed numpy deprecated problems. Checking in
improvement made long ago buit forgot to check in
---
DemoPrograms/Demo_Sudoku.py | 87 +++++++++++++++++--------------------
1 file changed, 40 insertions(+), 47 deletions(-)
diff --git a/DemoPrograms/Demo_Sudoku.py b/DemoPrograms/Demo_Sudoku.py
index 7e6ba67b..041faf96 100644
--- a/DemoPrograms/Demo_Sudoku.py
+++ b/DemoPrograms/Demo_Sudoku.py
@@ -2,18 +2,17 @@ import PySimpleGUI as sg, random
import numpy as np
from typing import List, Any, Union, Tuple, Dict
-
"""
Sudoku Puzzle Demo
-
+
How to easily generate a GUI for a Sudoku puzzle.
The Window definition and creation is a single line of code.
-
+
Code to generate a playable puzzle was supplied from:
https://github.com/MorvanZhou/sudoku
-
+
Copyright 2020 PySimpleGUI.com
-
+
"""
@@ -27,7 +26,7 @@ def generate_sudoku(mask_rate):
"""
while True:
n = 9
- solution = np.zeros((n, n), np.int)
+ solution = np.zeros((n, n), np.int_)
rg = np.arange(1, n + 1)
solution[0, :] = np.random.choice(rg, n, replace=False)
try:
@@ -36,10 +35,11 @@ def generate_sudoku(mask_rate):
col_rest = np.setdiff1d(rg, solution[:r, c])
row_rest = np.setdiff1d(rg, solution[r, :c])
avb1 = np.intersect1d(col_rest, row_rest)
- sub_r, sub_c = r//3, c//3
- avb2 = np.setdiff1d(np.arange(0, n+1), solution[sub_r*3:(sub_r+1)*3, sub_c*3:(sub_c+1)*3].ravel())
+ sub_r, sub_c = r // 3, c // 3
+ avb2 = np.setdiff1d(np.arange(0, n + 1), solution[sub_r * 3:(sub_r + 1) * 3, sub_c * 3:(sub_c + 1) * 3].ravel())
avb = np.intersect1d(avb1, avb2)
- solution[r, c] = np.random.choice(avb, size=1)
+ # solution[r, c] = np.random.choice(avb, size=1)
+ solution[r, c] = np.random.choice(avb, size=1)[0]
break
except ValueError:
pass
@@ -48,7 +48,6 @@ def generate_sudoku(mask_rate):
return puzzle, solution
-
def check_progress(window, solution):
"""
Gives you a visual hint on your progress.
@@ -65,38 +64,23 @@ def check_progress(window, solution):
solved = True
for r, row in enumerate(solution):
for c, col in enumerate(row):
- value = window[r,c].get()
+ value = window[r, c].get()
if value:
try:
value = int(value)
except:
value = 0
if value != solution[r][c]:
- window[r,c].update(background_color='red')
+ window[r, c].update(background_color='red')
solved = False
else:
- window[r,c].update(background_color=sg.theme_input_background_color())
+ window[r, c].update(background_color=sg.theme_input_background_color())
else:
solved = False
window[r, c].update(background_color='yellow')
return solved
-def create_and_show_puzzle(window):
- # create and display a puzzle by updating the Input elements
- rate = DEFAULT_MASK_RATE
- if window['-RATE-'].get():
- try:
- rate = float(window['-RATE-'].get())
- except:
- pass
- puzzle, solution = generate_sudoku(mask_rate=rate)
- for r, row in enumerate(puzzle):
- for c, col in enumerate(row):
- window[r, c].update(puzzle[r][c] if puzzle[r][c] else '', background_color=sg.theme_input_background_color())
- return puzzle, solution
-
-
def main(mask_rate=0.7):
""""
The Main GUI - It does it all.
@@ -105,8 +89,19 @@ def main(mask_rate=0.7):
addressing of the individual squares is via a key that's a tuple (0,0) to (8,8)
"""
-
-
+ def create_and_show_puzzle():
+ # create and display a puzzle by updating the Input elements
+ rate = mask_rate
+ if window['-RATE-'].get():
+ try:
+ rate = float(window['-RATE-'].get())
+ except:
+ pass
+ puzzle, solution = generate_sudoku(mask_rate=rate)
+ for r, row in enumerate(puzzle):
+ for c, col in enumerate(row):
+ window[r, c].update(puzzle[r][c] if puzzle[r][c] else '', background_color=sg.theme_input_background_color())
+ return puzzle, solution
# It's 1 line of code to make a Sudoku board. If you don't like it, then replace it.
# Dude (Dudette), it's 1-line of code. If you don't like the board, write a line of code.
@@ -114,16 +109,18 @@ def main(mask_rate=0.7):
# Get an input element for a position using: window[row, col]
# To get a better understanding, take it apart. Spread it out. You'll learn in the process.
window = sg.Window('Sudoku',
- [[sg.Frame('', [[sg.I(random.randint(1,9), justification='r', size=(3,1),enable_events=True, key=(fr*3+r,fc*3+c)) for c in range(3)] for r in range(3)]) for fc in range(3)] for fr in range(3)] +
- [[sg.B('Solve'), sg.B('Check'), sg.B('Hint'), sg.B('New Game'), sg.T('Mask rate (0-1)'), sg.In(str(mask_rate), size=(3,1),key='-RATE-')],], finalize=True)
+ [[sg.Frame('', [[sg.I(random.randint(1, 9), justification='r', size=(3, 1), key=(fr * 3 + r, fc * 3 + c)) for c in range(3)] for r in range(3)]) for fc in
+ range(3)] for fr in range(3)] +
+ [[sg.B('Solve'), sg.B('Check'), sg.B('Hint'), sg.B('New Game')], [sg.T('Mask rate (0-1)'), sg.In(str(mask_rate), size=(3, 1), key='-RATE-')], ],
+ finalize=True)
# create and display a puzzle by updating the Input elements
- puzzle, solution = create_and_show_puzzle(window)
- check_showing = False
- while True: # The Event Loop
+ puzzle, solution = create_and_show_puzzle()
+
+ while True: # The Event Loop
event, values = window.read()
- if event == sg.WIN_CLOSED:
+ if event is None:
break
if event == 'Solve':
@@ -131,7 +128,6 @@ def main(mask_rate=0.7):
for c, col in enumerate(row):
window[r, c].update(solution[r][c], background_color=sg.theme_input_background_color())
elif event == 'Check':
- check_showing = True
solved = check_progress(window, solution)
if solved:
sg.popup('Solved! You have solved the puzzle correctly.')
@@ -140,17 +136,14 @@ def main(mask_rate=0.7):
try:
elem.update(solution[elem.Key[0]][elem.Key[1]], background_color=sg.theme_input_background_color())
except:
- pass # Likely because an input element didn't have focus
+ pass # Likely because an input element didn't have focus
elif event == 'New Game':
- puzzle, solution = create_and_show_puzzle(window)
- elif check_showing: # an input was changed, so clear any background colors from prior hints
- check_showing = False
- for r, row in enumerate(solution):
- for c, col in enumerate(row):
- window[r, c].update(background_color=sg.theme_input_background_color())
+ puzzle, solution = create_and_show_puzzle()
+
window.close()
-if __name__ == "__main__":
- DEFAULT_MASK_RATE = 0.7 # % Of cells to hide
- main(DEFAULT_MASK_RATE)
+
+if __name__ == "__main__":
+ mask_rate = 0.7 # % Of cells to hide
+ main(mask_rate)
From 5131c537f522e054c43b7b4ee39e72a6792344e9 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Fri, 20 Oct 2023 17:30:27 +0000
Subject: [PATCH 128/145] Automated Update!
---
docs/Screens2.md | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/docs/Screens2.md b/docs/Screens2.md
index a5cc70d1..1171933c 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,13 @@
+[maria-korosteleva](https://github.com/maria-korosteleva) 2023-10-20T11:52:13Z
+I've used the framework to build a garment design configurator in my latest research paper on programmable garments =)
+https://github.com/maria-korosteleva/GarmentCode
+https://igl.ethz.ch/projects/garmentcode/
+
+
+
+
+-----------
+
[onyx-and-iris](https://github.com/onyx-and-iris) 2023-09-06T00:00:13Z
A small remote utility for Voicemeeter, designed to work with the NVDA screen reader.
From 746b79d61a0d7be1960c7be6a0ab94d49c0bc796 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sat, 21 Oct 2023 17:30:27 +0000
Subject: [PATCH 129/145] Automated Update!
---
docs/Screens.md | 6 ++++++
docs/Screens2.md | 7 +++++++
2 files changed, 13 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index b8b9d02c..54dbbdfd 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,9 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-21T16:11:14Z
+
+
+
+-----------
+
[onyx-and-iris](https://github.com/onyx-and-iris) 2023-09-06T00:00:13Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index 1171933c..2df21734 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,10 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-21T16:11:14Z
+Wow @maria-korosteleva what an incredible application! I love what you've created! 
+
+I've never seen anything like what you've made. There's clearly a **lot** going on with your work than just a GUI. I had never thought about the intersection of CAD and making garments. It's a fascinating use of technology. I really appreciate you taking the time to post a screenshot and letting us know about your project.
+
+-----------
+
[maria-korosteleva](https://github.com/maria-korosteleva) 2023-10-20T11:52:13Z
I've used the framework to build a garment design configurator in my latest research paper on programmable garments =)
https://github.com/maria-korosteleva/GarmentCode
From 29127a73eef3d0288bd96a869b83f8fdb222ac14 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Mon, 23 Oct 2023 17:30:23 +0000
Subject: [PATCH 130/145] Automated Update!
---
docs/Screens2.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/docs/Screens2.md b/docs/Screens2.md
index 2df21734..ce1f808c 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,9 @@
+[maria-korosteleva](https://github.com/maria-korosteleva) 2023-10-23T09:26:11Z
+@PySimpleGUI Thank you very much for your kind words! 🥰
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-21T16:11:14Z
Wow @maria-korosteleva what an incredible application! I love what you've created! 
From 9b63e2e66102ed807822d3c06cfabdd24f927b28 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Thu, 26 Oct 2023 17:30:26 +0000
Subject: [PATCH 131/145] Automated Update!
---
docs/Screens.md | 14 ++++++++++++++
docs/Screens2.md | 29 +++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 54dbbdfd..db331dba 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,17 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-26T09:38:54Z
+
+
+
+-----------
+
+[ikeman32](https://github.com/ikeman32) 2023-10-25T21:58:09Z
+
+
+
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-21T16:11:14Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index ce1f808c..41b51850 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,32 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-26T09:38:54Z
+We're on very similar wavelengths @ikeman32. It's great to see some add-on tools to help users.
+
+As part of the PySimpleGUI 5 release of the PySimpleGUI applications and add-on modules, I've written a GUI tool that creates all of the necessary files to upload a PySimpleGUI application to PyPI, opening up distribution of Python applications to PySimpleGUI users. We've been releasing tools via PyPI for some time. "psgresizer" is a good example. Users can pip install it and then once installed it can be run by typing "psgresizer" from the command line. There's already a tool, psgshortcut, that takes it all a start further by making shortcuts (icons) that can be pinned to the taskbar or double-clicked.
+
+The idea is to make distribution easy as well as the result be familiar feeling. The command line isn't a normal part of a normal Windows user's world, so getting it out of the way entirely makes a lot of sense. I've just about got the final tool finished that will make it all work end to end.
+
+
+
+
+-----------
+
+[ikeman32](https://github.com/ikeman32) 2023-10-25T21:58:09Z
+I have created a simple bash script to initialize a PySimpleGUI project. It can be found here: https://github.com/ikeman32/ScriptHelpers/tree/main/devscripts
+
+It's very basic at the moment, but functional. For Windows users, I do have an AI-generated port, but it remains untested as I gave up my Windows addiction in 2017. I may eventually create a platform-independent version of the script using Python.
+
+I do accept code contributions, so if there are Windows users that want to develop a Windows batch equivalent or a Python version of this script, see the README. Or you can code your own.
+
+PySimpleGUI is an absolute God-sent for me. I like simplicity, and I am also lazy, so if there is an easier way to do something, I'm all for it. I'm also in the planning stages for a visual editor/IDE for PySimpleGUI applications.
+
+
+
+
+
+
+
+-----------
+
[maria-korosteleva](https://github.com/maria-korosteleva) 2023-10-23T09:26:11Z
@PySimpleGUI Thank you very much for your kind words! 🥰
From f78e4913a275d762ffd987191c0d412b0eb12c13 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 27 Oct 2023 11:36:53 -0400
Subject: [PATCH 132/145] New Udemy Coupon Code
---
docs/cookbook.md | 8 ++++----
docs/readme.md | 4 ++--
readme.md | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/docs/cookbook.md b/docs/cookbook.md
index 5a2b26a2..c31e2319 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 2F6C6BE01B8940D3E457
+ C967880E71496470E40E
-
+
click here to visit course page
@@ -2664,7 +2664,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
@@ -2747,7 +2747,7 @@ def convert_to_bytes(file_or_bytes, resize=None):
if resize:
new_width, new_height = resize
scale = min(new_height/cur_height, new_width/cur_width)
- img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.LANCZOS)
+ img = img.resize((int(cur_width*scale), int(cur_height*scale)), PIL.Image.ANTIALIAS)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
diff --git a/docs/readme.md b/docs/readme.md
index e73b6075..2f5ece73 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -9,8 +9,8 @@
From 0f16031512678d0c0c80c3f868ededf20f39d6a0 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 27 Oct 2023 11:47:21 -0400
Subject: [PATCH 133/145] New yaml file for readthedocs
---
readthedocs.yml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/readthedocs.yml b/readthedocs.yml
index 47eaa0a4..b3c5d278 100644
--- a/readthedocs.yml
+++ b/readthedocs.yml
@@ -1,7 +1,10 @@
version: 2
+version: 2
+build:
+ os: "ubuntu-22.04"
+
python:
- version: 3.6
install:
- requirements: docs/requirements.txt
From 1ee5a7f9d2460de4f3f9d5998303af16c2b59a3c Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 27 Oct 2023 11:49:01 -0400
Subject: [PATCH 134/145] Update readthedocs.yml
---
readthedocs.yml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/readthedocs.yml b/readthedocs.yml
index b3c5d278..d05298fb 100644
--- a/readthedocs.yml
+++ b/readthedocs.yml
@@ -3,7 +3,9 @@ version: 2
version: 2
build:
os: "ubuntu-22.04"
-
+ tools:
+ python: "3.11"
+
python:
install:
- requirements: docs/requirements.txt
From bed18263e619cbbfdc77aed8a9e26657bbc1a9cf Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Fri, 27 Oct 2023 12:13:19 -0400
Subject: [PATCH 135/145] New udemy coupon.
---
docs/call reference.md | 4 ++--
docs/index.md | 4 ++--
readme_creator/markdown input files/1_HEADER_top_part.md | 4 ++--
readme_creator/markdown input files/5_call_reference.md | 4 ++--
readme_creator/output/call reference.md | 4 ++--
readme_creator/output/index.md | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/docs/call reference.md b/docs/call reference.md
index 08ca758c..ff8d87df 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 2F6C6BE01B8940D3E457.
+ C967880E71496470E40E.
-
+
click here to visit course page
diff --git a/docs/index.md b/docs/index.md
index 6c855457..58767359 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 2F6C6BE01B8940D3E457
+ C967880E71496470E40E
-
+
click here to visit course page
diff --git a/readme_creator/markdown input files/1_HEADER_top_part.md b/readme_creator/markdown input files/1_HEADER_top_part.md
index ca75d9e5..a9aac931 100644
--- a/readme_creator/markdown input files/1_HEADER_top_part.md
+++ b/readme_creator/markdown input files/1_HEADER_top_part.md
@@ -52,9 +52,9 @@ HOW DO I INSERT IMAGES ???
apply coupon for discount:
- 2F6C6BE01B8940D3E457
+ C967880E71496470E40E
-
+
click here to visit course page
diff --git a/readme_creator/markdown input files/5_call_reference.md b/readme_creator/markdown input files/5_call_reference.md
index 7b223866..a9ebf633 100644
--- a/readme_creator/markdown input files/5_call_reference.md
+++ b/readme_creator/markdown input files/5_call_reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 2F6C6BE01B8940D3E457.
+ C967880E71496470E40E.
-
+
click here to visit course page
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index 08ca758c..ff8d87df 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 2F6C6BE01B8940D3E457.
+ C967880E71496470E40E.
-
+
click here to visit course page
diff --git a/readme_creator/output/index.md b/readme_creator/output/index.md
index 6c855457..58767359 100644
--- a/readme_creator/output/index.md
+++ b/readme_creator/output/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- 2F6C6BE01B8940D3E457
+ C967880E71496470E40E
-
+
click here to visit course page
From 85f3f472f7da67510a006ee89347bb30acee4321 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 29 Oct 2023 13:10:57 -0400
Subject: [PATCH 136/145] Added doctring and destroy previous right click menu
to set_right_click_menu AND Changed Sizer element to use Canvas
instead of Column element
---
PySimpleGUI.py | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index c6cf892a..2b1489c6 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.201 Unreleased"
+version = __version__ = "4.61.0.203 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -474,6 +474,10 @@ _change_log = """
Fix for grab anywhere window movement and control+left_mouse_drag. Window move smoother, including the Move-All-Windows feature. Thank you JASON for the help!
4.61.0.201
Added init for _mouse_offset_x and y in case tkinter doesn't call the mouse down callback
+ 4.61.0.202
+ Added doctring and destroy previous right click menu to set_right_click_menu
+ 4.61.0.203
+ Changed Sizer element to use Canvas instead of Column element
"""
@@ -2267,6 +2271,12 @@ class Element():
def set_right_click_menu(self, menu=None):
+ """
+ Sets a right click menu for an element.
+ If a menu is already set for the element, it will call the tkinter destroy method to remove it
+ :param menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format.
+ :type menu: List[List[ List[str] | str ]]
+ """
if menu == MENU_RIGHT_CLICK_DISABLED:
return
if menu is None:
@@ -2274,6 +2284,12 @@ class Element():
if menu is None:
return
if menu:
+ # If previously had a menu destroy it
+ if self.TKRightClickMenu:
+ try:
+ self.TKRightClickMenu.destroy()
+ except:
+ pass
top_menu = tk.Menu(self.ParentForm.TKroot, tearoff=self.ParentForm.right_click_menu_tearoff, tearoffcommand=self._tearoff_menu_callback)
if self.ParentForm.right_click_menu_background_color not in (COLOR_SYSTEM_DEFAULT, None):
@@ -13595,8 +13611,8 @@ def Sizer(h_pixels=0, v_pixels=0):
:rtype: (Column)
"""
- return Column([[]], pad=((h_pixels, 0), (v_pixels, 0)))
-
+ # return Column([[]], pad=((h_pixels, 0), (v_pixels, 0)))
+ return Canvas(size=(h_pixels, v_pixels), pad=(0,0))
def pin(elem, vertical_alignment=None, shrink=True, expand_x=None, expand_y=None):
"""
@@ -26988,4 +27004,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#5550034f4202b0dde48a8ff1a870d871f1759f6e59b3a92f40150e8c42204e1b06eaafbe206994c7f0ff811df9f61018269480e40a91fe781b16dac2c81dfe0c0977090f8557e435b97d4d8e7c5ec1c91f2be19033b9dc2f5a8f16e0b5d1cab1e692d998dbb4f5fc26b551befa483142430c1cadee39363aba10ed19675867ed15ef534fd40fcdf38c811e3431751de160dd6eb567091160b936a580305902387dca997ce20b90f80984644e8289882eabf1809b3f54f98a80ea80f2c5a644ebeac34413cf68b4c8cf2c7d69072abee5fddd075e7daae6f7644e4eba3deaa228cc4d4dbcb59cdc62c73c2c830f630653cc10646d314eeba1736f43a8a603c57221eb9977f2ad6a05692f87f161238e8514b317d20fcaec1e84faead09e0e8c9ecac402c38a021b490086fd3d07d3f2777627f21946f0ff1b4b0e66d28e1b0484a21b9d61f4929bfd9ca58c48ec1e7bd764cbfe21cc827ae7239d544ee324a0f4a1d9d4aa75d5e76a0fed5f8540ba275fdc3684d2d7b722028cabee2d3d7aa469ab4c9cf5c3c66cb7dbcc749b57991988e726c5191ac02224d345d87ba6eb5b209f5f755fa1318f10034de6c828aead47f333f80de385ae13e0a0be2a8c76cfa9162c24c6ff9dc55c0031af42464adaf2ccb95bebbd17f24cfd2938140c3538109491bea1f409c7358dde3a2466f4788a68cd3c3bb45cbd33589475a149617549
\ No newline at end of file
+#3479bf01bf15751ece66f3f051045efd19442e1a59258450609b19789838cae7bbd47b4657b8be3c77b23ad9f7462bcae6b15e0b43683b19d464210391f37adb9ad6279915d2e85f5ca2ce1005462bc70fbdb5bb957ad4ac22a5c9fd814a4bf5a50bd7f7a46b155b3444b37716189b38bcdf3088ebe49f4ad9ffd162aa06adf2d54f7d096116d166575f3ad564f0a400bfd506d6adbbb663281d25ca19d243092411da18391e01feaaf5b75e6714095d82982302403c26de5855d8676df91f1ae694b4a0d47757b1c15dd507ff7843494d5c300be97fd53094ef77da5eec0a8a812ddecb01d294b3bce407ac04f79269bfaea95e375c19ed3fecdb75c8e8c6d6a93fc13c7c6cbea20dbabf10e9e28c3567d79a63f5c8b1a766fa640e7fb9397cf9000aa4127bf360aebb000c433531fa6d1cfbfa473efcbf0b72c89903a9b9c2e1eed43a4710ef0a9ee62fd94c297aabfb8db4e1ca913fea58b80c4131f5bf62a147a91220261af9f76fdea5556a63886581d76c96a955af6b26aeec5cb3f41c4b84c80623e099f04dfdc4fbc1d63c1291129c80b7aba628c3ceedb9244dcd8c05f8991cdf2fcdd510cb2f1f28134587a8f0d3ee01cabcbf29c9eff72cd120614d06423f372b30221f7f3a0ce985a29ec1c7561213fac5bed8023c07698b26775fb14027676fbd8fea17ff7c5a3839bc69bf680cc227b544fd2defd8a08cb02f
\ No newline at end of file
From cb39c58f9867851d321a6b374a92971be0db109c Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 29 Oct 2023 13:23:16 -0400
Subject: [PATCH 137/145] One more change to sizer so that it uses pad instead
of size.
---
PySimpleGUI.py | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 2b1489c6..a292e289 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.203 Unreleased"
+version = __version__ = "4.61.0.204 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -478,6 +478,8 @@ _change_log = """
Added doctring and destroy previous right click menu to set_right_click_menu
4.61.0.203
Changed Sizer element to use Canvas instead of Column element
+ 4.61.0.204
+ One more change to sizer so that it uses pad instead of size.
"""
@@ -13607,12 +13609,11 @@ def Sizer(h_pixels=0, v_pixels=0):
:type h_pixels: (int)
:param v_pixels: number of vertical pixels
:type v_pixels: (int)
- :return: (Column) A column element that has a pad setting set according to parameters
- :rtype: (Column)
+ :return: (Canvas) A canvas element that has a pad setting set according to parameters
+ :rtype: (Canvas)
"""
- # return Column([[]], pad=((h_pixels, 0), (v_pixels, 0)))
- return Canvas(size=(h_pixels, v_pixels), pad=(0,0))
+ return Canvas(size=(0, 0), pad=((h_pixels, 0), (v_pixels, 0)))
def pin(elem, vertical_alignment=None, shrink=True, expand_x=None, expand_y=None):
"""
@@ -27004,4 +27005,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#3479bf01bf15751ece66f3f051045efd19442e1a59258450609b19789838cae7bbd47b4657b8be3c77b23ad9f7462bcae6b15e0b43683b19d464210391f37adb9ad6279915d2e85f5ca2ce1005462bc70fbdb5bb957ad4ac22a5c9fd814a4bf5a50bd7f7a46b155b3444b37716189b38bcdf3088ebe49f4ad9ffd162aa06adf2d54f7d096116d166575f3ad564f0a400bfd506d6adbbb663281d25ca19d243092411da18391e01feaaf5b75e6714095d82982302403c26de5855d8676df91f1ae694b4a0d47757b1c15dd507ff7843494d5c300be97fd53094ef77da5eec0a8a812ddecb01d294b3bce407ac04f79269bfaea95e375c19ed3fecdb75c8e8c6d6a93fc13c7c6cbea20dbabf10e9e28c3567d79a63f5c8b1a766fa640e7fb9397cf9000aa4127bf360aebb000c433531fa6d1cfbfa473efcbf0b72c89903a9b9c2e1eed43a4710ef0a9ee62fd94c297aabfb8db4e1ca913fea58b80c4131f5bf62a147a91220261af9f76fdea5556a63886581d76c96a955af6b26aeec5cb3f41c4b84c80623e099f04dfdc4fbc1d63c1291129c80b7aba628c3ceedb9244dcd8c05f8991cdf2fcdd510cb2f1f28134587a8f0d3ee01cabcbf29c9eff72cd120614d06423f372b30221f7f3a0ce985a29ec1c7561213fac5bed8023c07698b26775fb14027676fbd8fea17ff7c5a3839bc69bf680cc227b544fd2defd8a08cb02f
\ No newline at end of file
+#2e3530bf7b9c7d2770054a0b33bc671dac9415010a5538c10185614a700119e33eec9c81d34cbc215dbfaa9ca4946883ed0a8b6f1a81acfbf7bdd16af1102b43edf840bb0e67ac7032f4b7dbb04748fa00966884ce0ef41bddb9ee8ded4c74bf20fe787093a041598701a9644096abe75706158341a9d82ce2b230c784bc71d960ecc2f98e37836b559099f3373de729771db2ba3bd3522b2c8b3faa9cb2ec4ae7dbaa4b88e8d289ceb3d423ac63cfe5e279540efe13e246bb8061231432eb3eb3b2eac1af56b38b9e1f2c688f2b5ccb1f187a0492de065aa985fabda3d9dbc463c2a62cdae1b516852179b1da7855198c03fb6bb9d05495d64e04b6809d8b40ccc532a6fabd1577a1f83af4fa928349a69994f5c010400a4ec81f6804badd61a6efa608372f39cc113cd33bdc6c568e46828657d5fe21828a6157ba7101295c7039f0c3d31f35b9f2ef9bbbc245fd7e26efe218914edfeceed69651d9d9d90839d5ce21098c8898551025438be74bd2e4cefed8470242b52fed9c47dbbf3b38b4d4eeaa11f62ddf6630bdc7ee863cbd1a17bb845750c3eda5431c75a791e64961076a08664e11e6f83dc5d004f524b69d43e8cca324a8cd2399552bb8bb01028ebd0f662695900a5fb5a5c9ba681212eb064e2e1e86bd047f2f825a1760f8f61b7846eb1e160c9f10bb7bef84508f8d0936e25f2a3caf5767a833278ed317c0
\ No newline at end of file
From e59310d5fc1d6e17069cc0f1f2e3a7f9505d61db Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Tue, 7 Nov 2023 18:30:22 +0000
Subject: [PATCH 138/145] Automated Update!
---
docs/Screens.md | 6 ++++++
docs/Screens2.md | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index db331dba..8896ceef 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,9 @@
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-11-07T14:22:15Z
+
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-26T09:38:54Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index 41b51850..f96ae8df 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,42 @@
+[SaSp73](https://github.com/SaSp73) 2023-11-07T15:52:58Z
+Thanks for your kind words. I will send you the code in a couple of days when I return back home.
+It need some extra hardware (PICAN-M board, Adafruit ADC and BME280 barometer), but you will manage to get around this with a little bit of tinkering.
+Basically the whole control is a graph with elements redrawing according to the calculated data...
+
+BTW, a Rotate_Figure(figure_id, center_point, degrees_of_rotation) would be very helpful (I will open a suggestion later)
+
+-----------
+
+[PySimpleGUI](https://github.com/PySimpleGUI) 2023-11-07T14:22:15Z
+WOW @SaSp73 !!
+
+
+
+Truly mind-blowing and very inspiring to see. I've never seen anything like this done with PySimpleGUI! One of the things I love about this project are the surprises by what people create.
+
+I would love to see how you did some of the things you did if you ever care to share the code (even privately would be great.... I'll be confidential. I'm curious what features were helpful).
+
+Thank you so so much for sharing.
+
+
+
+-----------
+
+[kcl1s](https://github.com/kcl1s) 2023-11-07T11:01:09Z
+Wow
+Those graphics are fantastic. Thanks for sharing.
+
+
+-----------
+
+[SaSp73](https://github.com/SaSp73) 2023-11-07T09:35:57Z
+This is my use of PySimpleGUI, a program reading NMEA200 networks, running on raspberry pi 4, and presenting various data used for sail racing.
+
+
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-26T09:38:54Z
We're on very similar wavelengths @ikeman32. It's great to see some add-on tools to help users.
From 93358382b495d7d039fdad1965f7cb84964db1dc Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Fri, 10 Nov 2023 18:30:24 +0000
Subject: [PATCH 139/145] Automated Update!
---
docs/Screens.md | 8 +++++++-
docs/Screens2.md | 4 ++--
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/docs/Screens.md b/docs/Screens.md
index 8896ceef..834c895e 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -4,6 +4,12 @@
-----------
+[SaSp73](https://github.com/SaSp73) 2023-11-07T09:35:57Z
+
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-10-26T09:38:54Z

@@ -69,7 +75,7 @@
-----------
-[Kinetikal](https://github.com/Kinetikal) 2023-04-19T09:55:26Z
+[zaricj](https://github.com/zaricj) 2023-04-19T09:55:26Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index f96ae8df..52894b87 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -31,7 +31,7 @@ Those graphics are fantastic. Thanks for sharing.
[SaSp73](https://github.com/SaSp73) 2023-11-07T09:35:57Z
This is my use of PySimpleGUI, a program reading NMEA200 networks, running on raspberry pi 4, and presenting various data used for sail racing.
-
+
@@ -176,7 +176,7 @@ It's got a nice design and the custom buttons look great.
-----------
-[Kinetikal](https://github.com/Kinetikal) 2023-04-19T09:55:26Z
+[zaricj](https://github.com/zaricj) 2023-04-19T09:55:26Z
I've been using PySimpleGUI to make a GUI for the Chocolatey Package Manager, thought of sending a screenshot of it here.

From e949083fdaeabf5885e2f368af25b70e4636a762 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Mon, 13 Nov 2023 13:15:23 -0500
Subject: [PATCH 140/145] Fixed docstring for execute_command_subprocess. The
command description was incorrect
---
PySimpleGUI.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index a292e289..4fd4cb7f 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.204 Unreleased"
+version = __version__ = "4.61.0.205 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -480,6 +480,9 @@ _change_log = """
Changed Sizer element to use Canvas instead of Column element
4.61.0.204
One more change to sizer so that it uses pad instead of size.
+ 4.61.0.205
+ Fixed docstring for execute_command_subprocess. The command description was incorrect
+
"""
@@ -23693,7 +23696,7 @@ def execute_command_subprocess(command, *args, wait=False, cwd=None, pipe_output
The function will immediately return without waiting for the process to complete running. You can use the returned Popen object to communicate with the subprocess and get the results.
Returns a subprocess Popen object.
- :param command: Filename to load settings from (and save to in the future)
+ :param command: The command/file to execute. What you would type at a console to run a program or shell command.
:type command: (str)
:param *args: Variable number of arguments that are passed to the program being started as command line parms
:type *args: (Any)
@@ -27005,4 +27008,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#2e3530bf7b9c7d2770054a0b33bc671dac9415010a5538c10185614a700119e33eec9c81d34cbc215dbfaa9ca4946883ed0a8b6f1a81acfbf7bdd16af1102b43edf840bb0e67ac7032f4b7dbb04748fa00966884ce0ef41bddb9ee8ded4c74bf20fe787093a041598701a9644096abe75706158341a9d82ce2b230c784bc71d960ecc2f98e37836b559099f3373de729771db2ba3bd3522b2c8b3faa9cb2ec4ae7dbaa4b88e8d289ceb3d423ac63cfe5e279540efe13e246bb8061231432eb3eb3b2eac1af56b38b9e1f2c688f2b5ccb1f187a0492de065aa985fabda3d9dbc463c2a62cdae1b516852179b1da7855198c03fb6bb9d05495d64e04b6809d8b40ccc532a6fabd1577a1f83af4fa928349a69994f5c010400a4ec81f6804badd61a6efa608372f39cc113cd33bdc6c568e46828657d5fe21828a6157ba7101295c7039f0c3d31f35b9f2ef9bbbc245fd7e26efe218914edfeceed69651d9d9d90839d5ce21098c8898551025438be74bd2e4cefed8470242b52fed9c47dbbf3b38b4d4eeaa11f62ddf6630bdc7ee863cbd1a17bb845750c3eda5431c75a791e64961076a08664e11e6f83dc5d004f524b69d43e8cca324a8cd2399552bb8bb01028ebd0f662695900a5fb5a5c9ba681212eb064e2e1e86bd047f2f825a1760f8f61b7846eb1e160c9f10bb7bef84508f8d0936e25f2a3caf5767a833278ed317c0
\ No newline at end of file
+#5545a931e7a1314d3f851ca20a18423484698ab868afd5a96927317b2c5ec13896f3fc634b68f9c1fcd9a381ce0192c51d13088670cb215e207f61f2be6088b1f20e0d4bdb5b992f0f2387b4cb205451cd5452041ca66159c87788d3e7bb84a6183d845012e02fc199b20342dfc2cd0c781d0e1624ee0602f85a4b83cb9004fa98b36565125a64234030a93e7c413be3fa1ec5740a13718f2126ab3e3db059037e676670b5dd4b2192058c9b41f25e868dc95a5064a83b6a10106d8002c142300394a583000c5f6ad76b9b2ee2d5ad357acc6e670576374e5562114f16a0a88328daa2d3e08539507011660a931dc97e72c1b399fffd00b2e7769992c05e6e25d99dac6e96d6095a36843484dcaef2b09c551da47a599bab6e143a583e72de15a769fa80b6af001582ce0391fb1e5652dc992354d553481e819e690d43e729883b285d3735ba88f48fc5ebceca15c460007ad88b689623c6b4f774b53a91cbe0eb8212951bbdc6991aafeb292e7d31faa11f4f884c934805398c511a9ed99b1a3d7baf0a7bee8aacc6e71638fa87f5796a316216d23f766bd0c9b194d9ac660b97f5a8de1b93ace083c74fd3d59e07f1c3d76a8afdf90cca75f820153f73cd3b0f7614e0d9ecb3b53ecb479a2b6a5738d966bb87c07566161bf6fff882102ca6ffa05cf53049f5002fd711685e2df18a630abe4bebb3d9c73495ac44bd8d3fe0
\ No newline at end of file
From 3f96ecf9ae1790397c541f7acf9cba6a7881cd99 Mon Sep 17 00:00:00 2001
From: PySimpleGUI <46163555+PySimpleGUI@users.noreply.github.com>
Date: Sun, 19 Nov 2023 18:30:26 +0000
Subject: [PATCH 141/145] Automated Update!
---
docs/Screens.md | 11 +++++++++++
docs/Screens2.md | 33 +++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/docs/Screens.md b/docs/Screens.md
index 834c895e..23a4da7f 100644
--- a/docs/Screens.md
+++ b/docs/Screens.md
@@ -1,3 +1,14 @@
+[splatert](https://github.com/splatert) 2023-11-19T04:48:55Z
+
+
+
+
+
+
+
+
+-----------
+
[PySimpleGUI](https://github.com/PySimpleGUI) 2023-11-07T14:22:15Z

diff --git a/docs/Screens2.md b/docs/Screens2.md
index 52894b87..43e8598c 100644
--- a/docs/Screens2.md
+++ b/docs/Screens2.md
@@ -1,3 +1,36 @@
+[splatert](https://github.com/splatert) 2023-11-19T04:48:55Z
+Hello. I would like to thank you for the awesome UI framework you built as it really does help create interfaces in a really simple manner. I've given credit to you on my project's readme file and provided a link that leads to your github page.
+
+With the power of your library, I've created an alternative UI frontend for SpotDL. A tool for downloading Spotify tracks using URLs that you provide. Now SpotDL does have their own interface which is loaded onto the web browser but It felt like it was slow as it took a couple of seconds to start up, which is why I wanted to create my own.
+
+
+
+The way this frontend is used is that you provide each link into the interface's textbox then hit the plus button to pass them to a list of URLs (which then the listbox shown above displays the urls list).
+
+Upon providing URLs, you then press the download button to initiate the download process (given that you provide the SpotDL executable).
+
+
+If the control shown above is checked, the program would ask you to provide a name for the folder you want to create and send downloaded songs to. Prompt dialog is shown below.
+
+
+Pressing **OK** will assign the folder name to a string variable then tell the program that you want to create a folder.
+Pressing **Cancel** or having the checkbox mentioned above unmarked would not tell the program to create any folders.
+
+
+After information is provided, the program executes SpotDL with the links you entered passed as arguments and will wait for it to complete the download job.
+
+
+
+After the download job is finished, songs get transferred over to the frontend's music directory and you will get a message saying that the download process has been completed.
+
+
+
+
+Here's a link to the project repository.
+https://github.com/splatert/spotdl-ui
+
+-----------
+
[SaSp73](https://github.com/SaSp73) 2023-11-07T15:52:58Z
Thanks for your kind words. I will send you the code in a couple of days when I return back home.
It need some extra hardware (PICAN-M board, Adafruit ADC and BME280 barometer), but you will manage to get around this with a little bit of tinkering.
From 05939b2725100cf4b1277f58c01f914f822bfc5f Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Thu, 23 Nov 2023 14:28:24 -0500
Subject: [PATCH 142/145] Make the multiple open demo program more useful
---
.../Demo_Window_Open_Multiple_Times.py | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/DemoPrograms/Demo_Window_Open_Multiple_Times.py b/DemoPrograms/Demo_Window_Open_Multiple_Times.py
index ffcc6a49..ac4bbca7 100644
--- a/DemoPrograms/Demo_Window_Open_Multiple_Times.py
+++ b/DemoPrograms/Demo_Window_Open_Multiple_Times.py
@@ -10,10 +10,10 @@ import PySimpleGUI as sg
The purpose of this demo is to show you the simple "make window" design pattern. It simply makes a
window using a layout that's defined in that function and returns the Window object. It's not a bad
- way to encapsulate windows if your applcation is gettinga little larger than the typical small data
+ way to encapsulate windows if your application is getting a little larger than the typical small data
entry window.
- Copyright 2020 PySimpleGUI.org
+ Copyright 2020, 2023 PySimpleGUI.org
"""
@@ -25,11 +25,12 @@ def make_window():
:return: Window that is created using the layout defined in the function
:rtype: Window
"""
- layout = [[sg.Text('My Window')],
- [sg.Input(key='-IN-'), sg.Text(size=(12, 1), key='-OUT-')],
- [sg.Button('Go'), sg.Button('Exit')]]
+ layout = [[sg.Text('The program will only exit using the "Quit Program" button.')],
+ [sg.Text('Closing the window or using Exit button will cause a new window to be created.')],
+ [sg.Input(key='-IN-')],
+ [sg.Button('Does Nothing'), sg.Button('Exit'), sg.Button('Quit Program')]]
- return sg.Window('Window Title', layout)
+ return sg.Window('Window that restarts on exit', layout)
def main():
@@ -41,8 +42,10 @@ def main():
if event == sg.WIN_CLOSED or event == 'Exit':
window.close()
window = make_window()
- elif event == 'Go':
- window['-OUT-'].update(values['-IN-'])
+ elif event == 'Quit Program': # The Quit Program button break out of event loop and exits program
+ break
+
+ window.close()
if __name__ == '__main__':
From a2cd9fb702f06040d762d1b24730e1a981b77b88 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sat, 25 Nov 2023 12:53:49 -0500
Subject: [PATCH 143/145] New Udemy Coupon Code
---
PySimpleGUI.py | 8 +++++---
docs/call reference.md | 8 ++++----
docs/cookbook.md | 4 ++--
docs/index.md | 4 ++--
readme_creator/markdown input files/1_HEADER_top_part.md | 4 ++--
readme_creator/markdown input files/5_call_reference.md | 4 ++--
readme_creator/output/call reference.md | 8 ++++----
readme_creator/output/index.md | 4 ++--
8 files changed, 23 insertions(+), 21 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 4fd4cb7f..2d21a099 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -482,6 +482,8 @@ _change_log = """
One more change to sizer so that it uses pad instead of size.
4.61.0.205
Fixed docstring for execute_command_subprocess. The command description was incorrect
+ 4.61.0.206
+ New Udemy Coupon code
"""
@@ -26819,7 +26821,7 @@ def main():
elif event == 'Get Text':
popup_scrolled('Returned:', popup_get_text('Enter some text', keep_on_top=True))
elif event.startswith('-UDEMY-'):
- webbrowser.open_new_tab(r'https://www.udemy.com/course/pysimplegui/?couponCode=2F6C6BE01B8940D3E457')
+ webbrowser.open_new_tab(r'https://www.udemy.com/course/pysimplegui/?couponCode=522B20BF5EF123C4AB30')
elif event.startswith('-SPONSOR-'):
if webbrowser_available:
webbrowser.open_new_tab(r'https://www.paypal.me/pythongui')
@@ -26827,7 +26829,7 @@ def main():
if webbrowser_available:
webbrowser.open_new_tab(r'https://www.buymeacoffee.com/PySimpleGUI')
elif event in ('-EMOJI-HEARTS-', '-HEART-', '-PYTHON HEARTS-'):
- popup_scrolled("Oh look! It's a Udemy discount coupon!", '2F6C6BE01B8940D3E457',
+ popup_scrolled("Oh look! It's a Udemy discount coupon!", '522B20BF5EF123C4AB30',
'A personal message from Mike -- thank you so very much for supporting PySimpleGUI!', title='Udemy Coupon', image=EMOJI_BASE64_MIKE, keep_on_top=True)
elif event == 'Themes':
search_string = popup_get_text('Enter a search term or leave blank for all themes', 'Show Available Themes', keep_on_top=True)
@@ -27008,4 +27010,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#5545a931e7a1314d3f851ca20a18423484698ab868afd5a96927317b2c5ec13896f3fc634b68f9c1fcd9a381ce0192c51d13088670cb215e207f61f2be6088b1f20e0d4bdb5b992f0f2387b4cb205451cd5452041ca66159c87788d3e7bb84a6183d845012e02fc199b20342dfc2cd0c781d0e1624ee0602f85a4b83cb9004fa98b36565125a64234030a93e7c413be3fa1ec5740a13718f2126ab3e3db059037e676670b5dd4b2192058c9b41f25e868dc95a5064a83b6a10106d8002c142300394a583000c5f6ad76b9b2ee2d5ad357acc6e670576374e5562114f16a0a88328daa2d3e08539507011660a931dc97e72c1b399fffd00b2e7769992c05e6e25d99dac6e96d6095a36843484dcaef2b09c551da47a599bab6e143a583e72de15a769fa80b6af001582ce0391fb1e5652dc992354d553481e819e690d43e729883b285d3735ba88f48fc5ebceca15c460007ad88b689623c6b4f774b53a91cbe0eb8212951bbdc6991aafeb292e7d31faa11f4f884c934805398c511a9ed99b1a3d7baf0a7bee8aacc6e71638fa87f5796a316216d23f766bd0c9b194d9ac660b97f5a8de1b93ace083c74fd3d59e07f1c3d76a8afdf90cca75f820153f73cd3b0f7614e0d9ecb3b53ecb479a2b6a5738d966bb87c07566161bf6fff882102ca6ffa05cf53049f5002fd711685e2df18a630abe4bebb3d9c73495ac44bd8d3fe0
\ No newline at end of file
+#722a483aea42030011461a21e54c30712fc87a01c22c71b5cfce8bb74b1913f74bb8376a9a47006947a1b1262fbe3ef81e7f9432c131563602dea877d84d6fadb9a977ff422e90eddde2c4917b5a969b2bd7b944f7ef9c08d3426620ee2917461e2323a76d725ae99cb239a73b9e7970533bb2a34a35bf2d2f339c087489c4023c0099a36c54991f378034265c3a84e159c0baa26983724908dd8897117fe7fe7e2428346c3e7f8eae8fc29222005b0dbfba9cac5ff663dc9dd7d598ac015d40b2e542eb08303c8e5c4cb06c2cdedb5d6349ce4a4d08cec2fddc26b19a4fe4cdb3d8d845c2d0740d9f3580ca6ef491c0c7396e573a41d31197e2e582c1a1910487ca3ebdaccf66ced2cf02ce34f3bfa883758dc4f78d8a097b79518aa5eec4a087d7d9ac42e60a396d4a3019b87c8249cf8797558d5dc9ded9e401c4550f812e4f1a627cb3b806723350d704b4c8cb89a460a89451ec4b5c7ed618c4242a80160932c19168390ce4ac346cb95c74100da2c3de06b833c2e063e6c246386d009df1586bc16d6e8bda892b7217e3027fcafab9fa628b2aa1c8e5c249a8ca46df7934aa061dffea226278f7c7e69312ac4038e42b75935574540c8435c01da375d09d021e34225ee474fac27bccfefb8149186d103c2ed93015406463f53476beab267de36cf4f433cec1c65a5e3e29fc829ec0307bfb298f583eae53f40b8b6d9c
\ No newline at end of file
diff --git a/docs/call reference.md b/docs/call reference.md
index ff8d87df..e909d3e7 100644
--- a/docs/call reference.md
+++ b/docs/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- C967880E71496470E40E.
+ 522B20BF5EF123C4AB30.
-
+
click here to visit course page
@@ -8996,7 +8996,7 @@ Parameter Descriptions:
|--|--|--|
| int | h_pixels | number of horizontal pixels |
| int | v_pixels | number of vertical pixels |
-| (Column) | **RETURN** | (Column) A column element that has a pad setting set according to parameters
+| (Canvas) | **RETURN** | (Canvas) A canvas element that has a pad setting set according to parameters
-------
@@ -19879,7 +19879,7 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | command | Filename to load settings from (and save to in the future) |
+| str | command | The command/file to execute. What you would type at a console to run a program or shell command. |
| Any | *args | Variable number of arguments that are passed to the program being started as command line parms |
| bool | wait | If True then wait for the subprocess to finish |
| str | cwd | Working directory to use when executing the subprocess |
diff --git a/docs/cookbook.md b/docs/cookbook.md
index c31e2319..0b977854 100644
--- a/docs/cookbook.md
+++ b/docs/cookbook.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- C967880E71496470E40E
+ 522B20BF5EF123C4AB30
-
+
click here to visit course page
diff --git a/docs/index.md b/docs/index.md
index 58767359..fd28ee9a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- C967880E71496470E40E
+ 522B20BF5EF123C4AB30
-
+
click here to visit course page
diff --git a/readme_creator/markdown input files/1_HEADER_top_part.md b/readme_creator/markdown input files/1_HEADER_top_part.md
index a9aac931..f1232855 100644
--- a/readme_creator/markdown input files/1_HEADER_top_part.md
+++ b/readme_creator/markdown input files/1_HEADER_top_part.md
@@ -52,9 +52,9 @@ HOW DO I INSERT IMAGES ???
apply coupon for discount:
- C967880E71496470E40E
+ 522B20BF5EF123C4AB30
-
+
click here to visit course page
diff --git a/readme_creator/markdown input files/5_call_reference.md b/readme_creator/markdown input files/5_call_reference.md
index a9ebf633..24c9e48c 100644
--- a/readme_creator/markdown input files/5_call_reference.md
+++ b/readme_creator/markdown input files/5_call_reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- C967880E71496470E40E.
+ 522B20BF5EF123C4AB30.
-
+
click here to visit course page
diff --git a/readme_creator/output/call reference.md b/readme_creator/output/call reference.md
index ff8d87df..e909d3e7 100644
--- a/readme_creator/output/call reference.md
+++ b/readme_creator/output/call reference.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- C967880E71496470E40E.
+ 522B20BF5EF123C4AB30.
-
+
click here to visit course page
@@ -8996,7 +8996,7 @@ Parameter Descriptions:
|--|--|--|
| int | h_pixels | number of horizontal pixels |
| int | v_pixels | number of vertical pixels |
-| (Column) | **RETURN** | (Column) A column element that has a pad setting set according to parameters
+| (Canvas) | **RETURN** | (Canvas) A canvas element that has a pad setting set according to parameters
-------
@@ -19879,7 +19879,7 @@ Parameter Descriptions:
|Type|Name|Meaning|
|--|--|--|
-| str | command | Filename to load settings from (and save to in the future) |
+| str | command | The command/file to execute. What you would type at a console to run a program or shell command. |
| Any | *args | Variable number of arguments that are passed to the program being started as command line parms |
| bool | wait | If True then wait for the subprocess to finish |
| str | cwd | Working directory to use when executing the subprocess |
diff --git a/readme_creator/output/index.md b/readme_creator/output/index.md
index 58767359..fd28ee9a 100644
--- a/readme_creator/output/index.md
+++ b/readme_creator/output/index.md
@@ -25,9 +25,9 @@
apply coupon for discount:
- C967880E71496470E40E
+ 522B20BF5EF123C4AB30
-
+
click here to visit course page
From bf4630ec65dd105f3f80a3874402cd14a1c30728 Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sat, 25 Nov 2023 12:57:17 -0500
Subject: [PATCH 144/145] Bumped the version number (forgot to with the Udemy
coupon)
---
PySimpleGUI.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/PySimpleGUI.py b/PySimpleGUI.py
index 2d21a099..fbbfd08d 100644
--- a/PySimpleGUI.py
+++ b/PySimpleGUI.py
@@ -1,6 +1,6 @@
#!/usr/bin/python3
-version = __version__ = "4.61.0.205 Unreleased"
+version = __version__ = "4.61.0.206 Unreleased"
_change_log = """
Changelog since 4.60.0 released to PyPI on 8-May-2022
@@ -27010,4 +27010,4 @@ if __name__ == '__main__':
exit(0)
main()
exit(0)
-#722a483aea42030011461a21e54c30712fc87a01c22c71b5cfce8bb74b1913f74bb8376a9a47006947a1b1262fbe3ef81e7f9432c131563602dea877d84d6fadb9a977ff422e90eddde2c4917b5a969b2bd7b944f7ef9c08d3426620ee2917461e2323a76d725ae99cb239a73b9e7970533bb2a34a35bf2d2f339c087489c4023c0099a36c54991f378034265c3a84e159c0baa26983724908dd8897117fe7fe7e2428346c3e7f8eae8fc29222005b0dbfba9cac5ff663dc9dd7d598ac015d40b2e542eb08303c8e5c4cb06c2cdedb5d6349ce4a4d08cec2fddc26b19a4fe4cdb3d8d845c2d0740d9f3580ca6ef491c0c7396e573a41d31197e2e582c1a1910487ca3ebdaccf66ced2cf02ce34f3bfa883758dc4f78d8a097b79518aa5eec4a087d7d9ac42e60a396d4a3019b87c8249cf8797558d5dc9ded9e401c4550f812e4f1a627cb3b806723350d704b4c8cb89a460a89451ec4b5c7ed618c4242a80160932c19168390ce4ac346cb95c74100da2c3de06b833c2e063e6c246386d009df1586bc16d6e8bda892b7217e3027fcafab9fa628b2aa1c8e5c249a8ca46df7934aa061dffea226278f7c7e69312ac4038e42b75935574540c8435c01da375d09d021e34225ee474fac27bccfefb8149186d103c2ed93015406463f53476beab267de36cf4f433cec1c65a5e3e29fc829ec0307bfb298f583eae53f40b8b6d9c
\ No newline at end of file
+#25424909a31c4fa789f5aa4e210e7e07d412560195dc21abe678b68a3b4bdb2a8a78651d8613daaded730bc2a31adc02ba8b99717fff701cda8ae13c31f1dcee9da8837908626f1c5cc81e7a34d3b9cd032dba190647564bba72d248ad6b83e30c8abc057f3f1b1fb3a2ca853069de936f3f53522fd4732b743268e0fcde54577a05880f2057efe6bbd6349f77d6c002544f38e24db40ab84f3dde4a4b8b31e84480db31656fb74ae0c01a7af0b35ac66cf8a0fbb8ca85685fea075608c7862da6635511d0e5403c4a637138324ce1fb1308b765cba53863ddf7b01ca4fc988932b03c4a8403a72b8105f821913f02925218dbecf1e089bd32e78667939503f2abfd89b37fa293927e30550d441f21dc68273d2d07ed910f6a69bc8c792015eb623ada7e65347cf0389cf2a1696a7ccf88098a4fb4bfa44e88fac2a94a44e25b010355e48d483d896c58eb771ef47e01066156f9344750b487e176ca0642601951f096d4c03045aa8f912d475dbe04b82c6ddf1ac3adbf815aef4ca2c6add058c2789b66a9abd875f334752ec1bde11b9b56e334823304b6cc3fadf7daae277c982ebc7eadb726a33e2740d075ad082b9c20304c4a53228d6f05357c40903a78113aea4e6169e1a5351866f7a9ffc6666eb08a31bfb84d90cb3002f7ebf87871988b88a7b8a52d36a1a7dd826360b5c6ad922829d9f73d204f09d1b9ad9ffd8d
\ No newline at end of file
From aae672824cbc3f0d9abe3a8f1ec22f12f9a6583e Mon Sep 17 00:00:00 2001
From: PySimpleGUI
Date: Sun, 26 Nov 2023 17:23:25 -0500
Subject: [PATCH 145/145] Ooops... forgot to update the Udemy coupon in the
readme too.
---
docs/readme.md | 4 ++--
readme.md | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/readme.md b/docs/readme.md
index 2f5ece73..1504d49e 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -9,8 +9,8 @@