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,45 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkProgressBar.
|
|
4
|
+
|
|
5
|
+
derived from progressBar
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkProgressBar.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkProgressBar
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pygubu.plugins.customtkinter.widgets import CTkProgressBarBO
|
|
18
|
+
from scustomtkinter.sctk_progress_bar import sCTkProgressBar
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Builder definition section
|
|
23
|
+
#
|
|
24
|
+
widget_namespace = "scustomtkinter.sctk_progress_bar"
|
|
25
|
+
widget_classname = "sCTkProgressBar"
|
|
26
|
+
builder_namespace = "scustomtkinter"
|
|
27
|
+
section_name = "sCustomTkinter"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class sCTkProgressBarBO(CTkProgressBarBO):
|
|
31
|
+
class_ = sCTkProgressBar
|
|
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, sCTkProgressBarBO, widget_classname, ("ttk", section_name)
|
|
44
|
+
)
|
|
45
|
+
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkRadioButton
|
|
4
|
+
|
|
5
|
+
derived from radioButton
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkRadioButton.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkRadioButton
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pygubu.plugins.customtkinter.widgets import CTkRadioButtonBO
|
|
18
|
+
from scustomtkinter.sctk_radiobutton import sCTkRadioButton
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Builder definition section
|
|
23
|
+
#
|
|
24
|
+
widget_namespace = "scustomtkinter.sctk_radiobutton"
|
|
25
|
+
widget_classname = "sCTkRadioButton"
|
|
26
|
+
builder_namespace = "scustomtkinter"
|
|
27
|
+
section_name = "sCustomTkinter"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class sCTkRadioButtonBO(CTkRadioButtonBO):
|
|
31
|
+
class_ = sCTkRadioButton
|
|
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, sCTkRadioButtonBO, widget_classname, ("ttk", section_name)
|
|
44
|
+
)
|
|
45
|
+
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkSMeterBar
|
|
4
|
+
|
|
5
|
+
Pygubu Builder Object for a bar style s-meter, pwr and swr.
|
|
6
|
+
"""
|
|
7
|
+
import ast
|
|
8
|
+
import pygubu
|
|
9
|
+
|
|
10
|
+
from pygubu.api.v1 import (
|
|
11
|
+
BuilderObject,
|
|
12
|
+
register_widget,
|
|
13
|
+
register_custom_property
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Import the native custom class
|
|
17
|
+
from scustomtkinter.themeable_widget import parse_font_property
|
|
18
|
+
from scustomtkinter.sctk_smeter_bar import sCTkSMeterBar
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Builder definition section
|
|
22
|
+
#
|
|
23
|
+
widget_namespace = "scustomtkinter.sctk_smeter_bar"
|
|
24
|
+
widget_classname = "sCTkSMeterBar"
|
|
25
|
+
builder_namespace = "scustomtkinter"
|
|
26
|
+
section_name = "sCustomTkinter"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class sCTkSMeterBarBO(BuilderObject):
|
|
30
|
+
class_ = sCTkSMeterBar
|
|
31
|
+
|
|
32
|
+
# Expose custom compound parameters alongside theme state configurations
|
|
33
|
+
OPTIONS_CUSTOM = ("width", "height", "fg_color", "swr_max_value", "swr_visible", "pwr_visible", "hide_lower_row", "hide_sig_row", "font", "scale_font")
|
|
34
|
+
|
|
35
|
+
# NOT CTkFrameBO.properties.
|
|
36
|
+
#
|
|
37
|
+
# Folding them in was tried and taken back out. The meter draws on a canvas
|
|
38
|
+
# that covers the whole widget, so the frame underneath is never visible:
|
|
39
|
+
# border_color, border_width and corner_radius appeared in the inspector
|
|
40
|
+
# and did nothing at all. A property that cannot work is worse than an
|
|
41
|
+
# absent one.
|
|
42
|
+
#
|
|
43
|
+
# fg_color IS listed above, because the widget paints the CANVAS with it --
|
|
44
|
+
# see sCTkSMeterBar.configure(). It was reaching sCTkSMeter and not this
|
|
45
|
+
# widget before, inherited from somewhere rather than declared, so the pair
|
|
46
|
+
# disagreed about a property they both support.
|
|
47
|
+
#
|
|
48
|
+
# corner_radius is the real loss: rounding the meter would mean rounding
|
|
49
|
+
# the canvas, which Tk cannot do to a canvas widget. It would have to be
|
|
50
|
+
# drawn -- a rounded rectangle filling the canvas in the parent's colour,
|
|
51
|
+
# masking the corners. Possible, not free.
|
|
52
|
+
properties = OPTIONS_CUSTOM
|
|
53
|
+
|
|
54
|
+
def _process_property_value(self, pname, value):
|
|
55
|
+
if pname in ("font", "scale_font"):
|
|
56
|
+
# Shared parser: Pygubu's fontentry emits a Tk font STRING, and
|
|
57
|
+
# "{}" for "no style selected" -- passed through, that reaches a
|
|
58
|
+
# canvas item as TclError: unknown font style "".
|
|
59
|
+
return parse_font_property(value)
|
|
60
|
+
if pname in ("width", "height"):
|
|
61
|
+
return int(value)
|
|
62
|
+
elif pname == "swr_max_value":
|
|
63
|
+
return float(value)
|
|
64
|
+
elif pname in ("swr_visible", "pwr_visible", "hide_lower_row", "hide_sig_row"):
|
|
65
|
+
if value == "True":
|
|
66
|
+
return True
|
|
67
|
+
else:
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
return super()._process_property_value(pname, value)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Register the widget into Pygubu's parsing engine
|
|
74
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
75
|
+
|
|
76
|
+
register_widget(builder_id, sCTkSMeterBarBO, 'sCTkSMeterBar', ("ttk", section_name))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# Register custom attribute fields to display inside the Designer properties panel
|
|
81
|
+
|
|
82
|
+
register_custom_property(
|
|
83
|
+
builder_id,
|
|
84
|
+
"width",
|
|
85
|
+
"naturalnumber",
|
|
86
|
+
help="Set total width in pixels of the meter"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
register_custom_property(
|
|
90
|
+
builder_id,
|
|
91
|
+
"height",
|
|
92
|
+
"naturalnumber",
|
|
93
|
+
help="Set height in pixels of the meter"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
register_custom_property(
|
|
98
|
+
builder_id,
|
|
99
|
+
"swr_max_value",
|
|
100
|
+
"realnumber",
|
|
101
|
+
help="largest value for signal on scale"
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
register_custom_property(
|
|
105
|
+
builder_id,
|
|
106
|
+
"swr_visible",
|
|
107
|
+
"choice",values=("True","False"),
|
|
108
|
+
default_value="True",
|
|
109
|
+
help="Controls the visability of the SWR meter"
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
register_custom_property(
|
|
113
|
+
builder_id,
|
|
114
|
+
"pwr_visible",
|
|
115
|
+
"choice",values=("True","False"),
|
|
116
|
+
default_value="True",
|
|
117
|
+
help="Controls the visability of the SWR meter"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
register_custom_property(
|
|
122
|
+
builder_id,
|
|
123
|
+
"hide_lower_row",
|
|
124
|
+
"choice",values=("True","False"),
|
|
125
|
+
default_value="False",
|
|
126
|
+
help="Hides the PWR/SWR if True"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
register_custom_property(
|
|
130
|
+
builder_id,
|
|
131
|
+
"hide_sig_row",
|
|
132
|
+
"choice", values=("True","False"),
|
|
133
|
+
default_value="False",
|
|
134
|
+
help="Hides the S row, leaving SWR and PWR. The mirror of hide_lower_row: "
|
|
135
|
+
"the two together let one meter be split across two panels -- signal "
|
|
136
|
+
"under the receive frequency, power under the transmit one."
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
register_custom_property(
|
|
140
|
+
builder_id, "font", "fontentry",
|
|
141
|
+
help='Font for the captions -- SIGNAL, SIG, SWR and PWR. Blank uses the theme font.'
|
|
142
|
+
)
|
|
143
|
+
register_custom_property(
|
|
144
|
+
builder_id, "scale_font", "fontentry",
|
|
145
|
+
help='Font for the scale tick labels. Blank uses the theme scale_font. Larger values can overlap on a narrow meter.'
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
register_custom_property(
|
|
149
|
+
builder_id, "fg_color", "colorentry",
|
|
150
|
+
help="Background the meter is drawn on. This paints the CANVAS, not the "
|
|
151
|
+
"frame behind it -- the canvas covers the whole widget. Blank uses "
|
|
152
|
+
"the theme's fg_color."
|
|
153
|
+
)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkSMeter.py
|
|
4
|
+
|
|
5
|
+
Pygubu Builder Object for a S Meter.
|
|
6
|
+
"""
|
|
7
|
+
import ast
|
|
8
|
+
import pygubu
|
|
9
|
+
|
|
10
|
+
from pygubu.api.v1 import (
|
|
11
|
+
BuilderObject,
|
|
12
|
+
register_widget,
|
|
13
|
+
register_custom_property
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Import the native custom class
|
|
17
|
+
from scustomtkinter.themeable_widget import parse_font_property
|
|
18
|
+
from scustomtkinter.sctk_smeter import sCTkSMeter
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Builder definition section
|
|
23
|
+
#
|
|
24
|
+
widget_namespace = "scustomtkinter.sctk_smeter"
|
|
25
|
+
widget_classname = "sCTkSMeter"
|
|
26
|
+
builder_namespace = "scustomtkinter"
|
|
27
|
+
section_name = "sCustomTkinter"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class sCTkSMeterBO(BuilderObject):
|
|
31
|
+
class_ = sCTkSMeter
|
|
32
|
+
|
|
33
|
+
# Expose custom compound parameters alongside theme state configurations
|
|
34
|
+
OPTIONS_CUSTOM = ("width", "height", "fg_color", "font", "scale_font")
|
|
35
|
+
|
|
36
|
+
# NOT CTkFrameBO.properties.
|
|
37
|
+
#
|
|
38
|
+
# Folding them in was tried and taken back out. The meter draws on a canvas
|
|
39
|
+
# that covers the whole widget, so the frame underneath is never visible:
|
|
40
|
+
# border_color, border_width and corner_radius appeared in the inspector
|
|
41
|
+
# and did nothing at all. A property that cannot work is worse than an
|
|
42
|
+
# absent one.
|
|
43
|
+
#
|
|
44
|
+
# fg_color IS listed, because the widget paints the canvas with it -- see
|
|
45
|
+
# sCTkSMeter.configure(). It was reaching only one of the two meters
|
|
46
|
+
# before, inherited from somewhere rather than declared, so the pair
|
|
47
|
+
# disagreed about a property they both support.
|
|
48
|
+
#
|
|
49
|
+
# corner_radius is the real loss: rounding the meter would mean rounding
|
|
50
|
+
# the canvas, which Tk cannot do to a canvas widget. It would have to be
|
|
51
|
+
# drawn -- a rounded rectangle filling the canvas in the parent's colour,
|
|
52
|
+
# masking the corners. Possible, not free.
|
|
53
|
+
properties = OPTIONS_CUSTOM
|
|
54
|
+
|
|
55
|
+
def _process_property_value(self, pname, value):
|
|
56
|
+
if pname in ("font", "scale_font"):
|
|
57
|
+
# Shared parser: Pygubu's fontentry emits a Tk font STRING, and
|
|
58
|
+
# "{}" for "no style selected" -- passed through, that reaches a
|
|
59
|
+
# canvas item as TclError: unknown font style "".
|
|
60
|
+
return parse_font_property(value)
|
|
61
|
+
if pname in ("width", "height"):
|
|
62
|
+
return int(value)
|
|
63
|
+
return super()._process_property_value(pname, value)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# Register the widget into Pygubu's parsing engine
|
|
67
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
68
|
+
|
|
69
|
+
register_widget(builder_id, sCTkSMeterBO, 'sCTkSMeter', ("ttk", section_name))
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# Register custom attribute fields to display inside the Designer properties panel
|
|
74
|
+
|
|
75
|
+
register_custom_property(
|
|
76
|
+
builder_id,
|
|
77
|
+
"width",
|
|
78
|
+
"naturalnumber",
|
|
79
|
+
help="Set total width in pixels of the meter"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
register_custom_property(
|
|
83
|
+
builder_id,
|
|
84
|
+
"height",
|
|
85
|
+
"naturalnumber",
|
|
86
|
+
help="Set height in pixels of the meter"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
register_custom_property(
|
|
90
|
+
builder_id, "font", "fontentry",
|
|
91
|
+
help='Font for the captions -- SIGNAL, SIG, SWR and PWR. Blank uses the theme font.'
|
|
92
|
+
)
|
|
93
|
+
register_custom_property(
|
|
94
|
+
builder_id, "scale_font", "fontentry",
|
|
95
|
+
help='Font for the scale tick labels. Blank uses the theme scale_font. Larger values can overlap on a narrow meter.'
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
register_custom_property(
|
|
99
|
+
builder_id, "fg_color", "colorentry",
|
|
100
|
+
help="Background the meter is drawn on. This paints the CANVAS, not the frame behind it -- the canvas covers the whole widget. Blank uses the theme's fg_color."
|
|
101
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkScrollableFrame
|
|
4
|
+
|
|
5
|
+
subclass of ScrollableFrame tuned for this ux
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkScrollableFrame.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkScrollableFrame
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
register_custom_property
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from pygubu.plugins.customtkinter import nsctk
|
|
19
|
+
from pygubu.plugins.customtkinter.scrollableframe import CTkScrollableFrameBO
|
|
20
|
+
from pygubu.api.v1 import copy_custom_property
|
|
21
|
+
|
|
22
|
+
from scustomtkinter.sctk_scrollable_frame import sCTkScrollableFrame
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Builder definition section
|
|
27
|
+
#
|
|
28
|
+
widget_namespace = "scustomtkinter.sctk_scrollable_frame"
|
|
29
|
+
widget_classname = "sCTkScrollableFrame"
|
|
30
|
+
builder_namespace = "scustomtkinter"
|
|
31
|
+
section_name = "sCustomTkinter"
|
|
32
|
+
|
|
33
|
+
container = True
|
|
34
|
+
# CTkScrollableFrame does some weird things
|
|
35
|
+
# with layout so disabled container layout here on purpose.
|
|
36
|
+
container_layout = False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class sCTkScrollableFrameBO(CTkScrollableFrameBO):
|
|
40
|
+
class_ = sCTkScrollableFrame
|
|
41
|
+
|
|
42
|
+
OPTIONS_CUSTOM = ('state',)
|
|
43
|
+
properties = CTkScrollableFrameBO.properties + OPTIONS_CUSTOM
|
|
44
|
+
|
|
45
|
+
OPTIONS_CUSTOM_DEFAULTS = {
|
|
46
|
+
'state': 'normal'
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
def code_imports(self):
|
|
50
|
+
# should return an iterable of (module, classname/function) to import
|
|
51
|
+
# or None
|
|
52
|
+
imports = [(widget_namespace, widget_classname)]
|
|
53
|
+
imports.extend(self.code_extra_imports())
|
|
54
|
+
return imports
|
|
55
|
+
|
|
56
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
57
|
+
register_widget(
|
|
58
|
+
builder_id, sCTkScrollableFrameBO, widget_classname, ("ttk", section_name)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# -----------------------------------------------------------------
|
|
63
|
+
# EXPOSE CUSTOM 'STATE' CHANNELS INSIDE PYGUBU DESIGNER PANEL
|
|
64
|
+
# -----------------------------------------------------------------
|
|
65
|
+
# 1. Define the UI element type mapping definitions
|
|
66
|
+
register_custom_property(builder_id,"state", "choice", values=("normal", "disabled"))
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkScrollbar
|
|
4
|
+
|
|
5
|
+
scrollbar
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkScrollbar.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkScrollbar
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pygubu.plugins.customtkinter import nsctk
|
|
18
|
+
from pygubu.plugins.customtkinter.widgets import CTkScrollbarBO
|
|
19
|
+
from pygubu.api.v1 import copy_custom_property
|
|
20
|
+
|
|
21
|
+
from scustomtkinter.sctk_scrollbar import sCTkScrollbar
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Builder definition section
|
|
26
|
+
#
|
|
27
|
+
widget_namespace = "scustomtkinter.sctk_scrollbar"
|
|
28
|
+
widget_classname = "sCTkScrollbar"
|
|
29
|
+
builder_namespace = "scustomtkinter"
|
|
30
|
+
section_name = "sCustomTkinter"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class sCTkScrollbarBO(CTkScrollbarBO):
|
|
34
|
+
class_ = sCTkScrollbar
|
|
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, sCTkScrollbarBO, widget_classname, ("ttk", section_name)
|
|
47
|
+
)
|
|
48
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkSegmentedButton
|
|
4
|
+
|
|
5
|
+
segmentedButton
|
|
6
|
+
|
|
7
|
+
UI source file: sCTkSegmentedButton.ui
|
|
8
|
+
"""
|
|
9
|
+
import tkinter as tk
|
|
10
|
+
import tkinter.ttk as ttk
|
|
11
|
+
from customtkinter import CTkSegmentedButton
|
|
12
|
+
from pygubu.api.v1 import (
|
|
13
|
+
BuilderObject,
|
|
14
|
+
register_widget,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from pygubu.plugins.customtkinter import nsctk
|
|
18
|
+
from pygubu.plugins.customtkinter.widgets import CTkSegmentedButtonBO
|
|
19
|
+
from pygubu.api.v1 import copy_custom_property
|
|
20
|
+
|
|
21
|
+
from scustomtkinter.sctk_segmentedbutton import sCTkSegmentedButton
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Builder definition section
|
|
26
|
+
#
|
|
27
|
+
widget_namespace = "scustomtkinter.sctk_segmentedbutton"
|
|
28
|
+
widget_classname = "sCTkSegmentedButton"
|
|
29
|
+
builder_namespace = "scustomtkinter"
|
|
30
|
+
section_name = "sCustomTkinter"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class sCTkSegmentedButtonBO(CTkSegmentedButtonBO):
|
|
34
|
+
class_ = sCTkSegmentedButton
|
|
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, sCTkSegmentedButtonBO, widget_classname, ("ttk", section_name)
|
|
47
|
+
)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/python3
|
|
2
|
+
"""
|
|
3
|
+
sCTkSelector Builder Object
|
|
4
|
+
"""
|
|
5
|
+
import pygubu
|
|
6
|
+
from pygubu.api.v1 import (
|
|
7
|
+
BuilderObject,
|
|
8
|
+
register_widget,
|
|
9
|
+
register_custom_property
|
|
10
|
+
)
|
|
11
|
+
from scustomtkinter.sctk_selector import sCTkSelector
|
|
12
|
+
from scustomtkinter.themeable_widget import parse_list_property
|
|
13
|
+
from pygubu.plugins.customtkinter.widgets import CTkFrameBO
|
|
14
|
+
|
|
15
|
+
widget_namespace = "scustomtkinter.sctk_selector"
|
|
16
|
+
widget_classname = "sCTkSelector"
|
|
17
|
+
builder_namespace = "scustomtkinter"
|
|
18
|
+
section_name = "sCustomTkinter"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class sCTkSelectorBO(BuilderObject):
|
|
22
|
+
class_ = sCTkSelector
|
|
23
|
+
|
|
24
|
+
# OPTIONS_STANDARD = ('height', 'width')
|
|
25
|
+
# 1. Append 'state' to your custom options tuple array
|
|
26
|
+
# grid_propagate is deliberately absent. pack_propagate() and
|
|
27
|
+
# grid_propagate() control whether a container resizes to fit its CHILDREN,
|
|
28
|
+
# and which applies depends on how those children are managed -- this
|
|
29
|
+
# widget packs its own, so grid_propagate could never have an effect. It
|
|
30
|
+
# was offered anyway, which made it look like a knob that did nothing.
|
|
31
|
+
OPTIONS_CUSTOM = ('items', 'multiple_choices', 'pack_propagate', 'state')
|
|
32
|
+
properties = CTkFrameBO.properties + OPTIONS_CUSTOM
|
|
33
|
+
|
|
34
|
+
OPTIONS_CUSTOM_DEFAULTS = {
|
|
35
|
+
'multiple_choices': 'True',
|
|
36
|
+
'items': '["Item 1", "Item 2"]',
|
|
37
|
+
'pack_propagate': 'True',
|
|
38
|
+
'state': 'normal'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# NOT a container. sCTkSelector builds and manages its own checkbox list
|
|
42
|
+
# from the `items` property, laying them out inside its internal
|
|
43
|
+
# checkboxes_frame. A child dropped in from the Designer would land in an
|
|
44
|
+
# unmanaged position and be destroyed by the next rebuild -- which happens
|
|
45
|
+
# whenever `items` changes. It inherits sCTkFrame and composes an
|
|
46
|
+
# sCTkScrollableFrame internally, which is what made it LOOK like a
|
|
47
|
+
# container to the Designer.
|
|
48
|
+
container = False
|
|
49
|
+
container_layout = False
|
|
50
|
+
|
|
51
|
+
def realize(self, parent, extra_init_args: dict = None):
|
|
52
|
+
if extra_init_args is None:
|
|
53
|
+
extra_init_args = {}
|
|
54
|
+
|
|
55
|
+
# Shared parser: accepts the quoted-list form, a bare comma-separated
|
|
56
|
+
# string, or a real list -- see parse_list_property(). The inspector
|
|
57
|
+
# default is the quoted-list form, which is what Pygubu Designer users
|
|
58
|
+
# expect and is the only one of the two text forms that can express a
|
|
59
|
+
# value containing a comma.
|
|
60
|
+
items_val = self.wmeta.properties.get('items', '["Item 1", "Item 2"]')
|
|
61
|
+
items_arg = parse_list_property(items_val, default=["Item 1", "Item 2"])
|
|
62
|
+
|
|
63
|
+
mult_choice = self.wmeta.properties.get('multiple_choices', 'True')
|
|
64
|
+
mult_choice_arg = str(mult_choice).lower() in ['true', '1', 'yes']
|
|
65
|
+
|
|
66
|
+
p_prop = self.wmeta.properties.get('pack_propagate', 'True')
|
|
67
|
+
p_prop_arg = str(p_prop).lower() in ['true', '1', 'yes']
|
|
68
|
+
|
|
69
|
+
# 2. Extract designer state choice
|
|
70
|
+
state_arg = self.wmeta.properties.get('state', 'normal')
|
|
71
|
+
|
|
72
|
+
init_args = {
|
|
73
|
+
'items': items_arg,
|
|
74
|
+
'multiple_choices': mult_choice_arg,
|
|
75
|
+
'pack_propagate': p_prop_arg,
|
|
76
|
+
'state': state_arg
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
for prop in self.OPTIONS_CUSTOM:
|
|
80
|
+
extra_init_args.pop(prop, None)
|
|
81
|
+
|
|
82
|
+
init_args.update(extra_init_args)
|
|
83
|
+
real_master = parent.widget if hasattr(parent, 'widget') else parent
|
|
84
|
+
self.widget = self.class_(real_master, **init_args)
|
|
85
|
+
return self.widget
|
|
86
|
+
|
|
87
|
+
def _set_property(self, target_widget, pname, value):
|
|
88
|
+
"""
|
|
89
|
+
Rebuilds the widget after a structural change.
|
|
90
|
+
|
|
91
|
+
Some properties cannot be expressed by configuring the existing
|
|
92
|
+
widget. A size only takes effect once Tk runs a geometry pass, and
|
|
93
|
+
turning pack_propagate back on merely tells it what to do at the next
|
|
94
|
+
one -- in an application the next event triggers that invisibly, but in
|
|
95
|
+
the Designer nothing else happens, so clearing a height appeared to do
|
|
96
|
+
nothing until an unrelated edit forced a repaint. `items` rebuilds the
|
|
97
|
+
checkbox list outright.
|
|
98
|
+
|
|
99
|
+
recreate_widget() is what the Designer itself does when you add or
|
|
100
|
+
delete a widget, which is why doing that by hand made the change
|
|
101
|
+
appear.
|
|
102
|
+
|
|
103
|
+
This hangs off _set_property, NOT set_property. The Designer edits a
|
|
104
|
+
property through the former -- confirmed by tracing, and it is the one
|
|
105
|
+
named in its own error messages ("Failed to set property 'x' on class
|
|
106
|
+
..."). set_property is never called, so sCTkTableviewBO's identical
|
|
107
|
+
rebuild, which hangs off that, has probably never fired either.
|
|
108
|
+
|
|
109
|
+
Deliberately NOT used for colours: rebuilding on every keystroke in a
|
|
110
|
+
colour field would be unpleasant, and a colour needs no rebuild.
|
|
111
|
+
"""
|
|
112
|
+
super()._set_property(target_widget, pname, value)
|
|
113
|
+
|
|
114
|
+
if pname in ("width", "height", "items", "pack_propagate"):
|
|
115
|
+
if hasattr(self, "builder") and hasattr(self.builder, "recreate_widget"):
|
|
116
|
+
try:
|
|
117
|
+
self.builder.recreate_widget(self)
|
|
118
|
+
except Exception:
|
|
119
|
+
# A widget not yet realized, or a builder that does not
|
|
120
|
+
# offer the call. Losing the rebuild costs a stale canvas,
|
|
121
|
+
# not correctness -- the .ui data is already updated.
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
def _code_set_property(self, targetid, pname, value, code_bag):
|
|
125
|
+
"""
|
|
126
|
+
The low-level code generation interception layer.
|
|
127
|
+
Ensures lists and booleans write as raw tokens, while text properties
|
|
128
|
+
like 'state' write out with proper Python string quotes.
|
|
129
|
+
"""
|
|
130
|
+
# 1. Handle properties that MUST be generated as raw unquoted Python code/tokens
|
|
131
|
+
if pname in ('items', 'multiple_choices', 'pack_propagate'):
|
|
132
|
+
clean_string = str(value).strip("'\"")
|
|
133
|
+
code_bag[pname] = clean_string
|
|
134
|
+
|
|
135
|
+
# 2. FIXED: Handle properties that MUST keep their string quote wrappers
|
|
136
|
+
elif pname == 'state':
|
|
137
|
+
# Force it to explicitly keep single quotes, preventing NameErrors at runtime
|
|
138
|
+
clean_string = str(value).strip("'\"")
|
|
139
|
+
code_bag[pname] = f"'{clean_string}'"
|
|
140
|
+
|
|
141
|
+
else:
|
|
142
|
+
super()._code_set_property(targetid, pname, value, code_bag)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
builder_id = f"{builder_namespace}.{widget_classname}"
|
|
146
|
+
|
|
147
|
+
register_widget(
|
|
148
|
+
builder_id, sCTkSelectorBO, widget_classname, ("ttk", section_name)
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
register_custom_property(
|
|
152
|
+
builder_id,
|
|
153
|
+
'items',
|
|
154
|
+
'entry',
|
|
155
|
+
help='Preferred: ["A", "B", "C"]. Bare comma-separated (A, B, C) also works, but cannot contain a comma inside a value.'
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
register_custom_property(builder_id, 'multiple_choices', 'choice', values=('True', 'False'))
|
|
159
|
+
# 4. Register the new UI type as a dropdown option selection field
|
|
160
|
+
register_custom_property(builder_id, 'state', 'choice', values=('normal', 'disabled'))
|
|
161
|
+
|
|
162
|
+
# 2. Register custom UI types as standard True/False dropdown pickers
|
|
163
|
+
register_custom_property(
|
|
164
|
+
builder_id, 'pack_propagate', 'choice', values=('True', 'False'),
|
|
165
|
+
help="False stops the widget resizing to fit its checkboxes, so an "
|
|
166
|
+
"explicit width and height are honoured."
|
|
167
|
+
)
|