scustomtkinter 0.2.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.
- scustomtkinter/__init__.py +81 -0
- scustomtkinter/assets/images/error.png +0 -0
- scustomtkinter/assets/images/info.png +0 -0
- scustomtkinter/assets/images/warning.png +0 -0
- scustomtkinter/assets/sCTkThemes.json +1963 -0
- scustomtkinter/license_morecustomtkinterwidgets.txt +22 -0
- scustomtkinter/sctk_button_primary.py +366 -0
- scustomtkinter/sctk_button_secondary.py +354 -0
- scustomtkinter/sctk_button_tertiary.py +375 -0
- scustomtkinter/sctk_checkbox.py +270 -0
- scustomtkinter/sctk_combobox.py +155 -0
- scustomtkinter/sctk_core.py +15 -0
- scustomtkinter/sctk_dial.py +1472 -0
- scustomtkinter/sctk_dialog.py +701 -0
- scustomtkinter/sctk_dialog_toplevel.py +268 -0
- scustomtkinter/sctk_entry_primary.py +400 -0
- scustomtkinter/sctk_entry_secondary.py +342 -0
- scustomtkinter/sctk_file_explorer.py +879 -0
- scustomtkinter/sctk_frame.py +210 -0
- scustomtkinter/sctk_frame_labeled_primary.py +667 -0
- scustomtkinter/sctk_frame_labeled_secondary.py +598 -0
- scustomtkinter/sctk_frequency_display.py +636 -0
- scustomtkinter/sctk_label_primary.py +283 -0
- scustomtkinter/sctk_label_secondary.py +275 -0
- scustomtkinter/sctk_label_tertiary.py +278 -0
- scustomtkinter/sctk_messagebox.py +275 -0
- scustomtkinter/sctk_notebook.py +1103 -0
- scustomtkinter/sctk_optionmenu_border_mixin.py +203 -0
- scustomtkinter/sctk_optionmenu_primary.py +378 -0
- scustomtkinter/sctk_optionmenu_secondary.py +346 -0
- scustomtkinter/sctk_path_chooser.py +516 -0
- scustomtkinter/sctk_progress_bar.py +274 -0
- scustomtkinter/sctk_radiobutton.py +360 -0
- scustomtkinter/sctk_scroll_mixin.py +546 -0
- scustomtkinter/sctk_scrollable_frame.py +795 -0
- scustomtkinter/sctk_scrollbar.py +313 -0
- scustomtkinter/sctk_segmentedbutton.py +424 -0
- scustomtkinter/sctk_selector.py +581 -0
- scustomtkinter/sctk_separator.py +308 -0
- scustomtkinter/sctk_slider.py +264 -0
- scustomtkinter/sctk_smeter.py +405 -0
- scustomtkinter/sctk_smeter_bar.py +557 -0
- scustomtkinter/sctk_spinbox.py +664 -0
- scustomtkinter/sctk_switch.py +463 -0
- scustomtkinter/sctk_tableview.py +869 -0
- scustomtkinter/sctk_tabview.py +409 -0
- scustomtkinter/sctk_textbox_primary.py +291 -0
- scustomtkinter/sctk_textbox_secondary.py +225 -0
- scustomtkinter/sctk_toplevel.py +153 -0
- scustomtkinter/themeable_widget.py +938 -0
- scustomtkinter-0.2.1.dist-info/METADATA +336 -0
- scustomtkinter-0.2.1.dist-info/RECORD +101 -0
- scustomtkinter-0.2.1.dist-info/WHEEL +5 -0
- scustomtkinter-0.2.1.dist-info/entry_points.txt +2 -0
- scustomtkinter-0.2.1.dist-info/licenses/LICENSE +21 -0
- scustomtkinter-0.2.1.dist-info/licenses/scustomtkinter/license_morecustomtkinterwidgets.txt +22 -0
- scustomtkinter-0.2.1.dist-info/top_level.txt +2 -0
- scustomtkinter_pygubu/__init__.py +1 -0
- scustomtkinter_pygubu/designer/__init__.py +0 -0
- scustomtkinter_pygubu/designer/plugin.py +1854 -0
- scustomtkinter_pygubu/designer/properties.py +247 -0
- scustomtkinter_pygubu/sCTkButtonPrimarybo.py +46 -0
- scustomtkinter_pygubu/sCTkButtonSecondarybo.py +45 -0
- scustomtkinter_pygubu/sCTkButtonTertiarybo.py +44 -0
- scustomtkinter_pygubu/sCTkCheckBoxbo.py +45 -0
- scustomtkinter_pygubu/sCTkComboBoxbo.py +45 -0
- scustomtkinter_pygubu/sCTkCorebo.py +120 -0
- scustomtkinter_pygubu/sCTkDialbo.py +371 -0
- scustomtkinter_pygubu/sCTkDialogbo.py +397 -0
- scustomtkinter_pygubu/sCTkEntryPrimarybo.py +100 -0
- scustomtkinter_pygubu/sCTkEntrySecondarybo.py +98 -0
- scustomtkinter_pygubu/sCTkFileExplorerbo.py +189 -0
- scustomtkinter_pygubu/sCTkFrameLabeledPrimarybo.py +69 -0
- scustomtkinter_pygubu/sCTkFrameLabeledSecondarybo.py +71 -0
- scustomtkinter_pygubu/sCTkFramebo.py +46 -0
- scustomtkinter_pygubu/sCTkFrequencyDisplaybo.py +175 -0
- scustomtkinter_pygubu/sCTkLabelPrimarybo.py +45 -0
- scustomtkinter_pygubu/sCTkLabelSecondarybo.py +44 -0
- scustomtkinter_pygubu/sCTkLabelTertiarybo.py +45 -0
- scustomtkinter_pygubu/sCTkNotebookbo.py +392 -0
- scustomtkinter_pygubu/sCTkOptionMenuPrimarybo.py +45 -0
- scustomtkinter_pygubu/sCTkOptionMenuSecondarybo.py +39 -0
- scustomtkinter_pygubu/sCTkPathChooserbo.py +204 -0
- scustomtkinter_pygubu/sCTkProgressBarbo.py +45 -0
- scustomtkinter_pygubu/sCTkRadioButtonbo.py +45 -0
- scustomtkinter_pygubu/sCTkSMeterBarbo.py +153 -0
- scustomtkinter_pygubu/sCTkSMeterbo.py +101 -0
- scustomtkinter_pygubu/sCTkScrollableFramebo.py +66 -0
- scustomtkinter_pygubu/sCTkScrollbarbo.py +48 -0
- scustomtkinter_pygubu/sCTkSegmentedButtonbo.py +47 -0
- scustomtkinter_pygubu/sCTkSelectorbo.py +167 -0
- scustomtkinter_pygubu/sCTkSeparatorbo.py +141 -0
- scustomtkinter_pygubu/sCTkSliderbo.py +45 -0
- scustomtkinter_pygubu/sCTkSpinboxbo.py +200 -0
- scustomtkinter_pygubu/sCTkSwitchbo.py +45 -0
- scustomtkinter_pygubu/sCTkTableviewbo.py +188 -0
- scustomtkinter_pygubu/sCTkTabviewbo.py +226 -0
- scustomtkinter_pygubu/sCTkTextboxPrimarybo.py +45 -0
- scustomtkinter_pygubu/sCTkTextboxSecondarybo.py +45 -0
- scustomtkinter_pygubu/sCTkToplevelbo.py +55 -0
- scustomtkinter_pygubu/sCTkWidgetSetForPygubuDesigner.py +141 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkTabview
|
|
4
|
+
|
|
5
|
+
Built on top of CTkTabview.
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkTabview.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkTabview
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
copy_custom_property,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from pygubu.plugins.customtkinter import nsctk
|
|
19
|
+
from pygubu.plugins.customtkinter.tabview import CTkTabviewBO, CTkTabviewTabBO
|
|
20
|
+
from scustomtkinter.sctk_tabview import sCTkTabview
|
|
21
|
+
from scustomtkinter.sctk_frame import sCTkFrame
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Builder definition section
|
|
26
|
+
#
|
|
27
|
+
widget_namespace = "scustomtkinter.sctk_tabview"
|
|
28
|
+
widget_classname = "sCTkTabview"
|
|
29
|
+
builder_namespace = "scustomtkinter"
|
|
30
|
+
section_name = "sCustomTkinter"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class sCTkTabviewBO(CTkTabviewBO):
|
|
34
|
+
class_ = sCTkTabview
|
|
35
|
+
|
|
36
|
+
def code_imports(self):
|
|
37
|
+
# should return an iterable of (module, classname/function) to import
|
|
38
|
+
# or None
|
|
39
|
+
imports = [(widget_namespace, widget_classname)]
|
|
40
|
+
imports.extend(self.code_extra_imports())
|
|
41
|
+
return imports
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
45
|
+
register_widget(
|
|
46
|
+
builder_id, sCTkTabviewBO, widget_classname, ("ttk", section_name)
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# =====================================================================
|
|
51
|
+
# sCTkTabview.Tab
|
|
52
|
+
#
|
|
53
|
+
# A tab is not a widget you construct -- it is created BY its parent tabview,
|
|
54
|
+
# through add(). So this builder object has class_ = None and overrides
|
|
55
|
+
# realize() to call the parent's add() rather than instantiating anything.
|
|
56
|
+
# That is CTkTabviewTabBO's design and this inherits it; only the naming,
|
|
57
|
+
# the parent constraint and the generated code differ.
|
|
58
|
+
#
|
|
59
|
+
# WHAT add() RETURNS. sCTkTabview.add() hands back an sCTkFrame page wrapper
|
|
60
|
+
# nested inside the native tab frame, not the native frame itself -- see the
|
|
61
|
+
# widget's own docs. That is exactly what a container builder object wants:
|
|
62
|
+
# children dropped onto the tab land in the wrapper, which is a themed sCTk
|
|
63
|
+
# widget rather than a bare ctk.CTkFrame. No extra work is needed here to get
|
|
64
|
+
# that; realize() simply returns whatever add() gives it.
|
|
65
|
+
# =====================================================================
|
|
66
|
+
class sCTkTabviewTabBO(CTkTabviewTabBO):
|
|
67
|
+
# Only this tabview may hold this tab. Without the constraint the Designer
|
|
68
|
+
# would offer sCTkTabview.Tab as a child of anything, and dropping one
|
|
69
|
+
# elsewhere would fail at realize() when the parent turned out to have no
|
|
70
|
+
# add() method.
|
|
71
|
+
allowed_parents = (builder_id,)
|
|
72
|
+
|
|
73
|
+
def realize(self, parent, extra_init_args: dict = None):
|
|
74
|
+
"""
|
|
75
|
+
Creates the tab, renaming it if that name is already taken.
|
|
76
|
+
|
|
77
|
+
Native CTkTabview.add() raises ValueError on a duplicate name. Inside
|
|
78
|
+
the Designer that exception surfaces only on the console, where nobody
|
|
79
|
+
is looking -- the tab silently fails to appear and the tree and the
|
|
80
|
+
preview disagree about what exists.
|
|
81
|
+
|
|
82
|
+
A unique suffix is appended instead, and written back into the widget
|
|
83
|
+
metadata so the inspector's `label` field updates too. Typing "mark"
|
|
84
|
+
for a second tab therefore produces a visible "mark_2" rather than an
|
|
85
|
+
invisible error. That is feedback the user actually receives.
|
|
86
|
+
|
|
87
|
+
Deliberately NOT done in sCTkTabview itself: the widget keeps raising,
|
|
88
|
+
so application code that creates a duplicate tab still fails loudly
|
|
89
|
+
rather than quietly getting a renamed one. This leniency is a
|
|
90
|
+
design-time affordance, not a change to the widget's contract.
|
|
91
|
+
"""
|
|
92
|
+
view = parent.get_child_master()
|
|
93
|
+
name = self._get_tab_name()
|
|
94
|
+
|
|
95
|
+
# _name_list is CTkTabview's own record of tab names, in order.
|
|
96
|
+
existing = list(getattr(view, "_name_list", []))
|
|
97
|
+
if name in existing:
|
|
98
|
+
suffix = 2
|
|
99
|
+
while f"{name}_{suffix}" in existing:
|
|
100
|
+
suffix += 1
|
|
101
|
+
name = f"{name}_{suffix}"
|
|
102
|
+
# Write it back so the inspector and the generated code agree with
|
|
103
|
+
# what is actually on screen.
|
|
104
|
+
self.wmeta.properties["label"] = name
|
|
105
|
+
|
|
106
|
+
self.widget = view.add(name)
|
|
107
|
+
return self.widget
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def _find_tabview(widget):
|
|
111
|
+
"""Walk up from a page wrapper to the sCTkTabview that owns it."""
|
|
112
|
+
node = widget
|
|
113
|
+
for _ in range(6): # page -> native tab frame -> tabview
|
|
114
|
+
if node is None:
|
|
115
|
+
return None
|
|
116
|
+
if isinstance(node, sCTkTabview):
|
|
117
|
+
return node
|
|
118
|
+
node = getattr(node, "master", None)
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
def configure(self, target=None):
|
|
122
|
+
"""
|
|
123
|
+
Applies a changed `label` by renaming the live tab.
|
|
124
|
+
|
|
125
|
+
CTkTabviewTabBO.configure() is a no-op -- `pass` -- so editing the
|
|
126
|
+
label in the inspector updated the metadata but never touched the
|
|
127
|
+
widget: the design area kept the old name while the preview, which
|
|
128
|
+
rebuilds from scratch, showed the new one.
|
|
129
|
+
|
|
130
|
+
EVERYTHING IS DERIVED FROM self.widget, deliberately. An earlier
|
|
131
|
+
version stashed the parent view and the created name on the builder
|
|
132
|
+
object during realize() and read them back here -- which failed,
|
|
133
|
+
because Pygubu calls configure() on a builder object whose realize()
|
|
134
|
+
never ran. Tracing showed those instances arriving with the new label
|
|
135
|
+
correctly set but no instance state at all:
|
|
136
|
+
|
|
137
|
+
[TabBO.configure] view=False old=None new='sue'
|
|
138
|
+
|
|
139
|
+
The page wrapper is the only reliable anchor: walk up from it to find
|
|
140
|
+
the tabview, then find the wrapper in that tabview's page registry to
|
|
141
|
+
learn the name it is currently filed under.
|
|
142
|
+
"""
|
|
143
|
+
widget = getattr(self, "widget", None)
|
|
144
|
+
if widget is None:
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
view = self._find_tabview(widget)
|
|
148
|
+
if view is None:
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
# The name this page is currently registered under, found by identity
|
|
152
|
+
# rather than by trusting any stored value.
|
|
153
|
+
old_name = None
|
|
154
|
+
for name, page in getattr(view, "_sctk_pages", {}).items():
|
|
155
|
+
if page is widget:
|
|
156
|
+
old_name = name
|
|
157
|
+
break
|
|
158
|
+
if old_name is None:
|
|
159
|
+
return
|
|
160
|
+
|
|
161
|
+
new_name = self._get_tab_name()
|
|
162
|
+
if new_name == old_name:
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
existing = [n for n in getattr(view, "_name_list", []) if n != old_name]
|
|
166
|
+
if new_name in existing:
|
|
167
|
+
suffix = 2
|
|
168
|
+
while f"{new_name}_{suffix}" in existing:
|
|
169
|
+
suffix += 1
|
|
170
|
+
new_name = f"{new_name}_{suffix}"
|
|
171
|
+
self.wmeta.properties["label"] = new_name
|
|
172
|
+
|
|
173
|
+
try:
|
|
174
|
+
view.rename(old_name, new_name)
|
|
175
|
+
except Exception:
|
|
176
|
+
# Widget torn down mid-edit, or a native rename this build of
|
|
177
|
+
# CustomTkinter doesn't support. The preview rebuild still shows
|
|
178
|
+
# the new label, so this degrades rather than breaks.
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
def code_realize(self, boparent, code_identifier=None):
|
|
182
|
+
"""
|
|
183
|
+
Emits the tab creation line.
|
|
184
|
+
|
|
185
|
+
Overridden only to keep the generated code honest about which class
|
|
186
|
+
the returned page is: sCTkTabview.add() returns an sCTkFrame wrapper,
|
|
187
|
+
so the comment tells a reader what they are holding. The call itself
|
|
188
|
+
is identical to the parent implementation's.
|
|
189
|
+
"""
|
|
190
|
+
view = boparent.code_child_master()
|
|
191
|
+
tabid = self.code_identifier()
|
|
192
|
+
tab_name = self._get_tab_name()
|
|
193
|
+
return [f'{tabid} = {view}.add("{tab_name}") # returns an sCTkFrame']
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
tab_builder_id = f"{builder_namespace}.sCTkTabviewTab"
|
|
197
|
+
register_widget(
|
|
198
|
+
tab_builder_id,
|
|
199
|
+
sCTkTabviewTabBO,
|
|
200
|
+
f"{widget_classname}.Tab",
|
|
201
|
+
("ttk", section_name),
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
#
|
|
205
|
+
# Wire the parent/child relationship in both directions. Pygubu checks both:
|
|
206
|
+
# add_allowed_child() lets the Designer offer the tab when a tabview is
|
|
207
|
+
# selected, and allowed_parents on the class above stops it being offered
|
|
208
|
+
# anywhere else.
|
|
209
|
+
#
|
|
210
|
+
sCTkTabviewBO.add_allowed_child(tab_builder_id)
|
|
211
|
+
|
|
212
|
+
#
|
|
213
|
+
# CustomTkinter's own tab is still accepted, so existing .ui files that used
|
|
214
|
+
# CTkTabview.Tab inside an sCTkTabview keep loading. New designs should use
|
|
215
|
+
# sCTkTabview.Tab above -- it is the one that appears under the sCustomTkinter
|
|
216
|
+
# palette section.
|
|
217
|
+
#
|
|
218
|
+
sCTkTabviewBO.add_allowed_child(nsctk.CTkTabviewTab)
|
|
219
|
+
CTkTabviewTabBO.add_allowed_parent(builder_id)
|
|
220
|
+
|
|
221
|
+
# NOTE: an earlier version of this file also called
|
|
222
|
+
# sCTkTabviewBO.add_allowed_child(sCTkFrame)
|
|
223
|
+
# passing the CLASS. add_allowed_child() takes a builder id STRING, so that
|
|
224
|
+
# call silently matched nothing and had no effect. Removed rather than
|
|
225
|
+
# corrected: a tabview's children are tabs, and a frame belongs inside a tab
|
|
226
|
+
# rather than directly in the tabview.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkTextboxPrimary
|
|
4
|
+
|
|
5
|
+
update to ctktextbox
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkTextboxPrimary.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkTextbox
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pygubu.plugins.customtkinter.widgets import CTkTextboxBO
|
|
18
|
+
from scustomtkinter.sctk_textbox_primary import sCTkTextboxPrimary
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Builder definition section
|
|
23
|
+
#
|
|
24
|
+
widget_namespace = "scustomtkinter.sctk_textbox_primary"
|
|
25
|
+
widget_classname = "sCTkTextboxPrimary"
|
|
26
|
+
builder_namespace = "scustomtkinter"
|
|
27
|
+
section_name = "sCustomTkinter"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class sCTkTextboxPrimaryBO(CTkTextboxBO):
|
|
31
|
+
class_ = sCTkTextboxPrimary
|
|
32
|
+
|
|
33
|
+
def code_imports(self):
|
|
34
|
+
# should return an iterable of (module, classname/function) to import
|
|
35
|
+
# or None
|
|
36
|
+
imports = [(widget_namespace, widget_classname)]
|
|
37
|
+
imports.extend(self.code_extra_imports())
|
|
38
|
+
return imports
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
42
|
+
register_widget(
|
|
43
|
+
builder_id, sCTkTextboxPrimaryBO, widget_classname, ("ttk", section_name)
|
|
44
|
+
)
|
|
45
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkTextboxSecondary
|
|
4
|
+
|
|
5
|
+
based on ctktextbox
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkTextboxSecondary.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkTextbox
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pygubu.plugins.customtkinter.widgets import CTkTextboxBO
|
|
18
|
+
from scustomtkinter.sctk_textbox_secondary import sCTkTextboxSecondary
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Builder definition section
|
|
23
|
+
#
|
|
24
|
+
widget_namespace = "scustomtkinter.sctk_textbox_secondary"
|
|
25
|
+
widget_classname = "sCTkTextboxSecondary"
|
|
26
|
+
builder_namespace = "scustomtkinter"
|
|
27
|
+
section_name = "sCustomTkinter"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class sCTkTextboxSecondaryBO(CTkTextboxBO):
|
|
31
|
+
class_ = sCTkTextboxSecondary
|
|
32
|
+
|
|
33
|
+
def code_imports(self):
|
|
34
|
+
# should return an iterable of (module, classname/function) to import
|
|
35
|
+
# or None
|
|
36
|
+
imports = [(widget_namespace, widget_classname)]
|
|
37
|
+
imports.extend(self.code_extra_imports())
|
|
38
|
+
return imports
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
42
|
+
register_widget(
|
|
43
|
+
builder_id, sCTkTextboxSecondaryBO, widget_classname, ("ttk", section_name)
|
|
44
|
+
)
|
|
45
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
|
|
3
|
+
import tkinter as tk
|
|
4
|
+
import tkinter.ttk as ttk
|
|
5
|
+
|
|
6
|
+
from pygubu.api.v1 import (
|
|
7
|
+
BuilderObject,
|
|
8
|
+
register_widget,
|
|
9
|
+
register_custom_property
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from pygubu.plugins.customtkinter import nsctk
|
|
13
|
+
from pygubu.plugins.customtkinter.windows import CTkToplevelBO
|
|
14
|
+
from pygubu.api.v1 import copy_custom_property
|
|
15
|
+
|
|
16
|
+
from scustomtkinter.sctk_toplevel import sCTkToplevel
|
|
17
|
+
from pygubu.plugins.customtkinter._config import GROOT
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Builder definition section
|
|
23
|
+
#
|
|
24
|
+
widget_namespace = "scustomtkinter.sctk_toplevel"
|
|
25
|
+
# NOTE the capitalisation: sCTkToplevel, lowercase "l", matching the class in
|
|
26
|
+
# sctk_toplevel.py and CustomTkinter's own CTkToplevel. This was previously
|
|
27
|
+
# "sCTkTopLevel", which fed straight into code_imports() below and generated
|
|
28
|
+
# from scustomtkinter.sctk_toplevel import sCTkTopLevel
|
|
29
|
+
# -- a name that does not exist, so every generated file using this widget
|
|
30
|
+
# failed at import. It also made the builder id and the palette entry disagree
|
|
31
|
+
# with the rest of the library.
|
|
32
|
+
widget_classname = "sCTkToplevel"
|
|
33
|
+
builder_namespace = "scustomtkinter"
|
|
34
|
+
section_name = "sCustomTkinter"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class sCTkToplevelBO(CTkToplevelBO):
|
|
38
|
+
class_ = sCTkToplevel
|
|
39
|
+
container = True
|
|
40
|
+
|
|
41
|
+
def code_imports(self):
|
|
42
|
+
# should return an iterable of (module, classname/function) to import
|
|
43
|
+
# or None
|
|
44
|
+
return [(widget_namespace, widget_classname)]
|
|
45
|
+
|
|
46
|
+
# NOTE: unlike sCTkBO, CTkToplevelBO's own code_imports() has no
|
|
47
|
+
# conditional appearance_mode / color_theme handling -- those are CTk-only
|
|
48
|
+
# properties -- so overriding it here loses nothing.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
52
|
+
register_widget(
|
|
53
|
+
builder_id, sCTkToplevelBO, widget_classname, ("ttk", section_name), group=GROOT
|
|
54
|
+
)
|
|
55
|
+
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import tkinter as tk
|
|
3
|
+
from typing import List
|
|
4
|
+
from pygubu.component.plugin_engine import BuilderLoaderPlugin
|
|
5
|
+
from customtkinter import (CTkScrollableFrame)
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# EVERY WIDGET NEEDS A LINE HERE.
|
|
9
|
+
#
|
|
10
|
+
# These imports are what register the builder objects when an APPLICATION
|
|
11
|
+
# loads a .ui file. The Designer does not use them -- it imports the builder
|
|
12
|
+
# objects directly through designer/plugin.py -- so a widget missing from
|
|
13
|
+
# this list works perfectly while you design and fails the moment you run
|
|
14
|
+
# the generated code:
|
|
15
|
+
#
|
|
16
|
+
# AttributeError: 'list' object has no attribute 'startswith'
|
|
17
|
+
#
|
|
18
|
+
# raised from importlib, because pygubu fell through to get_module_for().
|
|
19
|
+
# sCTkNotebook, sCTkDialog and sCTkFileExplorer were all in that state.
|
|
20
|
+
#
|
|
21
|
+
# Import the sCustomTkinter Widgets (alphabetically)
|
|
22
|
+
# Format is "import foobo" for normal widgets that are selectable
|
|
23
|
+
# format is
|
|
24
|
+
# from foo import foo
|
|
25
|
+
# from foobo import (fooBO,builder_id as foo_builder_id)
|
|
26
|
+
# notice difference between "foorbo" (file name) and "fooBO" (class name within that file)
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
import scustomtkinter_pygubu.sCTkCorebo
|
|
30
|
+
import scustomtkinter_pygubu.sCTkToplevelbo
|
|
31
|
+
|
|
32
|
+
import scustomtkinter_pygubu.sCTkButtonPrimarybo
|
|
33
|
+
import scustomtkinter_pygubu.sCTkButtonSecondarybo
|
|
34
|
+
import scustomtkinter_pygubu.sCTkButtonTertiarybo
|
|
35
|
+
|
|
36
|
+
import scustomtkinter_pygubu.sCTkCheckBoxbo
|
|
37
|
+
import scustomtkinter_pygubu.sCTkComboBoxbo
|
|
38
|
+
|
|
39
|
+
import scustomtkinter_pygubu.sCTkDialbo
|
|
40
|
+
|
|
41
|
+
import scustomtkinter_pygubu.sCTkDialogbo
|
|
42
|
+
|
|
43
|
+
import scustomtkinter_pygubu.sCTkEntryPrimarybo
|
|
44
|
+
import scustomtkinter_pygubu.sCTkEntrySecondarybo
|
|
45
|
+
|
|
46
|
+
import scustomtkinter_pygubu.sCTkFileExplorerbo
|
|
47
|
+
|
|
48
|
+
import scustomtkinter_pygubu.sCTkFramebo
|
|
49
|
+
|
|
50
|
+
import scustomtkinter_pygubu.sCTkFrameLabeledPrimarybo
|
|
51
|
+
import scustomtkinter_pygubu.sCTkFrameLabeledSecondarybo
|
|
52
|
+
|
|
53
|
+
import scustomtkinter_pygubu.sCTkFrequencyDisplaybo
|
|
54
|
+
|
|
55
|
+
import scustomtkinter_pygubu.sCTkLabelPrimarybo
|
|
56
|
+
import scustomtkinter_pygubu.sCTkLabelSecondarybo
|
|
57
|
+
import scustomtkinter_pygubu.sCTkLabelTertiarybo
|
|
58
|
+
|
|
59
|
+
import scustomtkinter_pygubu.sCTkNotebookbo
|
|
60
|
+
|
|
61
|
+
import scustomtkinter_pygubu.sCTkOptionMenuPrimarybo
|
|
62
|
+
import scustomtkinter_pygubu.sCTkOptionMenuSecondarybo
|
|
63
|
+
|
|
64
|
+
import scustomtkinter_pygubu.sCTkPathChooserbo
|
|
65
|
+
|
|
66
|
+
import scustomtkinter_pygubu.sCTkProgressBarbo
|
|
67
|
+
|
|
68
|
+
import scustomtkinter_pygubu.sCTkRadioButtonbo
|
|
69
|
+
|
|
70
|
+
import scustomtkinter_pygubu.sCTkScrollableFramebo
|
|
71
|
+
|
|
72
|
+
import scustomtkinter_pygubu.sCTkScrollbarbo
|
|
73
|
+
|
|
74
|
+
import scustomtkinter_pygubu.sCTkSegmentedButtonbo
|
|
75
|
+
# from sCTkSegmentedButtonbo import (sCTkSegmentedButtonBO, builder_id as sCTkSegmentedButton_builder_id )
|
|
76
|
+
|
|
77
|
+
import scustomtkinter_pygubu.sCTkSelectorbo
|
|
78
|
+
|
|
79
|
+
import scustomtkinter_pygubu.sCTkSeparatorbo
|
|
80
|
+
|
|
81
|
+
import scustomtkinter_pygubu.sCTkSliderbo
|
|
82
|
+
|
|
83
|
+
import scustomtkinter_pygubu.sCTkSMeterbo
|
|
84
|
+
import scustomtkinter_pygubu.sCTkSMeterBarbo
|
|
85
|
+
|
|
86
|
+
import scustomtkinter_pygubu.sCTkSpinboxbo
|
|
87
|
+
|
|
88
|
+
import scustomtkinter_pygubu.sCTkSwitchbo
|
|
89
|
+
|
|
90
|
+
import scustomtkinter_pygubu.sCTkTabviewbo
|
|
91
|
+
|
|
92
|
+
import scustomtkinter_pygubu.sCTkTableviewbo
|
|
93
|
+
|
|
94
|
+
import scustomtkinter_pygubu.sCTkTextboxPrimarybo
|
|
95
|
+
import scustomtkinter_pygubu.sCTkTextboxSecondarybo
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# import sCTkTreeviewbo # undecied whether to include
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class sCTkPlugin(BuilderLoaderPlugin):
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def get_uid(cls) -> str:
|
|
105
|
+
"""Return plugin unique ID."""
|
|
106
|
+
return "scustomtkinter"
|
|
107
|
+
|
|
108
|
+
@classmethod
|
|
109
|
+
def get_dependencies(cls) -> List[str]:
|
|
110
|
+
"""Return a list of required plugins UID."""
|
|
111
|
+
return ["pygubu_customtkinter"]
|
|
112
|
+
|
|
113
|
+
def do_activate(self) -> bool:
|
|
114
|
+
spec = importlib.util.find_spec("scustomtkinter")
|
|
115
|
+
return spec is not None
|
|
116
|
+
|
|
117
|
+
def get_module_for(self, identifier: str) -> str:
|
|
118
|
+
# A STRING, not a list.
|
|
119
|
+
#
|
|
120
|
+
# pygubu calls this when a class in a .ui file is not already
|
|
121
|
+
# registered, then hands the result to importlib -- which does
|
|
122
|
+
# name.startswith("."), so a list raised:
|
|
123
|
+
#
|
|
124
|
+
# AttributeError: 'list' object has no attribute 'startswith'
|
|
125
|
+
#
|
|
126
|
+
# It went unnoticed for as long as it did because every widget was
|
|
127
|
+
# registered by the imports at the top of this file, so the fallback
|
|
128
|
+
# never ran. The first class to miss that list found it immediately.
|
|
129
|
+
# get_all_modules() below DOES return a list, which is what the two
|
|
130
|
+
# were confused with.
|
|
131
|
+
return "scustomtkinter_pygubu"
|
|
132
|
+
|
|
133
|
+
def get_all_modules(self):
|
|
134
|
+
return ["scustomtkinter_pygubu"]
|
|
135
|
+
|
|
136
|
+
def can_load(self, identifier: str) -> bool:
|
|
137
|
+
return identifier.startswith("scustomtkinter.")
|
|
138
|
+
|
|
139
|
+
def get_designer_plugin(self):
|
|
140
|
+
from scustomtkinter_pygubu.designer.plugin import sCTkDesignerPlugin
|
|
141
|
+
return sCTkDesignerPlugin()
|