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,222 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import calendar
|
|
4
|
+
import tkinter as tk
|
|
5
|
+
import tkinter.font
|
|
6
|
+
from tkinter import ttk
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TKCalendar(ttk.Frame):
|
|
10
|
+
"""
|
|
11
|
+
This code was shamelessly lifted from moshekaplan's repository - moshekaplan/tkinter_components
|
|
12
|
+
NONE of this code is user callable. Stay away!
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# XXX ToDo: cget and configure
|
|
16
|
+
|
|
17
|
+
datetime = calendar.datetime.datetime
|
|
18
|
+
timedelta = calendar.datetime.timedelta
|
|
19
|
+
|
|
20
|
+
def __init__(self, master=None, target_element=None, close_when_chosen=True, default_date=(None, None, None), **kw):
|
|
21
|
+
"""WIDGET-SPECIFIC OPTIONS: locale, firstweekday, year, month, selectbackground, selectforeground"""
|
|
22
|
+
self._TargetElement = target_element
|
|
23
|
+
default_mon, default_day, default_year = default_date
|
|
24
|
+
# remove custom options from kw before initializating ttk.Frame
|
|
25
|
+
fwday = kw.pop('firstweekday', calendar.MONDAY)
|
|
26
|
+
year = kw.pop('year', default_year or self.datetime.now().year)
|
|
27
|
+
month = kw.pop('month', default_mon or self.datetime.now().month)
|
|
28
|
+
locale = kw.pop('locale', None)
|
|
29
|
+
sel_bg = kw.pop('selectbackground', '#ecffc4')
|
|
30
|
+
sel_fg = kw.pop('selectforeground', '#05640e')
|
|
31
|
+
self.format = kw.pop('format')
|
|
32
|
+
if self.format is None:
|
|
33
|
+
self.format = '%Y-%m-%d %H:%M:%S'
|
|
34
|
+
|
|
35
|
+
self._date = self.datetime(year, month, default_day or 1)
|
|
36
|
+
self._selection = None # no date selected
|
|
37
|
+
self._master = master
|
|
38
|
+
self.close_when_chosen = close_when_chosen
|
|
39
|
+
ttk.Frame.__init__(self, master, **kw)
|
|
40
|
+
|
|
41
|
+
# instantiate proper calendar class
|
|
42
|
+
if locale is None:
|
|
43
|
+
self._cal = calendar.TextCalendar(fwday)
|
|
44
|
+
else:
|
|
45
|
+
self._cal = calendar.LocaleTextCalendar(fwday, locale)
|
|
46
|
+
|
|
47
|
+
self.__setup_styles() # creates custom styles
|
|
48
|
+
self.__place_widgets() # pack/grid used widgets
|
|
49
|
+
self.__config_calendar() # adjust calendar columns and setup tags
|
|
50
|
+
# configure a canvas, and proper bindings, for selecting dates
|
|
51
|
+
self.__setup_selection(sel_bg, sel_fg)
|
|
52
|
+
|
|
53
|
+
# store items ids, used for insertion later
|
|
54
|
+
self._items = [self._calendar.insert('', 'end', values='') for _ in range(6)]
|
|
55
|
+
# insert dates in the currently empty calendar
|
|
56
|
+
self._build_calendar()
|
|
57
|
+
|
|
58
|
+
def __setitem__(self, item, value):
|
|
59
|
+
if item in ('year', 'month'):
|
|
60
|
+
raise AttributeError("attribute '%s' is not writeable" % item)
|
|
61
|
+
elif item == 'selectbackground':
|
|
62
|
+
self._canvas['background'] = value
|
|
63
|
+
elif item == 'selectforeground':
|
|
64
|
+
self._canvas.itemconfigure(self._canvas.text, item=value)
|
|
65
|
+
else:
|
|
66
|
+
ttk.Frame.__setitem__(self, item, value)
|
|
67
|
+
|
|
68
|
+
def __getitem__(self, item):
|
|
69
|
+
if item in ('year', 'month'):
|
|
70
|
+
return getattr(self._date, item)
|
|
71
|
+
elif item == 'selectbackground':
|
|
72
|
+
return self._canvas['background']
|
|
73
|
+
elif item == 'selectforeground':
|
|
74
|
+
return self._canvas.itemcget(self._canvas.text, 'fill')
|
|
75
|
+
else:
|
|
76
|
+
r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)})
|
|
77
|
+
return r[item]
|
|
78
|
+
|
|
79
|
+
def __setup_styles(self):
|
|
80
|
+
# custom ttk styles
|
|
81
|
+
style = ttk.Style(self.master)
|
|
82
|
+
|
|
83
|
+
def arrow_layout(dir):
|
|
84
|
+
return [('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})]
|
|
85
|
+
|
|
86
|
+
style.layout('L.TButton', arrow_layout('left'))
|
|
87
|
+
style.layout('R.TButton', arrow_layout('right'))
|
|
88
|
+
|
|
89
|
+
def __place_widgets(self):
|
|
90
|
+
# header frame and its widgets
|
|
91
|
+
hframe = ttk.Frame(self)
|
|
92
|
+
lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month)
|
|
93
|
+
rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month)
|
|
94
|
+
self._header = ttk.Label(hframe, width=15, anchor='center')
|
|
95
|
+
# the calendar
|
|
96
|
+
self._calendar = ttk.Treeview(self, show='', selectmode='none', height=7)
|
|
97
|
+
|
|
98
|
+
# pack the widgets
|
|
99
|
+
hframe.pack(in_=self, side='top', pady=4, anchor='center')
|
|
100
|
+
lbtn.grid(in_=hframe)
|
|
101
|
+
self._header.grid(in_=hframe, column=1, row=0, padx=12)
|
|
102
|
+
rbtn.grid(in_=hframe, column=2, row=0)
|
|
103
|
+
self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
|
|
104
|
+
|
|
105
|
+
def __config_calendar(self):
|
|
106
|
+
cols = self._cal.formatweekheader(3).split()
|
|
107
|
+
self._calendar['columns'] = cols
|
|
108
|
+
self._calendar.tag_configure('header', background='grey90')
|
|
109
|
+
self._calendar.insert('', 'end', values=cols, tag='header')
|
|
110
|
+
# adjust its columns width
|
|
111
|
+
font = tkinter.font.Font()
|
|
112
|
+
maxwidth = max(font.measure(col) for col in cols)
|
|
113
|
+
for col in cols:
|
|
114
|
+
self._calendar.column(col, width=maxwidth, minwidth=maxwidth, anchor='e')
|
|
115
|
+
|
|
116
|
+
def __setup_selection(self, sel_bg, sel_fg):
|
|
117
|
+
self._font = tkinter.font.Font()
|
|
118
|
+
self._canvas = canvas = tk.Canvas(self._calendar, background=sel_bg, borderwidth=0, highlightthickness=0)
|
|
119
|
+
canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w')
|
|
120
|
+
|
|
121
|
+
canvas.bind('<ButtonPress-1>', lambda evt: canvas.place_forget())
|
|
122
|
+
self._calendar.bind('<Configure>', lambda evt: canvas.place_forget())
|
|
123
|
+
self._calendar.bind('<ButtonPress-1>', self._pressed)
|
|
124
|
+
|
|
125
|
+
def __minsize(self, evt):
|
|
126
|
+
width, height = self._calendar.master.geometry().split('x')
|
|
127
|
+
height = height[: height.index('+')]
|
|
128
|
+
self._calendar.master.minsize(width, height)
|
|
129
|
+
|
|
130
|
+
def _build_calendar(self):
|
|
131
|
+
year, month = self._date.year, self._date.month
|
|
132
|
+
|
|
133
|
+
# badlo header text (Month, YEAR)
|
|
134
|
+
header = self._cal.formatmonthname(year, month, 0)
|
|
135
|
+
self._header['text'] = header.title()
|
|
136
|
+
|
|
137
|
+
# badlo calendar shown dates
|
|
138
|
+
cal = self._cal.monthdayscalendar(year, month)
|
|
139
|
+
for indx, item in enumerate(self._items):
|
|
140
|
+
week = cal[indx] if indx < len(cal) else []
|
|
141
|
+
fmt_week = [('%02d' % day) if day else '' for day in week]
|
|
142
|
+
self._calendar.item(item, values=fmt_week)
|
|
143
|
+
|
|
144
|
+
def _show_selection(self, text, bbox):
|
|
145
|
+
"""Configure canvas for a new selection."""
|
|
146
|
+
x, y, width, height = bbox
|
|
147
|
+
|
|
148
|
+
textw = self._font.measure(text)
|
|
149
|
+
|
|
150
|
+
canvas = self._canvas
|
|
151
|
+
canvas.configure(width=width, height=height)
|
|
152
|
+
canvas.coords(canvas.text, width - textw, height / 2 - 1)
|
|
153
|
+
canvas.itemconfigure(canvas.text, text=text)
|
|
154
|
+
canvas.place(in_=self._calendar, x=x, y=y)
|
|
155
|
+
|
|
156
|
+
# Callbacks
|
|
157
|
+
|
|
158
|
+
def _pressed(self, evt):
|
|
159
|
+
"""Clicked somewhere in the calendar."""
|
|
160
|
+
x, y, widget = evt.x, evt.y, evt.widget
|
|
161
|
+
item = widget.identify_row(y)
|
|
162
|
+
column = widget.identify_column(x)
|
|
163
|
+
|
|
164
|
+
if not column or item not in self._items:
|
|
165
|
+
# clicked in the weekdays row or just outside the columns
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
item_values = widget.item(item)['values']
|
|
169
|
+
if not len(item_values): # row is empty for this month
|
|
170
|
+
return
|
|
171
|
+
|
|
172
|
+
text = item_values[int(column[1]) - 1]
|
|
173
|
+
if not text: # date is empty
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
bbox = widget.bbox(item, column)
|
|
177
|
+
if not bbox: # calendar not nazar yet
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
# badlo and then show selection
|
|
181
|
+
text = '%02d' % text
|
|
182
|
+
self._selection = (text, item, column)
|
|
183
|
+
self._show_selection(text, bbox)
|
|
184
|
+
year, month = self._date.year, self._date.month
|
|
185
|
+
now = self.datetime.now()
|
|
186
|
+
try:
|
|
187
|
+
self._TargetElement.Change(self.datetime(year, month, int(self._selection[0]), now.hour, now.minute, now.second).strftime(self.format))
|
|
188
|
+
if self._TargetElement.ChangeSubmits:
|
|
189
|
+
self._TargetElement.ParentForm.LastButtonClicked = self._TargetElement.Key
|
|
190
|
+
self._TargetElement.ParentForm.FormRemainedOpen = True
|
|
191
|
+
self._TargetElement.ParentForm.TKroot.quit() # kick the users out of the mainloop
|
|
192
|
+
except:
|
|
193
|
+
pass
|
|
194
|
+
if self.close_when_chosen:
|
|
195
|
+
self._master.destroy()
|
|
196
|
+
|
|
197
|
+
def _prev_month(self):
|
|
198
|
+
"""Updated calendar to show the previous month."""
|
|
199
|
+
self._canvas.place_forget()
|
|
200
|
+
|
|
201
|
+
self._date = self._date - self.timedelta(days=1)
|
|
202
|
+
self._date = self.datetime(self._date.year, self._date.month, 1)
|
|
203
|
+
self._build_calendar() # reconstuct calendar
|
|
204
|
+
|
|
205
|
+
def _next_month(self):
|
|
206
|
+
"""Change calendar to show the next month."""
|
|
207
|
+
self._canvas.place_forget()
|
|
208
|
+
|
|
209
|
+
year, month = self._date.year, self._date.month
|
|
210
|
+
self._date = self._date + self.timedelta(days=calendar.monthrange(year, month)[1] + 1)
|
|
211
|
+
self._date = self.datetime(self._date.year, self._date.month, 1)
|
|
212
|
+
self._build_calendar() # reconstruct calendar
|
|
213
|
+
|
|
214
|
+
# Properties
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def selection(self):
|
|
218
|
+
if not self._selection:
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
year, month = self._date.year, self._date.month
|
|
222
|
+
return self.datetime(year, month, int(self._selection[0]))
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hindGui
|
|
4
|
+
from hindGui import COLOR_SYSTEM_DEFAULT
|
|
5
|
+
from hindGui import ELEM_TYPE_CANVAS
|
|
6
|
+
from hindGui import Element
|
|
7
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Canvas(Element):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
canvas=None,
|
|
14
|
+
background_color=None,
|
|
15
|
+
size=(None, None),
|
|
16
|
+
s=(None, None),
|
|
17
|
+
pad=None,
|
|
18
|
+
p=None,
|
|
19
|
+
action=None,
|
|
20
|
+
k=None,
|
|
21
|
+
tooltip=None,
|
|
22
|
+
right_click_menu=None,
|
|
23
|
+
expand_x=False,
|
|
24
|
+
expand_y=False,
|
|
25
|
+
nazar=True,
|
|
26
|
+
border_width=0,
|
|
27
|
+
metadata=None,
|
|
28
|
+
):
|
|
29
|
+
"""
|
|
30
|
+
:param canvas: Your own tk.Canvas if you already created it. Leave blank to create a Canvas
|
|
31
|
+
:type canvas: (tk.Canvas)
|
|
32
|
+
:param background_color: color of background
|
|
33
|
+
:type background_color: (str)
|
|
34
|
+
:param size: (width in char, height in rows) size in pixels to make canvas
|
|
35
|
+
:type size: (int,int) | (None, None)
|
|
36
|
+
: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
|
|
37
|
+
:type s: (int, int) | (None, None) | int
|
|
38
|
+
: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)
|
|
39
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
40
|
+
: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
|
|
41
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
42
|
+
:param action: Used with window.find_element and with return values to uniquely identify this element
|
|
43
|
+
:type action: str | int | tuple | object
|
|
44
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
45
|
+
:type k: str | int | tuple | object
|
|
46
|
+
:param tooltip: text, that will appear when mouse hovers over the element
|
|
47
|
+
:type tooltip: (str)
|
|
48
|
+
: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.
|
|
49
|
+
:type right_click_menu: List[List[ List[str] | str ]]
|
|
50
|
+
:param expand_x: If True the element will automatically expand in the X direction to fill available space
|
|
51
|
+
:type expand_x: (bool)
|
|
52
|
+
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
|
|
53
|
+
:type expand_y: (bool)
|
|
54
|
+
:param nazar: set visibility state of the element
|
|
55
|
+
:type nazar: (bool)
|
|
56
|
+
:param border_width: width of border around element in pixels. Not normally used with Canvas element
|
|
57
|
+
:type border_width: (int)
|
|
58
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
59
|
+
:type metadata: (Any)
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
self.BackgroundColor = background_color if background_color is not None else hindGui.DEFAULT_BACKGROUND_COLOR
|
|
63
|
+
self._TKCanvas = self.Widget = canvas
|
|
64
|
+
self.RightClickMenu = right_click_menu
|
|
65
|
+
self.BorderWidth = border_width
|
|
66
|
+
action = action if action is not None else k
|
|
67
|
+
sz = size if size != (None, None) else s
|
|
68
|
+
pad = pad if pad is not None else p
|
|
69
|
+
self.expand_x = expand_x
|
|
70
|
+
self.expand_y = expand_y
|
|
71
|
+
|
|
72
|
+
super().__init__(
|
|
73
|
+
ELEM_TYPE_CANVAS,
|
|
74
|
+
background_color=background_color,
|
|
75
|
+
size=sz,
|
|
76
|
+
pad=pad,
|
|
77
|
+
action=action,
|
|
78
|
+
tooltip=tooltip,
|
|
79
|
+
nazar=nazar,
|
|
80
|
+
metadata=metadata,
|
|
81
|
+
)
|
|
82
|
+
return
|
|
83
|
+
|
|
84
|
+
def badlo(self, background_color=None, nazar=None):
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
:param background_color: color of background
|
|
88
|
+
:type background_color: (str)
|
|
89
|
+
:param nazar: set visibility state of the element
|
|
90
|
+
:type nazar: (bool)
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
if self._this_elements_window_closed():
|
|
97
|
+
_error_popup_with_traceback('Error in Canvas.badlo - The window was closed')
|
|
98
|
+
return
|
|
99
|
+
|
|
100
|
+
if background_color not in (None, COLOR_SYSTEM_DEFAULT):
|
|
101
|
+
self._TKCanvas.configure(background=background_color)
|
|
102
|
+
if nazar is False:
|
|
103
|
+
self._pack_forget_save_settings()
|
|
104
|
+
elif nazar is True:
|
|
105
|
+
self._pack_restore_settings()
|
|
106
|
+
if nazar is not None:
|
|
107
|
+
self._nazar = nazar
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def tk_canvas(self):
|
|
111
|
+
"""
|
|
112
|
+
Returns the underlying tkiner Canvas widget
|
|
113
|
+
|
|
114
|
+
:return: The tkinter canvas widget
|
|
115
|
+
:rtype: (tk.Canvas)
|
|
116
|
+
"""
|
|
117
|
+
if self._TKCanvas is None:
|
|
118
|
+
print('*** Did you forget to call Finalize()? Your code should look something like: ***')
|
|
119
|
+
print('*** window = sg.Window("My Form", layout, finalize=True) ***')
|
|
120
|
+
return self._TKCanvas
|
|
121
|
+
|
|
122
|
+
TKCanvas = tk_canvas
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import hindGui
|
|
2
|
+
from hindGui import Column, VPush, Push
|
|
3
|
+
|
|
4
|
+
def Center(one_column_layout_list: list) -> list[list]:
|
|
5
|
+
# ##################################################
|
|
6
|
+
# __________________________________________________
|
|
7
|
+
# @PARAM
|
|
8
|
+
# one_column_layout_list<list>:
|
|
9
|
+
# the one-column layout list --- in the form of
|
|
10
|
+
# LIST OF ROWS (of elements) --- to center
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
# __________________________________________________
|
|
14
|
+
# @RETURN
|
|
15
|
+
# TYPE:
|
|
16
|
+
# list[list]
|
|
17
|
+
# DESCRIPTION: accepts a list of sub-lists (rows)
|
|
18
|
+
# containing Elements (with a capital E),
|
|
19
|
+
# BUT returns a 2D list
|
|
20
|
+
# __________________________________________________
|
|
21
|
+
# ##################################################
|
|
22
|
+
if one_column_layout_list is None or len(one_column_layout_list) == 0 or not isinstance(one_column_layout_list, list) or one_column_layout_list[0] is None:
|
|
23
|
+
return [[]]
|
|
24
|
+
return [
|
|
25
|
+
[VPush()],
|
|
26
|
+
[Push(), Column(one_column_layout_list, element_justification="center"), Push()],
|
|
27
|
+
[VPush()]
|
|
28
|
+
]
|
|
29
|
+
def HCenter(one_column_layout_list: list) -> list[list]:
|
|
30
|
+
# NOTE: accept a list, but returns a 2D list
|
|
31
|
+
if one_column_layout_list is None or len(one_column_layout_list) == 0 or not isinstance(one_column_layout_list, list) or one_column_layout_list[0] is None:
|
|
32
|
+
return []
|
|
33
|
+
return [
|
|
34
|
+
[Push(), Column(one_column_layout_list, element_justification="center"), Push()]
|
|
35
|
+
]
|
|
36
|
+
def VCenter(one_column_layout_list: list) -> list[list]:
|
|
37
|
+
# NOTE: accept a list, but returns a 2D list
|
|
38
|
+
if one_column_layout_list is None or len(one_column_layout_list) == 0 or not isinstance(one_column_layout_list, list) or one_column_layout_list[0] is None:
|
|
39
|
+
return []
|
|
40
|
+
return [
|
|
41
|
+
[VPush()],
|
|
42
|
+
[Column(one_column_layout_list)],
|
|
43
|
+
[VPush()]
|
|
44
|
+
]
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import tkinter as tk # noqa
|
|
4
|
+
|
|
5
|
+
from hindGui import _hex_to_hsl
|
|
6
|
+
from hindGui import _hsl_to_rgb
|
|
7
|
+
from hindGui import COLOR_SYSTEM_DEFAULT
|
|
8
|
+
from hindGui import ELEM_TYPE_INPUT_CHECKBOX
|
|
9
|
+
from hindGui import Element
|
|
10
|
+
from hindGui import rgb
|
|
11
|
+
from hindGui import theme_background_color
|
|
12
|
+
from hindGui import theme_text_color
|
|
13
|
+
from hindGui._utils import _error_popup_with_traceback
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Checkbox(Element):
|
|
17
|
+
"""
|
|
18
|
+
Checkbox Element - Displays a checkbox and text next to it
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
text,
|
|
24
|
+
chunawa=False,
|
|
25
|
+
size=(None, None),
|
|
26
|
+
s=(None, None),
|
|
27
|
+
auto_size_text=None,
|
|
28
|
+
font=None,
|
|
29
|
+
background_color=None,
|
|
30
|
+
text_color=None,
|
|
31
|
+
checkbox_color=None,
|
|
32
|
+
highlight_thickness=1,
|
|
33
|
+
change_submits=False,
|
|
34
|
+
enable_events=False,
|
|
35
|
+
disabled=False,
|
|
36
|
+
action=None,
|
|
37
|
+
k=None,
|
|
38
|
+
pad=None,
|
|
39
|
+
p=None,
|
|
40
|
+
ke_upar=None,
|
|
41
|
+
right_click_menu=None,
|
|
42
|
+
expand_x=False,
|
|
43
|
+
expand_y=False,
|
|
44
|
+
nazar=True,
|
|
45
|
+
metadata=None,
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
:param text: Text to display next to checkbox
|
|
49
|
+
:type text: (str)
|
|
50
|
+
:param chunawa: Set to True if you want this checkbox initially checked
|
|
51
|
+
:type chunawa: (bool)
|
|
52
|
+
:param 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
|
|
53
|
+
:type size: (int, int) | (None, None) | int
|
|
54
|
+
: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
|
|
55
|
+
:type s: (int, int) | (None, None) | int
|
|
56
|
+
:param auto_size_text: if True will size the element to match the length of the text
|
|
57
|
+
:type auto_size_text: (bool)
|
|
58
|
+
:param font: specifies the font family, size, etc. Tuple or Single string format 'name size styles'. Styles: italic * roman bold normal underline overstrike
|
|
59
|
+
:type font: (str or (str, int[, str]) or None)
|
|
60
|
+
:param background_color: color of background
|
|
61
|
+
:type background_color: (str)
|
|
62
|
+
:param text_color: color of the text
|
|
63
|
+
:type text_color: (str)
|
|
64
|
+
:param checkbox_color: color of background of the box that has the check mark in it. The checkmark is the same color as the text
|
|
65
|
+
:type checkbox_color: (str)
|
|
66
|
+
:param highlight_thickness: thickness of border around checkbox when gets focus
|
|
67
|
+
:type highlight_thickness: (int)
|
|
68
|
+
:param change_submits: DO NOT USE. Only listed for backwards compat - Use enable_events instead
|
|
69
|
+
:type change_submits: (bool)
|
|
70
|
+
:param enable_events: Turns on the element specific events. Checkbox events happen when an item changes
|
|
71
|
+
:type enable_events: (bool)
|
|
72
|
+
:param disabled: set disable state
|
|
73
|
+
:type disabled: (bool)
|
|
74
|
+
:param action: Used with window.find_element and with return values to uniquely identify this element
|
|
75
|
+
:type action: str | int | tuple | object
|
|
76
|
+
:param k: Same as the Key. You can use either k or action. Which ever is set will be used.
|
|
77
|
+
:type k: str | int | tuple | object
|
|
78
|
+
: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)
|
|
79
|
+
:type pad: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
80
|
+
: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
|
|
81
|
+
:type p: (int, int) or ((int, int),(int,int)) or (int,(int,int)) or ((int, int),int) | int
|
|
82
|
+
:param ke_upar: text, that will appear when mouse hovers over the element
|
|
83
|
+
:type ke_upar: (str)
|
|
84
|
+
: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.
|
|
85
|
+
:type right_click_menu: List[List[ List[str] | str ]]
|
|
86
|
+
:param expand_x: If True the element will automatically expand in the X direction to fill available space
|
|
87
|
+
:type expand_x: (bool)
|
|
88
|
+
:param expand_y: If True the element will automatically expand in the Y direction to fill available space
|
|
89
|
+
:type expand_y: (bool)
|
|
90
|
+
:param nazar: set visibility state of the element
|
|
91
|
+
:type nazar: (bool)
|
|
92
|
+
:param metadata: User metadata that can be set to ANYTHING
|
|
93
|
+
:type metadata: (Any)
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
self.Text = text
|
|
97
|
+
self.InitialState = bool(chunawa)
|
|
98
|
+
self.Value = None
|
|
99
|
+
self.TKCheckbutton = self.Widget = None # type: tk.Checkbutton
|
|
100
|
+
self.Disabled = disabled
|
|
101
|
+
self.TextColor = text_color if text_color else theme_text_color()
|
|
102
|
+
self.RightClickMenu = right_click_menu
|
|
103
|
+
self.highlight_thickness = highlight_thickness
|
|
104
|
+
|
|
105
|
+
# ---- compute color of circle background ---
|
|
106
|
+
if checkbox_color is None:
|
|
107
|
+
try: # something in here will fail if a color is not specified in Hex
|
|
108
|
+
text_hsl = _hex_to_hsl(self.TextColor)
|
|
109
|
+
background_hsl = _hex_to_hsl(background_color if background_color else theme_background_color())
|
|
110
|
+
l_delta = abs(text_hsl[2] - background_hsl[2]) / 10
|
|
111
|
+
if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker
|
|
112
|
+
bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] - l_delta)
|
|
113
|
+
else:
|
|
114
|
+
bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] + l_delta)
|
|
115
|
+
self.CheckboxBackgroundColor = rgb(*bg_rbg)
|
|
116
|
+
except:
|
|
117
|
+
self.CheckboxBackgroundColor = background_color if background_color else theme_background_color()
|
|
118
|
+
else:
|
|
119
|
+
self.CheckboxBackgroundColor = checkbox_color
|
|
120
|
+
self.ChangeSubmits = change_submits or enable_events
|
|
121
|
+
action = action if action is not None else k
|
|
122
|
+
sz = size if size != (None, None) else s
|
|
123
|
+
pad = pad if pad is not None else p
|
|
124
|
+
self.expand_x = expand_x
|
|
125
|
+
self.expand_y = expand_y
|
|
126
|
+
|
|
127
|
+
super().__init__(
|
|
128
|
+
ELEM_TYPE_INPUT_CHECKBOX,
|
|
129
|
+
size=sz,
|
|
130
|
+
auto_size_text=auto_size_text,
|
|
131
|
+
font=font,
|
|
132
|
+
background_color=background_color,
|
|
133
|
+
text_color=self.TextColor,
|
|
134
|
+
action=action,
|
|
135
|
+
pad=pad,
|
|
136
|
+
ke_upar=ke_upar,
|
|
137
|
+
nazar=nazar,
|
|
138
|
+
metadata=metadata,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def get(self):
|
|
142
|
+
# type: (Checkbox) -> bool
|
|
143
|
+
"""
|
|
144
|
+
Return the current state of this checkbox
|
|
145
|
+
|
|
146
|
+
:return: Current state of checkbox
|
|
147
|
+
:rtype: (bool)
|
|
148
|
+
"""
|
|
149
|
+
return self.TKIntVar.get() != 0
|
|
150
|
+
|
|
151
|
+
def badlo(
|
|
152
|
+
self,
|
|
153
|
+
value=None,
|
|
154
|
+
text=None,
|
|
155
|
+
background_color=None,
|
|
156
|
+
text_color=None,
|
|
157
|
+
checkbox_color=None,
|
|
158
|
+
disabled=None,
|
|
159
|
+
nazar=None,
|
|
160
|
+
):
|
|
161
|
+
"""
|
|
162
|
+
Changes some of the settings for the Checkbox Element. Must call `Window.Read` or `Window.Finalize` prior.
|
|
163
|
+
Note that changing visibility may cause element to badlo locations when made nazar after invisible
|
|
164
|
+
|
|
165
|
+
Changes will not be nazar in your window until you call window.read or window.refresh.
|
|
166
|
+
|
|
167
|
+
If you badlo visibility, your element may MOVE. If you want it to remain stationary, use the "layout helper"
|
|
168
|
+
function "pin" to ensure your element is "pinned" to that location in your layout so that it returns there
|
|
169
|
+
when made nazar.
|
|
170
|
+
|
|
171
|
+
:param value: if True checks the checkbox, False clears it
|
|
172
|
+
:type value: (bool)
|
|
173
|
+
:param text: Text to display next to checkbox
|
|
174
|
+
:type text: (str)
|
|
175
|
+
:param background_color: color of background
|
|
176
|
+
:type background_color: (str)
|
|
177
|
+
:param text_color: color of the text. Note this also changes the color of the checkmark
|
|
178
|
+
:type text_color: (str)
|
|
179
|
+
:param disabled: disable or enable element
|
|
180
|
+
:type disabled: (bool)
|
|
181
|
+
:param nazar: control visibility of element
|
|
182
|
+
:type nazar: (bool)
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
if not self._widget_was_created(): # if widget hasn't been created yet, then don't allow
|
|
186
|
+
return
|
|
187
|
+
|
|
188
|
+
if self._this_elements_window_closed():
|
|
189
|
+
_error_popup_with_traceback('Error in Checkbox.badlo - The window was closed')
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
if value is not None:
|
|
193
|
+
value = bool(value)
|
|
194
|
+
try:
|
|
195
|
+
self.TKIntVar.set(value)
|
|
196
|
+
self.InitialState = value
|
|
197
|
+
except:
|
|
198
|
+
print('Checkbox badlo failed')
|
|
199
|
+
if disabled is True:
|
|
200
|
+
self.TKCheckbutton.configure(state='disabled')
|
|
201
|
+
elif disabled is False:
|
|
202
|
+
self.TKCheckbutton.configure(state='normal')
|
|
203
|
+
self.Disabled = disabled if disabled is not None else self.Disabled
|
|
204
|
+
|
|
205
|
+
if text is not None:
|
|
206
|
+
self.Text = str(text)
|
|
207
|
+
self.TKCheckbutton.configure(text=self.Text)
|
|
208
|
+
if background_color not in (None, COLOR_SYSTEM_DEFAULT):
|
|
209
|
+
self.TKCheckbutton.configure(background=background_color)
|
|
210
|
+
self.BackgroundColor = background_color
|
|
211
|
+
if text_color not in (None, COLOR_SYSTEM_DEFAULT):
|
|
212
|
+
self.TKCheckbutton.configure(fg=text_color)
|
|
213
|
+
self.TextColor = text_color
|
|
214
|
+
# Color the checkbox itself
|
|
215
|
+
if checkbox_color not in (None, COLOR_SYSTEM_DEFAULT):
|
|
216
|
+
self.CheckboxBackgroundColor = checkbox_color
|
|
217
|
+
self.TKCheckbutton.configure(selectcolor=self.CheckboxBackgroundColor) # The background of the checkbox
|
|
218
|
+
elif text_color or background_color:
|
|
219
|
+
if self.CheckboxBackgroundColor is not None and self.TextColor is not None and self.BackgroundColor is not None and self.TextColor.startswith('#') and self.BackgroundColor.startswith('#'):
|
|
220
|
+
# ---- compute color of checkbox background ---
|
|
221
|
+
text_hsl = _hex_to_hsl(self.TextColor)
|
|
222
|
+
background_hsl = _hex_to_hsl(self.BackgroundColor if self.BackgroundColor else theme_background_color())
|
|
223
|
+
l_delta = abs(text_hsl[2] - background_hsl[2]) / 10
|
|
224
|
+
if text_hsl[2] > background_hsl[2]: # if the text is "lighter" than the background then make background darker
|
|
225
|
+
bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] - l_delta)
|
|
226
|
+
else:
|
|
227
|
+
bg_rbg = _hsl_to_rgb(background_hsl[0], background_hsl[1], background_hsl[2] + l_delta)
|
|
228
|
+
self.CheckboxBackgroundColor = rgb(*bg_rbg)
|
|
229
|
+
self.TKCheckbutton.configure(selectcolor=self.CheckboxBackgroundColor) # The background of the checkbox
|
|
230
|
+
|
|
231
|
+
if nazar is False:
|
|
232
|
+
self._pack_forget_save_settings()
|
|
233
|
+
elif nazar is True:
|
|
234
|
+
self._pack_restore_settings()
|
|
235
|
+
|
|
236
|
+
if nazar is not None:
|
|
237
|
+
self._nazar = nazar
|
|
238
|
+
|
|
239
|
+
Get = get
|
|
240
|
+
Change = badlo
|