KL-Py 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KL_Py/KL_Py.py +4400 -0
- KL_Py/__init__.py +1 -0
- KL_Py/hindGui/__init__.py +16529 -0
- KL_Py/hindGui/_utils.py +140 -0
- KL_Py/hindGui/elements/base.py +1055 -0
- KL_Py/hindGui/elements/button.py +947 -0
- KL_Py/hindGui/elements/calendar.py +222 -0
- KL_Py/hindGui/elements/canvas.py +122 -0
- KL_Py/hindGui/elements/center.py +44 -0
- KL_Py/hindGui/elements/checkbox.py +240 -0
- KL_Py/hindGui/elements/column.py +443 -0
- KL_Py/hindGui/elements/combo.py +329 -0
- KL_Py/hindGui/elements/error.py +47 -0
- KL_Py/hindGui/elements/frame.py +273 -0
- KL_Py/hindGui/elements/graph.py +817 -0
- KL_Py/hindGui/elements/helpers.py +202 -0
- KL_Py/hindGui/elements/image.py +324 -0
- KL_Py/hindGui/elements/input.py +310 -0
- KL_Py/hindGui/elements/list_box.py +392 -0
- KL_Py/hindGui/elements/menu.py +192 -0
- KL_Py/hindGui/elements/multiline.py +685 -0
- KL_Py/hindGui/elements/option_menu.py +168 -0
- KL_Py/hindGui/elements/pane.py +127 -0
- KL_Py/hindGui/elements/progress_bar.py +304 -0
- KL_Py/hindGui/elements/radio.py +252 -0
- KL_Py/hindGui/elements/separator.py +64 -0
- KL_Py/hindGui/elements/sizegrip.py +34 -0
- KL_Py/hindGui/elements/slider.py +199 -0
- KL_Py/hindGui/elements/spin.py +252 -0
- KL_Py/hindGui/elements/status_bar.py +165 -0
- KL_Py/hindGui/elements/stretch.py +26 -0
- KL_Py/hindGui/elements/tab.py +697 -0
- KL_Py/hindGui/elements/table.py +463 -0
- KL_Py/hindGui/elements/text.py +413 -0
- KL_Py/hindGui/elements/tree.py +493 -0
- KL_Py/hindGui/replace.py +45 -0
- KL_Py/hindGui/tray.py +358 -0
- KL_Py/hindGui/window.py +2906 -0
- KL_Py/requests/__init__.py +184 -0
- KL_Py/requests/__version__.py +14 -0
- KL_Py/requests/_internal_utils.py +50 -0
- KL_Py/requests/adapters.py +719 -0
- KL_Py/requests/api.py +157 -0
- KL_Py/requests/auth.py +314 -0
- KL_Py/requests/certifi/__init__.py +4 -0
- KL_Py/requests/certifi/__main__.py +12 -0
- KL_Py/requests/certifi/core.py +83 -0
- KL_Py/requests/certifi/py.typed +0 -0
- KL_Py/requests/certs.py +17 -0
- KL_Py/requests/charset_normalizer/__init__.py +48 -0
- KL_Py/requests/charset_normalizer/__main__.py +6 -0
- KL_Py/requests/charset_normalizer/api.py +671 -0
- KL_Py/requests/charset_normalizer/cd.py +421 -0
- KL_Py/requests/charset_normalizer/cli/__init__.py +8 -0
- KL_Py/requests/charset_normalizer/cli/__main__.py +363 -0
- KL_Py/requests/charset_normalizer/constant.py +2031 -0
- KL_Py/requests/charset_normalizer/legacy.py +80 -0
- KL_Py/requests/charset_normalizer/md.py +744 -0
- KL_Py/requests/charset_normalizer/models.py +359 -0
- KL_Py/requests/charset_normalizer/py.typed +0 -0
- KL_Py/requests/charset_normalizer/utils.py +420 -0
- KL_Py/requests/charset_normalizer/version.py +8 -0
- KL_Py/requests/compat.py +106 -0
- KL_Py/requests/cookies.py +561 -0
- KL_Py/requests/exceptions.py +151 -0
- KL_Py/requests/help.py +134 -0
- KL_Py/requests/hooks.py +33 -0
- KL_Py/requests/idna/__init__.py +45 -0
- KL_Py/requests/idna/codec.py +122 -0
- KL_Py/requests/idna/compat.py +15 -0
- KL_Py/requests/idna/core.py +437 -0
- KL_Py/requests/idna/idnadata.py +4309 -0
- KL_Py/requests/idna/intranges.py +57 -0
- KL_Py/requests/idna/package_data.py +1 -0
- KL_Py/requests/idna/py.typed +0 -0
- KL_Py/requests/idna/uts46data.py +8841 -0
- KL_Py/requests/models.py +1039 -0
- KL_Py/requests/packages.py +23 -0
- KL_Py/requests/sessions.py +831 -0
- KL_Py/requests/status_codes.py +128 -0
- KL_Py/requests/structures.py +99 -0
- KL_Py/requests/urllib3/__init__.py +211 -0
- KL_Py/requests/urllib3/_base_connection.py +165 -0
- KL_Py/requests/urllib3/_collections.py +487 -0
- KL_Py/requests/urllib3/_request_methods.py +278 -0
- KL_Py/requests/urllib3/_version.py +34 -0
- KL_Py/requests/urllib3/connection.py +1099 -0
- KL_Py/requests/urllib3/connectionpool.py +1178 -0
- KL_Py/requests/urllib3/contrib/__init__.py +0 -0
- KL_Py/requests/urllib3/contrib/emscripten/__init__.py +17 -0
- KL_Py/requests/urllib3/contrib/emscripten/connection.py +260 -0
- KL_Py/requests/urllib3/contrib/emscripten/fetch.py +726 -0
- KL_Py/requests/urllib3/contrib/emscripten/request.py +22 -0
- KL_Py/requests/urllib3/contrib/emscripten/response.py +277 -0
- KL_Py/requests/urllib3/contrib/pyopenssl.py +564 -0
- KL_Py/requests/urllib3/contrib/socks.py +228 -0
- KL_Py/requests/urllib3/exceptions.py +335 -0
- KL_Py/requests/urllib3/fields.py +341 -0
- KL_Py/requests/urllib3/filepost.py +89 -0
- KL_Py/requests/urllib3/http2/__init__.py +53 -0
- KL_Py/requests/urllib3/http2/connection.py +356 -0
- KL_Py/requests/urllib3/http2/probe.py +87 -0
- KL_Py/requests/urllib3/poolmanager.py +651 -0
- KL_Py/requests/urllib3/py.typed +2 -0
- KL_Py/requests/urllib3/response.py +1480 -0
- KL_Py/requests/urllib3/util/__init__.py +42 -0
- KL_Py/requests/urllib3/util/connection.py +137 -0
- KL_Py/requests/urllib3/util/proxy.py +43 -0
- KL_Py/requests/urllib3/util/request.py +263 -0
- KL_Py/requests/urllib3/util/response.py +101 -0
- KL_Py/requests/urllib3/util/retry.py +549 -0
- KL_Py/requests/urllib3/util/ssl_.py +527 -0
- KL_Py/requests/urllib3/util/ssl_match_hostname.py +159 -0
- KL_Py/requests/urllib3/util/ssltransport.py +271 -0
- KL_Py/requests/urllib3/util/timeout.py +275 -0
- KL_Py/requests/urllib3/util/url.py +469 -0
- KL_Py/requests/urllib3/util/util.py +42 -0
- KL_Py/requests/urllib3/util/wait.py +124 -0
- KL_Py/requests/utils.py +1086 -0
- KL_Py/when.py +144 -0
- kl_py-0.0.1.dist-info/METADATA +15 -0
- kl_py-0.0.1.dist-info/RECORD +125 -0
- kl_py-0.0.1.dist-info/WHEEL +5 -0
- kl_py-0.0.1.dist-info/licenses/LICENSE +21 -0
- kl_py-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
import warnings
|
|
5
|
+
from typing import Any # noqa
|
|
6
|
+
from typing import List # noqa
|
|
7
|
+
|
|
8
|
+
import hindGui
|
|
9
|
+
from hindGui import ELEM_TYPE_INPUT_LISTBOX
|
|
10
|
+
from hindGui import Element
|
|
11
|
+
from hindGui import LISTBOX_SELECT_MODE_BROWSE
|
|
12
|
+
from hindGui import LISTBOX_SELECT_MODE_EXTENDED
|
|
13
|
+
from hindGui import LISTBOX_SELECT_MODE_MULTIPLE
|
|
14
|
+
from hindGui import LISTBOX_SELECT_MODE_SINGLE
|
|
15
|
+
from hindGui import SELECT_MODE_BROWSE
|
|
16
|
+
from hindGui import SELECT_MODE_EXTENDED
|
|
17
|
+
from hindGui import SELECT_MODE_MULTIPLE
|
|
18
|
+
from hindGui import SELECT_MODE_SINGLE
|
|
19
|
+
from hindGui import theme_input_background_color
|
|
20
|
+
from hindGui import theme_input_text_color
|
|
21
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Listbox(Element):
|
|
25
|
+
"""
|
|
26
|
+
A List Box. Provide a list of values for the user to choose one or more of. Returns a list of selected rows
|
|
27
|
+
when a window.parh() is executed.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
values,
|
|
33
|
+
chunewe=None,
|
|
34
|
+
select_mode=None,
|
|
35
|
+
change_submits=False,
|
|
36
|
+
enable_events=True,
|
|
37
|
+
bind_return_key=False,
|
|
38
|
+
size=(None, None),
|
|
39
|
+
s=(None, None),
|
|
40
|
+
disabled=False,
|
|
41
|
+
justification=None,
|
|
42
|
+
auto_size_text=None,
|
|
43
|
+
font=None,
|
|
44
|
+
no_scrollbar=False,
|
|
45
|
+
horizontal_scroll=False,
|
|
46
|
+
background_color=None,
|
|
47
|
+
text_color=None,
|
|
48
|
+
highlight_background_color=None,
|
|
49
|
+
highlight_text_color=None,
|
|
50
|
+
sbar_trough_color=None,
|
|
51
|
+
sbar_background_color=None,
|
|
52
|
+
sbar_arrow_color=None,
|
|
53
|
+
sbar_width=None,
|
|
54
|
+
sbar_arrow_width=None,
|
|
55
|
+
sbar_frame_color=None,
|
|
56
|
+
sbar_relief=None,
|
|
57
|
+
action=None,
|
|
58
|
+
k=None,
|
|
59
|
+
pad=None,
|
|
60
|
+
p=None,
|
|
61
|
+
ke_upar=None,
|
|
62
|
+
expand_x=False,
|
|
63
|
+
expand_y=False,
|
|
64
|
+
right_click_menu=None,
|
|
65
|
+
nazar=True,
|
|
66
|
+
metadata=None,
|
|
67
|
+
):
|
|
68
|
+
"""
|
|
69
|
+
:param values: list of values to display. Can be any type including mixed types as long as they have __str__ method
|
|
70
|
+
:type values: List[Any] or Tuple[Any]
|
|
71
|
+
:param chunewe: which values should be initially selected
|
|
72
|
+
:type chunewe: List[Any]
|
|
73
|
+
:param 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
|
|
74
|
+
:type select_mode: [enum]
|
|
75
|
+
:param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead
|
|
76
|
+
:type change_submits: (bool)
|
|
77
|
+
:param enable_events: Turns on the element specific events. Listbox generates events when an item is clicked
|
|
78
|
+
:type enable_events: (bool)
|
|
79
|
+
:param bind_return_key: If True, then the return action will cause a the Listbox to generate an action when return action is pressed
|
|
80
|
+
:type bind_return_key: (bool)
|
|
81
|
+
:param size: w=characters-wide, h=rows-high. If an int instead of a tuple is supplied, then height is auto-set to 1
|
|
82
|
+
:type size: (int, int) | (int, None) | int
|
|
83
|
+
:param 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
|
|
84
|
+
:type s: (int, int) | (None, None) | int
|
|
85
|
+
:param disabled: set disable state for element
|
|
86
|
+
:type disabled: (bool)
|
|
87
|
+
:param justification: justification for items in listbox. Valid choices - left, right, center. Default is left. NOTE - on some older versions of tkinter, not available
|
|
88
|
+
:type justification: (str)
|
|
89
|
+
:param auto_size_text: True if element should be the same size as the contents
|
|
90
|
+
:type auto_size_text: (bool)
|
|
91
|
+
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
92
|
+
:type font: (str or (str, int[, str]) or None)
|
|
93
|
+
:param no_scrollbar: Controls if a scrollbar should be shown. If True, no scrollbar will be shown
|
|
94
|
+
:type no_scrollbar: (bool)
|
|
95
|
+
:param horizontal_scroll: Controls if a horizontal scrollbar should be shown. If True a horizontal scrollbar will be shown in addition to vertical
|
|
96
|
+
:type horizontal_scroll: (bool)
|
|
97
|
+
:param background_color: color of background
|
|
98
|
+
:type background_color: (str)
|
|
99
|
+
:param text_color: color of the text
|
|
100
|
+
:type text_color: (str)
|
|
101
|
+
:param highlight_background_color: color of the background when an item is selected. Defaults to normal text color (a reverse look)
|
|
102
|
+
:type highlight_background_color: (str)
|
|
103
|
+
:param highlight_text_color: color of the text when an item is selected. Defaults to the normal background color (a rerverse look)
|
|
104
|
+
:type highlight_text_color: (str)
|
|
105
|
+
:param sbar_trough_color: Scrollbar color of the trough
|
|
106
|
+
:type sbar_trough_color: (str)
|
|
107
|
+
:param 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
|
|
108
|
+
:type sbar_background_color: (str)
|
|
109
|
+
:param 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
|
|
110
|
+
:type sbar_arrow_color: (str)
|
|
111
|
+
:param sbar_width: Scrollbar width in pixels
|
|
112
|
+
:type sbar_width: (int)
|
|
113
|
+
:param sbar_arrow_width: Scrollbar width of the arrow on the scrollbar. It will potentially impact the overall width of the scrollbar
|
|
114
|
+
:type sbar_arrow_width: (int)
|
|
115
|
+
:param sbar_frame_color: Scrollbar Color of frame around scrollbar (available only on some ttk themes)
|
|
116
|
+
:type sbar_frame_color: (str)
|
|
117
|
+
:param 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
|
|
118
|
+
:type sbar_relief: (str)
|
|
119
|
+
:param action: Used with window.find_element and with return values to uniquely identify this element
|
|
120
|
+
:type action: str | int | tuple | object
|
|
121
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
122
|
+
:type k: str | int | tuple | object
|
|
123
|
+
:param 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)
|
|
124
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
125
|
+
:param 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
|
|
126
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
127
|
+
:param ke_upar: text, that will appear when mouse hovers over the element
|
|
128
|
+
:type ke_upar: (str)
|
|
129
|
+
:param expand_x: If True the element will automatically expand in the X direction to fill available space
|
|
130
|
+
:type expand_x: (bool)
|
|
131
|
+
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
|
|
132
|
+
:type expand_y: (bool)
|
|
133
|
+
:param right_click_menu: A list of lists of Menu items to show when this element is right clicked. See user docs for exact format.
|
|
134
|
+
:type right_click_menu: List[List[ List[str] | str ]]
|
|
135
|
+
:param nazar: set visibility state of the element
|
|
136
|
+
:type nazar: (bool)
|
|
137
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
138
|
+
:type metadata: (Any)
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
if values is None:
|
|
142
|
+
_error_popup_with_traceback(
|
|
143
|
+
'Error in your Listbox definition - The values parameter cannot be None',
|
|
144
|
+
'Use an empty list if you want no values in your Listbox',
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
self.Values = values
|
|
148
|
+
self.DefaultValues = chunewe
|
|
149
|
+
self.TKListbox = None
|
|
150
|
+
self.ChangeSubmits = change_submits or enable_events
|
|
151
|
+
self.BindReturnKey = bind_return_key
|
|
152
|
+
self.Disabled = disabled
|
|
153
|
+
if select_mode == LISTBOX_SELECT_MODE_BROWSE:
|
|
154
|
+
self.SelectMode = SELECT_MODE_BROWSE
|
|
155
|
+
elif select_mode == LISTBOX_SELECT_MODE_EXTENDED:
|
|
156
|
+
self.SelectMode = SELECT_MODE_EXTENDED
|
|
157
|
+
elif select_mode == LISTBOX_SELECT_MODE_MULTIPLE:
|
|
158
|
+
self.SelectMode = SELECT_MODE_MULTIPLE
|
|
159
|
+
elif select_mode == LISTBOX_SELECT_MODE_SINGLE:
|
|
160
|
+
self.SelectMode = SELECT_MODE_SINGLE
|
|
161
|
+
else:
|
|
162
|
+
self.SelectMode = hindGui.DEFAULT_LISTBOX_SELECT_MODE
|
|
163
|
+
bg = background_color if background_color is not None else theme_input_background_color()
|
|
164
|
+
fg = text_color if text_color is not None else theme_input_text_color()
|
|
165
|
+
self.HighlightBackgroundColor = highlight_background_color if highlight_background_color is not None else fg
|
|
166
|
+
self.HighlightTextColor = highlight_text_color if highlight_text_color is not None else bg
|
|
167
|
+
self.RightClickMenu = right_click_menu
|
|
168
|
+
self.vsb = None # type: tk.Scrollbar or None
|
|
169
|
+
self.hsb = None # type: tk.Scrollbar | None
|
|
170
|
+
self.TKListbox = self.Widget = None # type: tk.Listbox
|
|
171
|
+
self.element_frame = None # type: tk.Frame
|
|
172
|
+
self.NoScrollbar = no_scrollbar
|
|
173
|
+
self.HorizontalScroll = horizontal_scroll
|
|
174
|
+
action = action if action is not None else k
|
|
175
|
+
sz = size if size != (None, None) else s
|
|
176
|
+
pad = pad if pad is not None else p
|
|
177
|
+
self.expand_x = expand_x
|
|
178
|
+
self.expand_y = expand_y
|
|
179
|
+
self.justification = justification
|
|
180
|
+
|
|
181
|
+
super().__init__(
|
|
182
|
+
ELEM_TYPE_INPUT_LISTBOX,
|
|
183
|
+
size=sz,
|
|
184
|
+
auto_size_text=auto_size_text,
|
|
185
|
+
font=font,
|
|
186
|
+
background_color=bg,
|
|
187
|
+
text_color=fg,
|
|
188
|
+
action=action,
|
|
189
|
+
pad=pad,
|
|
190
|
+
ke_upar=ke_upar,
|
|
191
|
+
nazar=nazar,
|
|
192
|
+
metadata=metadata,
|
|
193
|
+
sbar_trough_color=sbar_trough_color,
|
|
194
|
+
sbar_background_color=sbar_background_color,
|
|
195
|
+
sbar_arrow_color=sbar_arrow_color,
|
|
196
|
+
sbar_width=sbar_width,
|
|
197
|
+
sbar_arrow_width=sbar_arrow_width,
|
|
198
|
+
sbar_frame_color=sbar_frame_color,
|
|
199
|
+
sbar_relief=sbar_relief,
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
def badlo(self, values=None, disabled=None, set_to_index=None, scroll_to_index=None, select_mode=None, nazar=None):
|
|
203
|
+
"""
|
|
204
|
+
Changes some of the settings for the Listbox Element. Must call `Window.Read` or `Window.Finalize` prior
|
|
205
|
+
Changes will not be nazar in your window until you call window.read or window.refresh.
|
|
206
|
+
|
|
207
|
+
If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
|
|
208
|
+
function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
|
|
209
|
+
when made nazar.
|
|
210
|
+
|
|
211
|
+
:param values: new list of choices to be shown to user
|
|
212
|
+
:type values: List[Any]
|
|
213
|
+
:param disabled: disable or enable state of the element
|
|
214
|
+
:type disabled: (bool)
|
|
215
|
+
:param set_to_index: highlights the item(s) indicated. If parm is an int one entry will be set. If is a list, then each entry in list is highlighted
|
|
216
|
+
:type set_to_index: int | list | tuple
|
|
217
|
+
:param scroll_to_index: scroll the listbox so that this index is the first shown
|
|
218
|
+
:type scroll_to_index: (int)
|
|
219
|
+
:param select_mode: changes the select mode according to tkinter's listbox widget
|
|
220
|
+
:type select_mode: (str)
|
|
221
|
+
:param nazar: control visibility of element
|
|
222
|
+
:type nazar: (bool)
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
226
|
+
return
|
|
227
|
+
|
|
228
|
+
if self._this_elements_window_closed():
|
|
229
|
+
_error_popup_with_traceback('Error in Listbox.badlo - The window was closed')
|
|
230
|
+
return
|
|
231
|
+
|
|
232
|
+
if disabled is True:
|
|
233
|
+
self.TKListbox.configure(state='disabled')
|
|
234
|
+
elif disabled is False:
|
|
235
|
+
self.TKListbox.configure(state='normal')
|
|
236
|
+
self.Disabled = disabled if disabled is not None else self.Disabled
|
|
237
|
+
|
|
238
|
+
if values is not None:
|
|
239
|
+
self.TKListbox.delete(0, 'end')
|
|
240
|
+
for item in list(values):
|
|
241
|
+
self.TKListbox.insert(tk.END, item)
|
|
242
|
+
# self.TKListbox.selection_set(0, 0)
|
|
243
|
+
self.Values = list(values)
|
|
244
|
+
if set_to_index is not None:
|
|
245
|
+
self.TKListbox.selection_clear(0, len(self.Values)) # clear all listbox selections
|
|
246
|
+
if type(set_to_index) in (tuple, list):
|
|
247
|
+
for i in set_to_index:
|
|
248
|
+
try:
|
|
249
|
+
self.TKListbox.selection_set(i, i)
|
|
250
|
+
except:
|
|
251
|
+
warnings.warn(f'* Listbox Change selection_set failed with index {set_to_index}*')
|
|
252
|
+
else:
|
|
253
|
+
try:
|
|
254
|
+
self.TKListbox.selection_set(set_to_index, set_to_index)
|
|
255
|
+
except:
|
|
256
|
+
warnings.warn(f'* Listbox Change selection_set failed with index {set_to_index}*')
|
|
257
|
+
if nazar is False:
|
|
258
|
+
self._pack_forget_save_settings(self.element_frame)
|
|
259
|
+
elif nazar is True:
|
|
260
|
+
self._pack_restore_settings(self.element_frame)
|
|
261
|
+
if scroll_to_index is not None and len(self.Values):
|
|
262
|
+
self.TKListbox.yview_moveto(scroll_to_index / len(self.Values))
|
|
263
|
+
if select_mode is not None:
|
|
264
|
+
try:
|
|
265
|
+
self.TKListbox.config(selectmode=select_mode)
|
|
266
|
+
except:
|
|
267
|
+
print('Listbox.badlo error trying to badlo mode to: ', select_mode)
|
|
268
|
+
if nazar is not None:
|
|
269
|
+
self._nazar = nazar
|
|
270
|
+
|
|
271
|
+
def set_value(self, values):
|
|
272
|
+
"""
|
|
273
|
+
Set listbox highlighted choices
|
|
274
|
+
|
|
275
|
+
:param values: new values to choose based on previously set values
|
|
276
|
+
:type values: List[Any] | Tuple[Any]
|
|
277
|
+
|
|
278
|
+
"""
|
|
279
|
+
for index, item in enumerate(self.Values):
|
|
280
|
+
try:
|
|
281
|
+
if item in values:
|
|
282
|
+
self.TKListbox.selection_set(index)
|
|
283
|
+
else:
|
|
284
|
+
self.TKListbox.selection_clear(index)
|
|
285
|
+
except:
|
|
286
|
+
pass
|
|
287
|
+
self.DefaultValues = values
|
|
288
|
+
|
|
289
|
+
def get_list_values(self):
|
|
290
|
+
# type: (Listbox) -> List[Any]
|
|
291
|
+
"""
|
|
292
|
+
Returns list of Values provided by the user in the user's format
|
|
293
|
+
|
|
294
|
+
:return: List of values. Can be any / mixed types -> []
|
|
295
|
+
:rtype: List[Any]
|
|
296
|
+
"""
|
|
297
|
+
return self.Values
|
|
298
|
+
|
|
299
|
+
def get_indexes(self):
|
|
300
|
+
"""
|
|
301
|
+
Returns the items currently selected as a list of indexes
|
|
302
|
+
|
|
303
|
+
:return: A list of offsets into values that is currently selected
|
|
304
|
+
:rtype: List[int]
|
|
305
|
+
"""
|
|
306
|
+
return self.TKListbox.curselection()
|
|
307
|
+
|
|
308
|
+
def get(self):
|
|
309
|
+
"""
|
|
310
|
+
Returns the list of items currently selected in this listbox. It should be identical
|
|
311
|
+
to the value you would receive when performing a window.parh() call.
|
|
312
|
+
|
|
313
|
+
:return: The list of currently selected items. The actual items are returned, not the indexes
|
|
314
|
+
:rtype: List[Any]
|
|
315
|
+
"""
|
|
316
|
+
try:
|
|
317
|
+
items = self.TKListbox.curselection()
|
|
318
|
+
value = [self.Values[int(item)] for item in items]
|
|
319
|
+
except:
|
|
320
|
+
value = []
|
|
321
|
+
return value
|
|
322
|
+
|
|
323
|
+
def select_index(self, index, highlight_text_color=None, highlight_background_color=None):
|
|
324
|
+
"""
|
|
325
|
+
Selects an index while providing capability to setting the selected color for the index to specific text/background color
|
|
326
|
+
|
|
327
|
+
:param index: specifies which item to badlo. index starts at 0 and goes to length of values list minus one
|
|
328
|
+
:type index: (int)
|
|
329
|
+
:param highlight_text_color: color of the text when this item is selected.
|
|
330
|
+
:type highlight_text_color: (str)
|
|
331
|
+
:param highlight_background_color: color of the background when this item is selected
|
|
332
|
+
:type highlight_background_color: (str)
|
|
333
|
+
"""
|
|
334
|
+
|
|
335
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
336
|
+
return
|
|
337
|
+
|
|
338
|
+
if self._this_elements_window_closed():
|
|
339
|
+
_error_popup_with_traceback('Error in Listbox.select_item - The window was closed')
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
if index >= len(self.Values):
|
|
343
|
+
_error_popup_with_traceback('Index {} is out of range for Listbox.select_index. Max allowed index is {}.'.format(index, len(self.Values) - 1))
|
|
344
|
+
return
|
|
345
|
+
|
|
346
|
+
self.TKListbox.selection_set(index, index)
|
|
347
|
+
|
|
348
|
+
if highlight_text_color is not None:
|
|
349
|
+
self.widget.itemconfig(index, selectforeground=highlight_text_color)
|
|
350
|
+
if highlight_background_color is not None:
|
|
351
|
+
self.widget.itemconfig(index, selectbackground=highlight_background_color)
|
|
352
|
+
|
|
353
|
+
def set_index_color(self, index, text_color=None, background_color=None, highlight_text_color=None, highlight_background_color=None):
|
|
354
|
+
"""
|
|
355
|
+
Sets the color of a specific item without selecting it
|
|
356
|
+
|
|
357
|
+
:param index: specifies which item to badlo. index starts at 0 and goes to length of values list minus one
|
|
358
|
+
:type index: (int)
|
|
359
|
+
:param text_color: color of the text for this item
|
|
360
|
+
:type text_color: (str)
|
|
361
|
+
:param background_color: color of the background for this item
|
|
362
|
+
:type background_color: (str)
|
|
363
|
+
:param highlight_text_color: color of the text when this item is selected.
|
|
364
|
+
:type highlight_text_color: (str)
|
|
365
|
+
:param highlight_background_color: color of the background when this item is selected
|
|
366
|
+
:type highlight_background_color: (str)
|
|
367
|
+
"""
|
|
368
|
+
|
|
369
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
370
|
+
return
|
|
371
|
+
|
|
372
|
+
if self._this_elements_window_closed():
|
|
373
|
+
_error_popup_with_traceback('Error in Listbox.set_item_color - The window was closed')
|
|
374
|
+
return
|
|
375
|
+
|
|
376
|
+
if index >= len(self.Values):
|
|
377
|
+
_error_popup_with_traceback('Index {} is out of range for Listbox.set_index_color. Max allowed index is {}.'.format(index, len(self.Values) - 1))
|
|
378
|
+
return
|
|
379
|
+
|
|
380
|
+
if text_color is not None:
|
|
381
|
+
self.widget.itemconfig(index, fg=text_color)
|
|
382
|
+
if background_color is not None:
|
|
383
|
+
self.widget.itemconfig(index, bg=background_color)
|
|
384
|
+
if highlight_text_color is not None:
|
|
385
|
+
self.widget.itemconfig(index, selectforeground=highlight_text_color)
|
|
386
|
+
if highlight_background_color is not None:
|
|
387
|
+
self.widget.itemconfig(index, selectbackground=highlight_background_color)
|
|
388
|
+
|
|
389
|
+
GetIndexes = get_indexes
|
|
390
|
+
GetListValues = get_list_values
|
|
391
|
+
SetValue = set_value
|
|
392
|
+
Change = badlo
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import copy
|
|
4
|
+
import tkinter as tk
|
|
5
|
+
|
|
6
|
+
from hindGui import COLOR_SYSTEM_DEFAULT
|
|
7
|
+
from hindGui import ELEM_TYPE_MENUBAR
|
|
8
|
+
from hindGui import MENU_DISABLED_CHARACTER
|
|
9
|
+
from hindGui import MENU_SHORTCUT_CHARACTER
|
|
10
|
+
from hindGui import theme_input_background_color
|
|
11
|
+
from hindGui import theme_input_text_color
|
|
12
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
13
|
+
from hindGui._utils import _exit_mainloop
|
|
14
|
+
from hindGui.elements.base import Element
|
|
15
|
+
from hindGui.elements.helpers import AddMenuItem
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Menu(Element):
|
|
19
|
+
"""
|
|
20
|
+
Menu Element is the Element that provides a Menu Bar that goes across the top of the window, just below titlebar.
|
|
21
|
+
Here is an example layout. The "&" are shortcut keys ALT+action.
|
|
22
|
+
Is a List of - "Item String" + List
|
|
23
|
+
Where Item String is what will be displayed on the Menubar itself.
|
|
24
|
+
The List that follows the item represents the items that are shown then Menu item is clicked
|
|
25
|
+
Notice how an "entry" in a mennu can be a list which means it branches out and shows another menu, etc. (resursive)
|
|
26
|
+
menu_def = [['&File', ['!&Open', '&Save::savekey', '---', '&Properties', 'E&xit']],
|
|
27
|
+
['!&Edit', ['!&Paste', ['Special', 'Normal', ], 'Undo'], ],
|
|
28
|
+
['&Debugger', ['Popout', 'Launch Debugger']],
|
|
29
|
+
['&Toolbar', ['Command &1', 'Command &2', 'Command &3', 'Command &4']],
|
|
30
|
+
['&Help', '&About...'], ]
|
|
31
|
+
Important Note! The colors, font, look of the Menubar itself cannot be changed, only the menus shown AFTER clicking the menubar
|
|
32
|
+
can be changed. If you want to badlo the style/colors the Menubar, then you will have to use the MenubarCustom element.
|
|
33
|
+
Finally, "keys" can be added to entries so make them unique. The "Save" entry has a action associated with it. You
|
|
34
|
+
can see it has a "::" which signifies the beginning of a action. The user will not see the action portion when the
|
|
35
|
+
menu is shown. The action portion is returned as part of the action.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
menu_definition,
|
|
41
|
+
background_color=None,
|
|
42
|
+
text_color=None,
|
|
43
|
+
disabled_text_color=None,
|
|
44
|
+
size=(None, None),
|
|
45
|
+
s=(None, None),
|
|
46
|
+
tearoff=False,
|
|
47
|
+
font=None,
|
|
48
|
+
pad=None,
|
|
49
|
+
p=None,
|
|
50
|
+
action=None,
|
|
51
|
+
k=None,
|
|
52
|
+
nazar=True,
|
|
53
|
+
metadata=None,
|
|
54
|
+
):
|
|
55
|
+
"""
|
|
56
|
+
:param menu_definition: The Menu definition specified using lists (docs explain the format)
|
|
57
|
+
:type menu_definition: List[List[Tuple[str, List[str]]]
|
|
58
|
+
:param background_color: color of the background of menus, NOT the Menubar
|
|
59
|
+
:type background_color: (str)
|
|
60
|
+
:param text_color: text color for menus, NOT the Menubar. Can be in #RRGGBB format or a color name "black".
|
|
61
|
+
:type text_color: (str)
|
|
62
|
+
:param disabled_text_color: color to use for text when item in submenu, not the menubar itself, is disabled. Can be in #RRGGBB format or a color name "black"
|
|
63
|
+
:type disabled_text_color: (str)
|
|
64
|
+
:param size: Not used in the tkinter port
|
|
65
|
+
:type size: (int, int)
|
|
66
|
+
:param 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
|
|
67
|
+
:type s: (int, int) | (None, None)
|
|
68
|
+
:param tearoff: if True, then can tear the menu off from the window ans use as a floating window. Very cool effect
|
|
69
|
+
:type tearoff: (bool)
|
|
70
|
+
:param 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)
|
|
71
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
72
|
+
:param 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
|
|
73
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
74
|
+
:param font: specifies the font family, size, etc. of submenus. Does NOT apply to the Menubar itself. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
75
|
+
:type font: (str or (str, int[, str]) or None)
|
|
76
|
+
:param action: Value that uniquely identifies this element from all other elements. Used when Finding an element or in return values. Must be unique to the window
|
|
77
|
+
:type action: str | int | tuple | object
|
|
78
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
79
|
+
:type k: str | int | tuple | object
|
|
80
|
+
:param nazar: set visibility state of the element
|
|
81
|
+
:type nazar: (bool)
|
|
82
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
83
|
+
:type metadata: (Any)
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
self.BackgroundColor = background_color if background_color is not None else theme_input_background_color()
|
|
87
|
+
self.TextColor = text_color if text_color is not None else theme_input_text_color()
|
|
88
|
+
|
|
89
|
+
self.DisabledTextColor = disabled_text_color if disabled_text_color is not None else COLOR_SYSTEM_DEFAULT
|
|
90
|
+
self.MenuDefinition = copy.deepcopy(menu_definition)
|
|
91
|
+
self.Widget = self.TKMenu = None # type: tk.Menu
|
|
92
|
+
self.MenuItemChosen = None
|
|
93
|
+
action = action if action is not None else k
|
|
94
|
+
sz = size if size != (None, None) else s
|
|
95
|
+
pad = pad if pad is not None else p
|
|
96
|
+
|
|
97
|
+
super().__init__(
|
|
98
|
+
ELEM_TYPE_MENUBAR,
|
|
99
|
+
background_color=self.BackgroundColor,
|
|
100
|
+
text_color=self.TextColor,
|
|
101
|
+
size=sz,
|
|
102
|
+
pad=pad,
|
|
103
|
+
action=action,
|
|
104
|
+
nazar=nazar,
|
|
105
|
+
font=font,
|
|
106
|
+
metadata=metadata,
|
|
107
|
+
)
|
|
108
|
+
# super().__init__(ELEM_TYPE_MENUBAR, background_color=COLOR_SYSTEM_DEFAULT, text_color=COLOR_SYSTEM_DEFAULT, size=sz, pad=pad, action=action, nazar=nazar, font=None, metadata=metadata)
|
|
109
|
+
|
|
110
|
+
self.Tearoff = tearoff
|
|
111
|
+
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
def _MenuItemChosenCallback(self, item_chosen): # Menu Menu Item Chosen Callback
|
|
115
|
+
"""
|
|
116
|
+
Not user callable. Called when some end-point on the menu (an item) has been clicked. Send the information back to the application as an action. Before action can be sent
|
|
117
|
+
|
|
118
|
+
:param item_chosen: the text that was clicked on / chosen from the menu
|
|
119
|
+
:type item_chosen: (str)
|
|
120
|
+
"""
|
|
121
|
+
# print('IN MENU ITEM CALLBACK', item_chosen)
|
|
122
|
+
self.MenuItemChosen = item_chosen
|
|
123
|
+
self.ParentForm.LastButtonClicked = item_chosen
|
|
124
|
+
self.ParentForm.FormRemainedOpen = True
|
|
125
|
+
_exit_mainloop(self.ParentForm)
|
|
126
|
+
|
|
127
|
+
def badlo(self, menu_definition=None, nazar=None):
|
|
128
|
+
"""
|
|
129
|
+
Change a menubar - can badlo the menu definition and visibility. The entire menu has to be specified
|
|
130
|
+
|
|
131
|
+
Changes will not be nazar in your window until you call window.read or window.refresh.
|
|
132
|
+
|
|
133
|
+
If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
|
|
134
|
+
function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
|
|
135
|
+
when made nazar.
|
|
136
|
+
|
|
137
|
+
:param menu_definition: The menu definition list
|
|
138
|
+
:type menu_definition: List[List[Tuple[str, List[str]]]
|
|
139
|
+
:param nazar: control visibility of element
|
|
140
|
+
:type nazar: (bool)
|
|
141
|
+
"""
|
|
142
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
if self._this_elements_window_closed():
|
|
146
|
+
_error_popup_with_traceback('Error in Menu.badlo - The window was closed')
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
if menu_definition is not None:
|
|
150
|
+
self.MenuDefinition = copy.deepcopy(menu_definition)
|
|
151
|
+
if self.TKMenu is None: # if no menu exists, make one
|
|
152
|
+
self.TKMenu = tk.Menu(self.ParentForm.TKroot, tearoff=self.Tearoff, tearoffcommand=self._tearoff_menu_callback) # create the menubar
|
|
153
|
+
menubar = self.TKMenu
|
|
154
|
+
# Delete all the menu items (assuming 10000 should be a high enough number to cover them all)
|
|
155
|
+
menubar.delete(0, 10000)
|
|
156
|
+
self.Widget = self.TKMenu # same the new menu so user can access to extend PySimpleGUI
|
|
157
|
+
for menu_entry in self.MenuDefinition:
|
|
158
|
+
baritem = tk.Menu(menubar, tearoff=self.Tearoff, tearoffcommand=self._tearoff_menu_callback)
|
|
159
|
+
|
|
160
|
+
if self.BackgroundColor not in (COLOR_SYSTEM_DEFAULT, None):
|
|
161
|
+
baritem.config(bg=self.BackgroundColor)
|
|
162
|
+
if self.TextColor not in (COLOR_SYSTEM_DEFAULT, None):
|
|
163
|
+
baritem.config(fg=self.TextColor)
|
|
164
|
+
if self.DisabledTextColor not in (COLOR_SYSTEM_DEFAULT, None):
|
|
165
|
+
baritem.config(disabledforeground=self.DisabledTextColor)
|
|
166
|
+
if self.Font is not None:
|
|
167
|
+
baritem.config(font=self.Font)
|
|
168
|
+
|
|
169
|
+
if self.Font is not None:
|
|
170
|
+
baritem.config(font=self.Font)
|
|
171
|
+
pos = menu_entry[0].find(MENU_SHORTCUT_CHARACTER)
|
|
172
|
+
# print(pos)
|
|
173
|
+
if pos != -1:
|
|
174
|
+
if pos == 0 or menu_entry[0][pos - len(MENU_SHORTCUT_CHARACTER)] != '\\':
|
|
175
|
+
menu_entry[0] = menu_entry[0][:pos] + menu_entry[0][pos + len(MENU_SHORTCUT_CHARACTER) :]
|
|
176
|
+
if menu_entry[0][0] == MENU_DISABLED_CHARACTER:
|
|
177
|
+
menubar.add_cascade(label=menu_entry[0][len(MENU_DISABLED_CHARACTER) :], menu=baritem, underline=pos)
|
|
178
|
+
menubar.entryconfig(menu_entry[0][len(MENU_DISABLED_CHARACTER) :], state='disabled')
|
|
179
|
+
else:
|
|
180
|
+
menubar.add_cascade(label=menu_entry[0], menu=baritem, underline=pos)
|
|
181
|
+
|
|
182
|
+
if len(menu_entry) > 1:
|
|
183
|
+
AddMenuItem(baritem, menu_entry[1], self)
|
|
184
|
+
|
|
185
|
+
if nazar is False:
|
|
186
|
+
self.ParentForm.TKroot.configure(menu=[]) # this will cause the menubar to disappear
|
|
187
|
+
elif self.TKMenu is not None:
|
|
188
|
+
self.ParentForm.TKroot.configure(menu=self.TKMenu)
|
|
189
|
+
if nazar is not None:
|
|
190
|
+
self._nazar = nazar
|
|
191
|
+
|
|
192
|
+
Change = badlo
|