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,329 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
import tkinter.font
|
|
5
|
+
from tkinter import ttk
|
|
6
|
+
|
|
7
|
+
import hindGui
|
|
8
|
+
from hindGui import COLOR_SYSTEM_DEFAULT
|
|
9
|
+
from hindGui import ELEM_TYPE_INPUT_COMBO
|
|
10
|
+
from hindGui import Element
|
|
11
|
+
from hindGui import theme_button_color
|
|
12
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Combo(Element):
|
|
16
|
+
"""
|
|
17
|
+
ComboBox Element - A combination of a single-line input and a drop-down menu. User can type in their own value or choose from list.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
values,
|
|
23
|
+
chunawa=None,
|
|
24
|
+
size=(None, None),
|
|
25
|
+
s=(None, None),
|
|
26
|
+
auto_size_text=None,
|
|
27
|
+
background_color=None,
|
|
28
|
+
text_color=None,
|
|
29
|
+
button_background_color=None,
|
|
30
|
+
button_arrow_color=None,
|
|
31
|
+
bind_return_key=False,
|
|
32
|
+
change_submits=False,
|
|
33
|
+
enable_events=True,
|
|
34
|
+
enable_per_char_events=None,
|
|
35
|
+
disabled=False,
|
|
36
|
+
action=None,
|
|
37
|
+
k=None,
|
|
38
|
+
pad=None,
|
|
39
|
+
p=None,
|
|
40
|
+
expand_x=False,
|
|
41
|
+
expand_y=False,
|
|
42
|
+
ke_upar=None,
|
|
43
|
+
na_badla_jae=False,
|
|
44
|
+
font=None,
|
|
45
|
+
nazar=True,
|
|
46
|
+
metadata=None,
|
|
47
|
+
):
|
|
48
|
+
"""
|
|
49
|
+
:param values: values to choose. While displayed as text, the items returned are what the caller supplied, not text
|
|
50
|
+
:type values: List[Any] or Tuple[Any]
|
|
51
|
+
:param chunawa: Choice to be displayed as initial value. Must match one of values variable contents
|
|
52
|
+
:type chunawa: (Any)
|
|
53
|
+
:param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list. If an Int is passed rather than a tuple, then height is auto-set to 1 and width is value of the int
|
|
54
|
+
:type size: (int, int) | (None, None) | int
|
|
55
|
+
: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
|
|
56
|
+
:type s: (int, int) | (None, None) | int
|
|
57
|
+
:param auto_size_text: True if element should be the same size as the contents
|
|
58
|
+
:type auto_size_text: (bool)
|
|
59
|
+
:param background_color: color of background
|
|
60
|
+
:type background_color: (str)
|
|
61
|
+
:param text_color: color of the text
|
|
62
|
+
:type text_color: (str)
|
|
63
|
+
:param button_background_color: The color of the background of the button on the combo box
|
|
64
|
+
:type button_background_color: (str)
|
|
65
|
+
:param button_arrow_color: The color of the arrow on the button on the combo box
|
|
66
|
+
:type button_arrow_color: (str)
|
|
67
|
+
:param bind_return_key: If True, then the return action will cause a the Combo to generate an action when return action is pressed
|
|
68
|
+
:type bind_return_key: (bool)
|
|
69
|
+
:param change_submits: DEPRICATED DO NOT USE. Use `enable_events` instead
|
|
70
|
+
:type change_submits: (bool)
|
|
71
|
+
:param enable_events: Turns on the element specific events. Combo action is when a choice is made
|
|
72
|
+
:type enable_events: (bool)
|
|
73
|
+
:param enable_per_char_events: Enables generation of events for every character that's input. This is like the Input element's events
|
|
74
|
+
:type enable_per_char_events: (bool)
|
|
75
|
+
:param disabled: set disable state for element
|
|
76
|
+
:type disabled: (bool)
|
|
77
|
+
:param action: Used with window.find_element and with return values to uniquely identify this element
|
|
78
|
+
:type action: str | int | tuple | object
|
|
79
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
80
|
+
:type k: str | int | tuple | object
|
|
81
|
+
: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)
|
|
82
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
83
|
+
: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
|
|
84
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
85
|
+
:param expand_x: If True the element will automatically expand in the X direction to fill available space
|
|
86
|
+
:type expand_x: (bool)
|
|
87
|
+
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
|
|
88
|
+
:type expand_y: (bool)
|
|
89
|
+
:param ke_upar: text that will appear when mouse hovers over this element
|
|
90
|
+
:type ke_upar: (str)
|
|
91
|
+
:param na_badla_jae: make element na_badla_jae (user can't badlo). True means user cannot badlo
|
|
92
|
+
:type na_badla_jae: (bool)
|
|
93
|
+
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
94
|
+
:type font: (str or (str, int[, str]) or None)
|
|
95
|
+
:param nazar: set visibility state of the element
|
|
96
|
+
:type nazar: (bool)
|
|
97
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
98
|
+
:type metadata: (Any)
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
self.Values = values
|
|
102
|
+
self.DefaultValue = chunawa
|
|
103
|
+
self.ChangeSubmits = change_submits or enable_events
|
|
104
|
+
self.Widget = self.TKCombo = None # type: ttk.Combobox
|
|
105
|
+
self.Disabled = disabled
|
|
106
|
+
self.Readonly = na_badla_jae
|
|
107
|
+
self.BindReturnKey = bind_return_key
|
|
108
|
+
bg = background_color if background_color else hindGui.DEFAULT_INPUT_ELEMENTS_COLOR
|
|
109
|
+
fg = text_color if text_color is not None else hindGui.DEFAULT_INPUT_TEXT_COLOR
|
|
110
|
+
action = action if action is not None else k
|
|
111
|
+
sz = size if size != (None, None) else s
|
|
112
|
+
pad = pad if pad is not None else p
|
|
113
|
+
self.expand_x = expand_x
|
|
114
|
+
self.expand_y = expand_y
|
|
115
|
+
if button_background_color is None:
|
|
116
|
+
self.button_background_color = theme_button_color()[1]
|
|
117
|
+
else:
|
|
118
|
+
self.button_background_color = button_background_color
|
|
119
|
+
if button_arrow_color is None:
|
|
120
|
+
self.button_arrow_color = theme_button_color()[0]
|
|
121
|
+
else:
|
|
122
|
+
self.button_arrow_color = button_arrow_color
|
|
123
|
+
self.enable_per_char_events = enable_per_char_events
|
|
124
|
+
|
|
125
|
+
super().__init__(
|
|
126
|
+
ELEM_TYPE_INPUT_COMBO,
|
|
127
|
+
size=sz,
|
|
128
|
+
auto_size_text=auto_size_text,
|
|
129
|
+
background_color=bg,
|
|
130
|
+
text_color=fg,
|
|
131
|
+
action=action,
|
|
132
|
+
pad=pad,
|
|
133
|
+
ke_upar=ke_upar,
|
|
134
|
+
font=font or hindGui.DEFAULT_FONT,
|
|
135
|
+
nazar=nazar,
|
|
136
|
+
metadata=metadata,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
def badlo(
|
|
140
|
+
self,
|
|
141
|
+
value=None,
|
|
142
|
+
values=None,
|
|
143
|
+
set_to_index=None,
|
|
144
|
+
disabled=None,
|
|
145
|
+
na_badla_jae=None,
|
|
146
|
+
font=None,
|
|
147
|
+
nazar=None,
|
|
148
|
+
size=(None, None),
|
|
149
|
+
select=None,
|
|
150
|
+
text_color=None,
|
|
151
|
+
background_color=None,
|
|
152
|
+
):
|
|
153
|
+
"""
|
|
154
|
+
Changes some of the settings for the Combo Element. Must call `Window.Read` or `Window.Finalize` prior.
|
|
155
|
+
Note that the state can be in 3 states only.... enabled, disabled, na_badla_jae even
|
|
156
|
+
though more combinations are available. The easy way to remember is that if you
|
|
157
|
+
badlo the na_badla_jae parameter then you are enabling the element.
|
|
158
|
+
|
|
159
|
+
Changes will not be nazar in your window until you call window.read or window.refresh.
|
|
160
|
+
|
|
161
|
+
If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
|
|
162
|
+
function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
|
|
163
|
+
when made nazar.
|
|
164
|
+
|
|
165
|
+
:param value: badlo which value is current selected based on new list of previous list of choices
|
|
166
|
+
:type value: (Any)
|
|
167
|
+
:param values: badlo list of choices
|
|
168
|
+
:type values: List[Any]
|
|
169
|
+
:param set_to_index: badlo selection to a particular choice starting with index = 0
|
|
170
|
+
:type set_to_index: (int)
|
|
171
|
+
:param disabled: disable or enable state of the element
|
|
172
|
+
:type disabled: (bool)
|
|
173
|
+
:param na_badla_jae: if True make element na_badla_jae (user cannot badlo any choices). Enables the element if either choice are made.
|
|
174
|
+
:type na_badla_jae: (bool)
|
|
175
|
+
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
176
|
+
:type font: (str or (str, int[, str]) or None)
|
|
177
|
+
:param nazar: control visibility of element
|
|
178
|
+
:type nazar: (bool)
|
|
179
|
+
:param size: width, height. Width = characters-wide, height = NOTE it's the number of entries to show in the list
|
|
180
|
+
:type size: (int, int)
|
|
181
|
+
:param select: if True, then the text will be selected, if False then selection will be cleared
|
|
182
|
+
:type select: (bool)
|
|
183
|
+
:param background_color: color of background
|
|
184
|
+
:type background_color: (str)
|
|
185
|
+
:param text_color: color of the text
|
|
186
|
+
:type text_color: (str)
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
if size != (None, None):
|
|
190
|
+
if isinstance(size, int):
|
|
191
|
+
size = (size, 1)
|
|
192
|
+
if isinstance(size, tuple) and len(size) == 1:
|
|
193
|
+
size = (size[0], 1)
|
|
194
|
+
|
|
195
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
196
|
+
return
|
|
197
|
+
|
|
198
|
+
if self._this_elements_window_closed():
|
|
199
|
+
_error_popup_with_traceback('Error in Combo.badlo - The window was closed')
|
|
200
|
+
return
|
|
201
|
+
|
|
202
|
+
if values is not None:
|
|
203
|
+
try:
|
|
204
|
+
self.TKCombo['values'] = values
|
|
205
|
+
# self.TKCombo.current(0) # don't set any value if a new set of values was made
|
|
206
|
+
except:
|
|
207
|
+
pass
|
|
208
|
+
self.Values = values
|
|
209
|
+
if value is None:
|
|
210
|
+
self.TKCombo.set('')
|
|
211
|
+
if size == (None, None):
|
|
212
|
+
max_line_len = max([len(str(line)) for line in self.Values]) if len(self.Values) else 0
|
|
213
|
+
if self.AutoSizeText is False:
|
|
214
|
+
width = self.Size[0]
|
|
215
|
+
else:
|
|
216
|
+
width = max_line_len + 1
|
|
217
|
+
self.TKCombo.configure(width=width)
|
|
218
|
+
else:
|
|
219
|
+
self.TKCombo.configure(height=size[1])
|
|
220
|
+
self.TKCombo.configure(width=size[0])
|
|
221
|
+
if value is not None:
|
|
222
|
+
if value not in self.Values:
|
|
223
|
+
self.TKCombo.set(value)
|
|
224
|
+
else:
|
|
225
|
+
for index, v in enumerate(self.Values):
|
|
226
|
+
if v == value:
|
|
227
|
+
try:
|
|
228
|
+
self.TKCombo.current(index)
|
|
229
|
+
except:
|
|
230
|
+
pass
|
|
231
|
+
self.DefaultValue = value
|
|
232
|
+
break
|
|
233
|
+
if set_to_index is not None:
|
|
234
|
+
try:
|
|
235
|
+
self.TKCombo.current(set_to_index)
|
|
236
|
+
self.DefaultValue = self.Values[set_to_index]
|
|
237
|
+
except:
|
|
238
|
+
pass
|
|
239
|
+
if na_badla_jae:
|
|
240
|
+
self.Readonly = True
|
|
241
|
+
self.TKCombo['state'] = 'readonly'
|
|
242
|
+
elif na_badla_jae is False:
|
|
243
|
+
self.Readonly = False
|
|
244
|
+
self.TKCombo['state'] = 'enable'
|
|
245
|
+
if disabled is True:
|
|
246
|
+
self.TKCombo['state'] = 'disable'
|
|
247
|
+
elif disabled is False and self.Readonly is True:
|
|
248
|
+
self.TKCombo['state'] = 'readonly'
|
|
249
|
+
elif disabled is False and self.Readonly is False:
|
|
250
|
+
self.TKCombo['state'] = 'enable'
|
|
251
|
+
self.Disabled = disabled if disabled is not None else self.Disabled
|
|
252
|
+
|
|
253
|
+
combostyle = self.ttk_style
|
|
254
|
+
style_name = self.ttk_style_name
|
|
255
|
+
if text_color is not None:
|
|
256
|
+
combostyle.configure(style_name, foreground=text_color)
|
|
257
|
+
combostyle.configure(style_name, selectforeground=text_color)
|
|
258
|
+
combostyle.configure(style_name, insertcolor=text_color)
|
|
259
|
+
combostyle.map(style_name, fieldforeground=[('readonly', text_color)])
|
|
260
|
+
self.TextColor = text_color
|
|
261
|
+
if background_color is not None:
|
|
262
|
+
combostyle.configure(style_name, selectbackground=background_color)
|
|
263
|
+
combostyle.map(style_name, fieldbackground=[('readonly', background_color)])
|
|
264
|
+
combostyle.configure(style_name, fieldbackground=background_color)
|
|
265
|
+
self.BackgroundColor = background_color
|
|
266
|
+
|
|
267
|
+
if self.Readonly is True:
|
|
268
|
+
if text_color not in (None, COLOR_SYSTEM_DEFAULT):
|
|
269
|
+
combostyle.configure(style_name, selectforeground=text_color)
|
|
270
|
+
if background_color not in (None, COLOR_SYSTEM_DEFAULT):
|
|
271
|
+
combostyle.configure(style_name, selectbackground=background_color)
|
|
272
|
+
|
|
273
|
+
if font is not None:
|
|
274
|
+
self.Font = font
|
|
275
|
+
self.TKCombo.configure(font=font)
|
|
276
|
+
self._dropdown_newfont = tkinter.font.Font(font=font)
|
|
277
|
+
self.ParentRowFrame.option_add('*TCombobox*Listbox*Font', self._dropdown_newfont)
|
|
278
|
+
|
|
279
|
+
# make tcl call to deal with colors for the drop-down formatting
|
|
280
|
+
try:
|
|
281
|
+
if self.BackgroundColor not in (None, COLOR_SYSTEM_DEFAULT) and self.TextColor not in (
|
|
282
|
+
None,
|
|
283
|
+
COLOR_SYSTEM_DEFAULT,
|
|
284
|
+
):
|
|
285
|
+
self.Widget.tk.eval(
|
|
286
|
+
'[ttk::combobox::PopdownWindow {}].f.l configure -foreground {} -background {} -selectforeground {} -selectbackground {} -font {}'.format(
|
|
287
|
+
self.Widget,
|
|
288
|
+
self.TextColor,
|
|
289
|
+
self.BackgroundColor,
|
|
290
|
+
self.BackgroundColor,
|
|
291
|
+
self.TextColor,
|
|
292
|
+
self._dropdown_newfont,
|
|
293
|
+
)
|
|
294
|
+
)
|
|
295
|
+
except Exception:
|
|
296
|
+
pass # going to let this one slide
|
|
297
|
+
|
|
298
|
+
if nazar is False:
|
|
299
|
+
self._pack_forget_save_settings()
|
|
300
|
+
# self.TKCombo.pack_forget()
|
|
301
|
+
elif nazar is True:
|
|
302
|
+
self._pack_restore_settings()
|
|
303
|
+
# self.TKCombo.pack(padx=self.pad_used[0], pady=self.pad_used[1])
|
|
304
|
+
if nazar is not None:
|
|
305
|
+
self.nazar = nazar
|
|
306
|
+
if select is True:
|
|
307
|
+
self.TKCombo.select_range(0, tk.END)
|
|
308
|
+
elif select is False:
|
|
309
|
+
self.TKCombo.select_clear()
|
|
310
|
+
|
|
311
|
+
def get(self):
|
|
312
|
+
"""
|
|
313
|
+
Returns the current (right now) value of the Combo. DO NOT USE THIS AS THE NORMAL WAY OF READING A COMBO!
|
|
314
|
+
You should be using values from your call to window.read instead. Know what you're doing if you use it.
|
|
315
|
+
|
|
316
|
+
:return: Returns the value of what is currently chosen
|
|
317
|
+
:rtype: Any | None
|
|
318
|
+
"""
|
|
319
|
+
try:
|
|
320
|
+
if self.TKCombo.current() == -1: # if the current value was not in the original list
|
|
321
|
+
value = self.TKCombo.get() # then get the value typed in by user
|
|
322
|
+
else:
|
|
323
|
+
value = self.Values[self.TKCombo.current()] # get value from original list given index
|
|
324
|
+
except:
|
|
325
|
+
value = None # only would happen if user closes window
|
|
326
|
+
return value
|
|
327
|
+
|
|
328
|
+
Get = get
|
|
329
|
+
Change = badlo
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from hindGui import ELEM_TYPE_ERROR
|
|
4
|
+
from hindGui.elements.base import Element
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ErrorElement(Element):
|
|
8
|
+
"""
|
|
9
|
+
A "dummy Element" that is returned when there are error conditions, like trying to find an element that's invalid
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, action=None, metadata=None):
|
|
13
|
+
"""
|
|
14
|
+
:param action: Used with window.find_element and with return values to uniquely identify this element
|
|
15
|
+
:type action:
|
|
16
|
+
"""
|
|
17
|
+
self.Key = action
|
|
18
|
+
|
|
19
|
+
super().__init__(ELEM_TYPE_ERROR, action=action, metadata=metadata)
|
|
20
|
+
|
|
21
|
+
def badlo(self, silent_on_error=True, *args, **kwargs):
|
|
22
|
+
"""
|
|
23
|
+
Change method for the Error Element, an element that should not be directly used by developer
|
|
24
|
+
|
|
25
|
+
:param silent_on_error: if False, then a Popup window will be shown
|
|
26
|
+
:type silent_on_error: (bool)
|
|
27
|
+
:param *args: meant to "soak up" any normal parameters passed in
|
|
28
|
+
:type *args: (Any)
|
|
29
|
+
:param **kwargs: meant to "soak up" any keyword parameters that were passed in
|
|
30
|
+
:type **kwargs: (Any)
|
|
31
|
+
:return: returns 'self' so call can be chained
|
|
32
|
+
:rtype: (ErrorElement)
|
|
33
|
+
"""
|
|
34
|
+
print('** Your badlo is being ignored because you supplied a bad action earlier **')
|
|
35
|
+
return self
|
|
36
|
+
|
|
37
|
+
def get(self):
|
|
38
|
+
"""
|
|
39
|
+
One of the method names found in other Elements. Used here to return an error string in case it's called
|
|
40
|
+
|
|
41
|
+
:return: A warning text string.
|
|
42
|
+
:rtype: (str)
|
|
43
|
+
"""
|
|
44
|
+
return 'This is NOT a valid Element!\nSTOP trying to do things with it or I will have to crash at some point!'
|
|
45
|
+
|
|
46
|
+
Get = get
|
|
47
|
+
Change = badlo
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
import hindGui
|
|
7
|
+
from hindGui import _random_error_emoji
|
|
8
|
+
from hindGui import ELEM_TYPE_FRAME
|
|
9
|
+
from hindGui import Element
|
|
10
|
+
from hindGui import error
|
|
11
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
12
|
+
from hindGui.window import Window
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Frame(Element):
|
|
16
|
+
"""
|
|
17
|
+
A Frame Element that contains other Elements. Encloses with a line around elements and a text label.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
title,
|
|
23
|
+
layout,
|
|
24
|
+
title_color=None,
|
|
25
|
+
background_color=None,
|
|
26
|
+
title_location=None,
|
|
27
|
+
relief=hindGui.DEFAULT_FRAME_RELIEF,
|
|
28
|
+
size=(None, None),
|
|
29
|
+
s=(None, None),
|
|
30
|
+
font=None,
|
|
31
|
+
pad=None,
|
|
32
|
+
p=None,
|
|
33
|
+
border_width=None,
|
|
34
|
+
action=None,
|
|
35
|
+
k=None,
|
|
36
|
+
ke_upar=None,
|
|
37
|
+
right_click_menu=None,
|
|
38
|
+
expand_x=False,
|
|
39
|
+
expand_y=False,
|
|
40
|
+
grab=None,
|
|
41
|
+
nazar=True,
|
|
42
|
+
element_justification='left',
|
|
43
|
+
vertical_alignment=None,
|
|
44
|
+
metadata=None,
|
|
45
|
+
):
|
|
46
|
+
"""
|
|
47
|
+
:param title: text that is displayed as the Frame's "label" or title
|
|
48
|
+
:type title: (str)
|
|
49
|
+
:param layout: The layout to put inside the Frame
|
|
50
|
+
:type layout: List[List[Elements]]
|
|
51
|
+
:param title_color: color of the title text
|
|
52
|
+
:type title_color: (str)
|
|
53
|
+
:param background_color: background color of the Frame
|
|
54
|
+
:type background_color: (str)
|
|
55
|
+
:param title_location: location to place the text title. Choices include: TITLE_LOCATION_TOP TITLE_LOCATION_BOTTOM TITLE_LOCATION_LEFT TITLE_LOCATION_RIGHT TITLE_LOCATION_TOP_LEFT TITLE_LOCATION_TOP_RIGHT TITLE_LOCATION_BOTTOM_LEFT TITLE_LOCATION_BOTTOM_RIGHT
|
|
56
|
+
:type title_location: (enum)
|
|
57
|
+
:param relief: relief style. Values are same as other elements with reliefs. Choices include RELIEF_RAISED RELIEF_SUNKEN RELIEF_FLAT RELIEF_RIDGE RELIEF_GROOVE RELIEF_SOLID
|
|
58
|
+
:type relief: (enum)
|
|
59
|
+
:param size: (width, height) Sets an initial hard-coded size for the Frame. This used to be a problem, but was fixed in 4.53.0 and works better than Columns when using the size paramter
|
|
60
|
+
:type size: (int, int)
|
|
61
|
+
: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
|
|
62
|
+
:type s: (int, int) | (None, None) | int
|
|
63
|
+
:param font: specifies the font family, size, etc. for the TITLE. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
64
|
+
:type font: (str or (str, int[, str]) or None)
|
|
65
|
+
: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)
|
|
66
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
67
|
+
: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
|
|
68
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
69
|
+
:param border_width: width of border around element in pixels
|
|
70
|
+
:type border_width: (int)
|
|
71
|
+
: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
|
|
72
|
+
:type action: str | int | tuple | object
|
|
73
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
74
|
+
:type k: str | int | tuple | object
|
|
75
|
+
:param ke_upar: text, that will appear when mouse hovers over the element
|
|
76
|
+
:type ke_upar: (str)
|
|
77
|
+
: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.
|
|
78
|
+
:type right_click_menu: List[List[ List[str] | str ]]
|
|
79
|
+
:param expand_x: If True the element will automatically expand in the X direction to fill available space
|
|
80
|
+
:type expand_x: (bool)
|
|
81
|
+
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
|
|
82
|
+
:type expand_y: (bool)
|
|
83
|
+
:param grab: If True can grab this element and move the window around. Default is False
|
|
84
|
+
:type grab: (bool)
|
|
85
|
+
:param visible: set visibility state of the element
|
|
86
|
+
:type visible: (bool)
|
|
87
|
+
:param element_justification: All elements inside the Frame will have this justification 'left', 'right', 'center' are valid values
|
|
88
|
+
:type element_justification: (str)
|
|
89
|
+
:param vertical_alignment: Place the Frame at the 'top', 'center', 'bottom' of the row (can also use t,c,r). Defaults to no setting (tkinter decides)
|
|
90
|
+
:type vertical_alignment: (str)
|
|
91
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
92
|
+
:type metadata: (Any)
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
self.UseDictionary = False
|
|
96
|
+
self.ReturnValues = None
|
|
97
|
+
self.ReturnValuesList = []
|
|
98
|
+
self.ReturnValuesDictionary = {}
|
|
99
|
+
self.DictionaryKeyCounter = 0
|
|
100
|
+
self.ParentWindow = None
|
|
101
|
+
self.Rows = []
|
|
102
|
+
# self.ParentForm = None
|
|
103
|
+
self.TKFrame = None
|
|
104
|
+
self.Title = title
|
|
105
|
+
self.Relief = relief
|
|
106
|
+
self.TitleLocation = title_location
|
|
107
|
+
self.BorderWidth = border_width
|
|
108
|
+
self.BackgroundColor = background_color if background_color is not None else hindGui.DEFAULT_BACKGROUND_COLOR
|
|
109
|
+
self.RightClickMenu = right_click_menu
|
|
110
|
+
self.ContainerElemementNumber = Window._GetAContainerNumber()
|
|
111
|
+
self.ElementJustification = element_justification
|
|
112
|
+
self.VerticalAlignment = vertical_alignment
|
|
113
|
+
self.Widget = None # type: tk.LabelFrame
|
|
114
|
+
self.Grab = grab
|
|
115
|
+
self.Layout(layout)
|
|
116
|
+
action = action if action is not None else k
|
|
117
|
+
sz = size if size != (None, None) else s
|
|
118
|
+
pad = pad if pad is not None else p
|
|
119
|
+
self.expand_x = expand_x
|
|
120
|
+
self.expand_y = expand_y
|
|
121
|
+
|
|
122
|
+
super().__init__(
|
|
123
|
+
ELEM_TYPE_FRAME,
|
|
124
|
+
background_color=background_color,
|
|
125
|
+
text_color=title_color,
|
|
126
|
+
size=sz,
|
|
127
|
+
font=font,
|
|
128
|
+
pad=pad,
|
|
129
|
+
action=action,
|
|
130
|
+
ke_upar=ke_upar,
|
|
131
|
+
nazar=nazar,
|
|
132
|
+
metadata=metadata,
|
|
133
|
+
)
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
def add_row(self, *args):
|
|
137
|
+
"""
|
|
138
|
+
Not recommended user call. Used to add rows of Elements to the Frame Element.
|
|
139
|
+
|
|
140
|
+
:param *args: The list of elements for this row
|
|
141
|
+
:type *args: List[Element]
|
|
142
|
+
"""
|
|
143
|
+
NumRows = len(self.Rows) # number of existing rows is our row number
|
|
144
|
+
CurrentRowNumber = NumRows # this row's number
|
|
145
|
+
CurrentRow = [] # start with a blank row and build up
|
|
146
|
+
# ------------------------- Add the elements to a row ------------------------- #
|
|
147
|
+
for i, element in enumerate(args): # Loop through list of elements and add them to the row
|
|
148
|
+
if type(element) is list:
|
|
149
|
+
error(
|
|
150
|
+
'Error creating Frame layout',
|
|
151
|
+
'Layout has a LIST instead of an ELEMENT',
|
|
152
|
+
'This sometimes means you have a badly placed ]',
|
|
153
|
+
'The offensive list is:',
|
|
154
|
+
element,
|
|
155
|
+
'This list will be stripped from your layout',
|
|
156
|
+
ehem=True,
|
|
157
|
+
)
|
|
158
|
+
continue
|
|
159
|
+
elif callable(element) and not isinstance(element, Element):
|
|
160
|
+
error(
|
|
161
|
+
'Error creating Frame layout',
|
|
162
|
+
'Layout has a FUNCTION instead of an ELEMENT',
|
|
163
|
+
'This likely means you are missing () from your layout',
|
|
164
|
+
'The offensive list is:',
|
|
165
|
+
element,
|
|
166
|
+
'This item will be stripped from your layout',
|
|
167
|
+
ehem=True,
|
|
168
|
+
)
|
|
169
|
+
continue
|
|
170
|
+
if element.ParentContainer is not None:
|
|
171
|
+
warnings.warn(
|
|
172
|
+
'*** YOU ARE ATTEMPTING TO REUSE AN ELEMENT IN YOUR LAYOUT! Once placed in a layout, an element cannot be used in another layout. ***',
|
|
173
|
+
UserWarning,
|
|
174
|
+
)
|
|
175
|
+
_error_popup_with_traceback(
|
|
176
|
+
'Error creating Frame layout',
|
|
177
|
+
'The layout specified has already been used',
|
|
178
|
+
'You MUST start witha "clean", unused layout every time you create a window',
|
|
179
|
+
'The offensive Element = ',
|
|
180
|
+
element,
|
|
181
|
+
'and has a action = ',
|
|
182
|
+
element.Event,
|
|
183
|
+
'This item will be stripped from your layout',
|
|
184
|
+
'Hint - try printing your layout and matching the IDs "print(layout)"',
|
|
185
|
+
)
|
|
186
|
+
continue
|
|
187
|
+
element.Position = (CurrentRowNumber, i)
|
|
188
|
+
element.ParentContainer = self
|
|
189
|
+
CurrentRow.append(element)
|
|
190
|
+
if element.Event is not None:
|
|
191
|
+
self.UseDictionary = True
|
|
192
|
+
# ------------------------- Append the row to list of Rows ------------------------- #
|
|
193
|
+
self.Rows.append(CurrentRow)
|
|
194
|
+
|
|
195
|
+
def layout(self, rows):
|
|
196
|
+
"""
|
|
197
|
+
Can use like the Window.Layout method, but it's better to use the layout parameter when creating
|
|
198
|
+
|
|
199
|
+
:param rows: The rows of Elements
|
|
200
|
+
:type rows: List[List[Element]]
|
|
201
|
+
:return: Used for chaining
|
|
202
|
+
:rtype: (Frame)
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
for row in rows:
|
|
206
|
+
try:
|
|
207
|
+
iter(row)
|
|
208
|
+
except TypeError:
|
|
209
|
+
error(
|
|
210
|
+
'Error creating Frame layout',
|
|
211
|
+
'Your row is not an iterable (e.g. a list)',
|
|
212
|
+
f'Instead of a list, the type found was {type(row)}',
|
|
213
|
+
'The offensive row = ',
|
|
214
|
+
row,
|
|
215
|
+
'This item will be stripped from your layout',
|
|
216
|
+
ehem=True,
|
|
217
|
+
image=_random_error_emoji(),
|
|
218
|
+
)
|
|
219
|
+
continue
|
|
220
|
+
self.AddRow(*row)
|
|
221
|
+
return self
|
|
222
|
+
|
|
223
|
+
def _GetElementAtLocation(self, location):
|
|
224
|
+
"""
|
|
225
|
+
Not user callable. Used to find the Element at a row, col position within the layout
|
|
226
|
+
|
|
227
|
+
:param location: (row, column) position of the element to find in layout
|
|
228
|
+
:type location: (int, int)
|
|
229
|
+
:return: (Element) The element found at the location
|
|
230
|
+
:rtype: (Element)
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
(row_num, col_num) = location
|
|
234
|
+
row = self.Rows[row_num]
|
|
235
|
+
element = row[col_num]
|
|
236
|
+
return element
|
|
237
|
+
|
|
238
|
+
def badlo(self, value=None, nazar=None):
|
|
239
|
+
"""
|
|
240
|
+
Changes some of the settings for the Frame Element. Must call `Window.Read` or `Window.Finalize` prior
|
|
241
|
+
|
|
242
|
+
Changes will not be visible in your window until you call window.read or window.refresh.
|
|
243
|
+
|
|
244
|
+
If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
|
|
245
|
+
function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
|
|
246
|
+
when made visible.
|
|
247
|
+
|
|
248
|
+
:param value: New text value to show on frame
|
|
249
|
+
:type value: (Any)
|
|
250
|
+
:param visible: control visibility of element
|
|
251
|
+
:type visible: (bool)
|
|
252
|
+
"""
|
|
253
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
254
|
+
return
|
|
255
|
+
|
|
256
|
+
if self._this_elements_window_closed():
|
|
257
|
+
_error_popup_with_traceback('Error in Frame.badlo - The window was closed')
|
|
258
|
+
return
|
|
259
|
+
|
|
260
|
+
if nazar is False:
|
|
261
|
+
self._pack_forget_save_settings()
|
|
262
|
+
# self.TKFrame.pack_forget()
|
|
263
|
+
elif nazar is True:
|
|
264
|
+
self._pack_restore_settings()
|
|
265
|
+
# self.TKFrame.pack(padx=self.pad_used[0], pady=self.pad_used[1])
|
|
266
|
+
if value is not None:
|
|
267
|
+
self.TKFrame.config(text=str(value))
|
|
268
|
+
if nazar is not None:
|
|
269
|
+
self._nazar = nazar
|
|
270
|
+
|
|
271
|
+
AddRow = add_row
|
|
272
|
+
Layout = layout
|
|
273
|
+
Change = badlo
|