tkfluent 0.1.4__py3-none-any.whl → 0.1.6__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.
- tkflu/__init__.py +1 -0
- tkflu/__main__.py +32 -18
- tkflu/badge.py +12 -4
- tkflu/button.py +12 -3
- tkflu/bwm.py +10 -0
- tkflu/demos/demo.py +137 -0
- tkflu/demos/designer.py +19 -4
- tkflu/demos/screenshot.py +8 -0
- tkflu/demos/scroll.py +19 -0
- tkflu/designs/__init__.py +4 -1
- tkflu/designs/animation.py +2 -2
- tkflu/designs/button.py +4 -4
- tkflu/designs/design.py +20 -0
- tkflu/designs/fonts/__init__.py +16 -1
- tkflu/designs/fonts/segoe_fluent_icons.ttf +0 -0
- tkflu/designs/frame.py +2 -2
- tkflu/designs/menubar.py +2 -0
- tkflu/designs/renderer.py +19 -0
- tkflu/designs/scrollbar.py +17 -39
- tkflu/designs/text.py +5 -5
- tkflu/designs/window.py +4 -2
- tkflu/entry.py +8 -4
- tkflu/frame.py +3 -2
- tkflu/label.py +11 -8
- tkflu/listbox.py +1 -1
- tkflu/menu.py +13 -13
- tkflu/menubar.py +26 -26
- tkflu/popupmenu.py +1 -1
- tkflu/popupwindow.py +38 -14
- tkflu/scrollbar.py +347 -133
- tkflu/slider.py +113 -66
- tkflu/text.py +20 -12
- tkflu/togglebutton.py +98 -89
- tkflu/tooltip.py +6 -15
- {tkfluent-0.1.4.dist-info → tkfluent-0.1.6.dist-info}/METADATA +7 -4
- tkfluent-0.1.6.dist-info/RECORD +64 -0
- tkfluent-0.1.4.dist-info/RECORD +0 -59
- {tkfluent-0.1.4.dist-info → tkfluent-0.1.6.dist-info}/WHEEL +0 -0
tkflu/designs/text.py
CHANGED
@@ -23,7 +23,7 @@ def text(mode, state):
|
|
23
23
|
"radius": _r,
|
24
24
|
"text_color": "#646464",
|
25
25
|
"underline_fill": "#8a8a8a",
|
26
|
-
"underline_width": 1,
|
26
|
+
"underline_width": 1.4,
|
27
27
|
}
|
28
28
|
elif state == "hover":
|
29
29
|
return {
|
@@ -42,7 +42,7 @@ def text(mode, state):
|
|
42
42
|
"radius": _r,
|
43
43
|
"text_color": "#626262",
|
44
44
|
"underline_fill": "#8a8a8a",
|
45
|
-
"underline_width": 1,
|
45
|
+
"underline_width": 1.4,
|
46
46
|
}
|
47
47
|
elif state == "pressed":
|
48
48
|
return {
|
@@ -101,7 +101,7 @@ def text(mode, state):
|
|
101
101
|
"radius": _r,
|
102
102
|
"text_color": "#d1d1d1",
|
103
103
|
"underline_fill": "#989898",
|
104
|
-
"underline_width": 1,
|
104
|
+
"underline_width": 1.4,
|
105
105
|
}
|
106
106
|
elif state == "hover":
|
107
107
|
return {
|
@@ -121,7 +121,7 @@ def text(mode, state):
|
|
121
121
|
"text_color": "#d2d2d2",
|
122
122
|
|
123
123
|
"underline_fill": "#989898",
|
124
|
-
"underline_width": 1,
|
124
|
+
"underline_width": 1.4,
|
125
125
|
}
|
126
126
|
elif state == "pressed":
|
127
127
|
return {
|
@@ -160,5 +160,5 @@ def text(mode, state):
|
|
160
160
|
"radius": _r,
|
161
161
|
"text_color": "#757575",
|
162
162
|
"underline_fill": None,
|
163
|
-
"underline_width": 1,
|
163
|
+
"underline_width": 1.4,
|
164
164
|
}
|
tkflu/designs/window.py
CHANGED
@@ -7,7 +7,8 @@ def window(mode):
|
|
7
7
|
"back_color": "#cf392d",
|
8
8
|
"text_color": "#000000",
|
9
9
|
"text_hover_color": "#ffffff"
|
10
|
-
}
|
10
|
+
},
|
11
|
+
"transparent_color": "grey"
|
11
12
|
}
|
12
13
|
else:
|
13
14
|
return {
|
@@ -17,5 +18,6 @@ def window(mode):
|
|
17
18
|
"back_color": "#c42b1c",
|
18
19
|
"text_color": "#ffffff",
|
19
20
|
"text_hover_color": "#000000"
|
20
|
-
}
|
21
|
+
},
|
22
|
+
"transparent_color": "grey"
|
21
23
|
}
|
tkflu/entry.py
CHANGED
@@ -54,7 +54,7 @@ class FluEntryCanvas(DCanvas):
|
|
54
54
|
draw = FluEntryDraw
|
55
55
|
|
56
56
|
def create_round_rectangle(self,
|
57
|
-
x1, y1, x2, y2, r1, r2=None, temppath=None,
|
57
|
+
x1, y1, x2, y2, r1, r2=None, temppath=None, temppath2=None,
|
58
58
|
fill="transparent", fill_opacity=1, stop1="0.93", stop2="0.94",
|
59
59
|
outline="black", outline2="black", outline_opacity=1, outline2_opacity=1,
|
60
60
|
width=1
|
@@ -65,7 +65,8 @@ class FluEntryCanvas(DCanvas):
|
|
65
65
|
outline=outline, outline2=outline2, outline_opacity=outline_opacity, outline2_opacity=outline2_opacity,
|
66
66
|
width=width
|
67
67
|
)
|
68
|
-
|
68
|
+
from .designs.renderer import get_renderer
|
69
|
+
self._tkimg = self.svgdraw.create_svg_image(self._img, temppath2, way=get_renderer())
|
69
70
|
return self.create_image(x1, y1, anchor="nw", image=self._tkimg)
|
70
71
|
|
71
72
|
create_roundrect = create_round_rectangle
|
@@ -168,9 +169,12 @@ class FluEntry(FluEntryCanvas, DDrawWidget, FluToolTipBase):
|
|
168
169
|
|
169
170
|
self.entry.configure(background=_back_color, insertbackground=_text_color, foreground=_text_color,
|
170
171
|
disabledbackground=_back_color, disabledforeground=_text_color)
|
171
|
-
|
172
|
+
from .designs.renderer import get_renderer
|
173
|
+
if get_renderer() == 1:
|
174
|
+
width -= 1
|
175
|
+
height -= 1
|
172
176
|
self.element_border = self.create_round_rectangle(
|
173
|
-
0, 0, width, height, _radius, temppath=self.temppath,
|
177
|
+
0, 0, width, height, _radius, temppath=self.temppath, temppath2=self.temppath3,
|
174
178
|
fill=_back_color, fill_opacity=_back_opacity, stop1=_stop1, stop2=_stop2,
|
175
179
|
outline=_border_color, outline_opacity=_border_color_opacity, outline2=_border_color2,
|
176
180
|
outline2_opacity=_border_color2_opacity,
|
tkflu/frame.py
CHANGED
@@ -110,7 +110,8 @@ class FluFrameCanvas(DCanvas):
|
|
110
110
|
fill=fill, #fill_opacity=fill_opacity,
|
111
111
|
outline=outline, outline_opacity=outline_opacity, width=width
|
112
112
|
)
|
113
|
-
|
113
|
+
from .designs.renderer import get_renderer
|
114
|
+
self._tkimg = self.svgdraw.create_svg_image(self._img)
|
114
115
|
return self.create_image(x1, y1, anchor="nw", image=self._tkimg)
|
115
116
|
|
116
117
|
create_roundrect = create_round_rectangle
|
@@ -194,7 +195,7 @@ class FluFrame(Frame, DObject, FluGradient):
|
|
194
195
|
back_colors = self.generate_hex2hex(self.attributes.back_color, n["back_color"], steps=animation_steps)
|
195
196
|
for i in range(animation_steps):
|
196
197
|
def update(ii=i): # 使用默认参数立即捕获i的值
|
197
|
-
print(back_colors[ii])
|
198
|
+
#print(back_colors[ii])
|
198
199
|
self._draw(tempcolor=back_colors[ii])
|
199
200
|
self.update()
|
200
201
|
|
tkflu/label.py
CHANGED
@@ -67,14 +67,17 @@ class FluLabel(DDrawWidget, FluToolTipBase, FluGradient):
|
|
67
67
|
from .designs.animation import get_animation_step_time
|
68
68
|
animation_step_time = get_animation_step_time()
|
69
69
|
|
70
|
-
if
|
71
|
-
if self
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
70
|
+
if not animation_steps == 0 or not animation_step_time == 0:
|
71
|
+
if hasattr(self, "tk"):
|
72
|
+
if self.attributes.text_color != m["text_color"]:
|
73
|
+
text_colors = self.generate_hex2hex(self.attributes.text_color, m["text_color"], steps=animation_steps)
|
74
|
+
for i in range(animation_steps):
|
75
|
+
def update(ii=i): # 使用默认参数立即捕获i的值
|
76
|
+
self._draw(tempcolor=text_colors[ii])
|
77
|
+
|
78
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
78
79
|
self.dconfigure(
|
79
80
|
text_color=m["text_color"]
|
80
81
|
)
|
82
|
+
if hasattr(self, "tk"):
|
83
|
+
self._draw()
|
tkflu/listbox.py
CHANGED
@@ -40,7 +40,7 @@ class FluListBoxCanvas(DCanvas):
|
|
40
40
|
x1, y1, x2, y2, r1, r2, temppath=temppath,
|
41
41
|
fill=fill, outline=outline, outline2=outline2, width=width
|
42
42
|
)
|
43
|
-
self._tkimg = self.svgdraw.
|
43
|
+
self._tkimg = self.svgdraw.create_svg_image(self._img)
|
44
44
|
return self.create_image(x1, y1, anchor="nw", image=self._tkimg)
|
45
45
|
|
46
46
|
create_roundrect = create_round_rectangle
|
tkflu/menu.py
CHANGED
@@ -4,7 +4,7 @@ from .tooltip import FluToolTipBase
|
|
4
4
|
|
5
5
|
|
6
6
|
class FluMenu(FluPopupMenu, FluToolTipBase):
|
7
|
-
def __init__(self, *args, **kwargs):
|
7
|
+
def __init__(self, height=None, *args, **kwargs):
|
8
8
|
super().__init__(*args, **kwargs)
|
9
9
|
|
10
10
|
def _init(self, mode, style):
|
@@ -25,16 +25,14 @@ class FluMenu(FluPopupMenu, FluToolTipBase):
|
|
25
25
|
|
26
26
|
self.theme(mode=mode, style=style)
|
27
27
|
|
28
|
-
def add_command(self, custom_widget=None, width=
|
28
|
+
def add_command(self, custom_widget=None, width=None, label: str = "", **kwargs):
|
29
|
+
if width is None:
|
30
|
+
width = len(label)*8
|
29
31
|
if custom_widget:
|
30
32
|
widget = custom_widget(self)
|
31
33
|
else:
|
32
34
|
from .button import FluButton
|
33
35
|
widget = FluButton(self, width=width)
|
34
|
-
if "label" in kwargs:
|
35
|
-
label = kwargs.pop("label")
|
36
|
-
else:
|
37
|
-
label = ""
|
38
36
|
if "style" in kwargs:
|
39
37
|
style = kwargs.pop("style")
|
40
38
|
else:
|
@@ -66,16 +64,14 @@ class FluMenu(FluPopupMenu, FluToolTipBase):
|
|
66
64
|
widget.pack(side="top", fill="x", padx=1, pady=(1, 0))
|
67
65
|
self.dcget("actions")[id] = widget
|
68
66
|
|
69
|
-
def add_cascade(self, custom_widget=None, width=
|
67
|
+
def add_cascade(self, custom_widget=None, width=None, menu=None, label: str = "", **kwargs):
|
68
|
+
if width is None:
|
69
|
+
width = len(label)*8
|
70
70
|
if custom_widget:
|
71
71
|
widget = custom_widget(self)
|
72
72
|
else:
|
73
73
|
from .button import FluButton
|
74
74
|
widget = FluButton(self, width=width)
|
75
|
-
if "label" in kwargs:
|
76
|
-
label = kwargs.pop("label")
|
77
|
-
else:
|
78
|
-
label = ""
|
79
75
|
if "style" in kwargs:
|
80
76
|
style = kwargs.pop("style")
|
81
77
|
else:
|
@@ -86,9 +82,13 @@ class FluMenu(FluPopupMenu, FluToolTipBase):
|
|
86
82
|
id = widget._w
|
87
83
|
|
88
84
|
def command(event=None):
|
85
|
+
self.l1 = True
|
89
86
|
#print(menu._w)
|
90
87
|
|
91
|
-
menu.popup(widget.winfo_rootx()+widget.winfo_width()
|
88
|
+
menu.popup(widget.winfo_rootx()+widget.winfo_width(), widget.winfo_rooty()-5)
|
89
|
+
height = len(self.dcget("actions")) * 45
|
90
|
+
#print(height)
|
91
|
+
menu.window.geometry(f"100x{height}")
|
92
92
|
menu.window.deiconify()
|
93
93
|
menu.window.attributes("-topmost")
|
94
94
|
|
@@ -102,4 +102,4 @@ class FluMenu(FluPopupMenu, FluToolTipBase):
|
|
102
102
|
widget.theme(style=style)
|
103
103
|
|
104
104
|
widget.pack(side="top", fill="x", padx=1, pady=(1, 0))
|
105
|
-
self.dcget("actions")[id] = widget
|
105
|
+
self.dcget("actions")[id] = widget
|
tkflu/menubar.py
CHANGED
@@ -20,6 +20,7 @@ class FluMenuBar(Frame, DObject, FluGradient):
|
|
20
20
|
self.attributes = EasyDict(
|
21
21
|
{
|
22
22
|
"back_color": "#f3f3f3",
|
23
|
+
"border_color": "#e5e5e5",
|
23
24
|
|
24
25
|
"actions": {}
|
25
26
|
}
|
@@ -30,16 +31,14 @@ class FluMenuBar(Frame, DObject, FluGradient):
|
|
30
31
|
def show(self):
|
31
32
|
self.pack(fill="x")
|
32
33
|
|
33
|
-
def add_command(self, custom_widget=None, width=
|
34
|
+
def add_command(self, custom_widget=None, width=None, label: str = "", **kwargs):
|
35
|
+
if width is None:
|
36
|
+
width = len(label)*8
|
34
37
|
if custom_widget:
|
35
38
|
widget = custom_widget(self)
|
36
39
|
else:
|
37
40
|
from .button import FluButton
|
38
41
|
widget = FluButton(self, width=width)
|
39
|
-
if "label" in kwargs:
|
40
|
-
label = kwargs.pop("label")
|
41
|
-
else:
|
42
|
-
label = ""
|
43
42
|
if "style" in kwargs:
|
44
43
|
style = kwargs.pop("style")
|
45
44
|
else:
|
@@ -68,16 +67,14 @@ class FluMenuBar(Frame, DObject, FluGradient):
|
|
68
67
|
|
69
68
|
from .menu import FluMenu
|
70
69
|
|
71
|
-
def add_cascade(self, custom_widget=None, width=
|
70
|
+
def add_cascade(self, custom_widget=None, width=None, label: str = "", menu: FluMenu = None, **kwargs):
|
71
|
+
if width is None:
|
72
|
+
width = len(label)*8
|
72
73
|
if custom_widget:
|
73
74
|
widget = custom_widget(self)
|
74
75
|
else:
|
75
76
|
from .button import FluButton
|
76
77
|
widget = FluButton(self, width=width)
|
77
|
-
if "label" in kwargs:
|
78
|
-
label = kwargs.pop("label")
|
79
|
-
else:
|
80
|
-
label = ""
|
81
78
|
if "style" in kwargs:
|
82
79
|
style = kwargs.pop("style")
|
83
80
|
else:
|
@@ -89,7 +86,9 @@ class FluMenuBar(Frame, DObject, FluGradient):
|
|
89
86
|
|
90
87
|
def command():
|
91
88
|
menu.focus_set()
|
92
|
-
menu.popup(widget.winfo_rootx(), widget.winfo_rooty() + widget.winfo_height())
|
89
|
+
menu.popup(widget.winfo_rootx()-5, widget.winfo_rooty() + widget.winfo_height())
|
90
|
+
height = len(menu.dcget("actions")) * 45
|
91
|
+
menu.window.geometry(f"100x{height}")
|
93
92
|
menu.window.deiconify()
|
94
93
|
menu.window.attributes("-topmost")
|
95
94
|
|
@@ -144,31 +143,32 @@ class FluMenuBar(Frame, DObject, FluGradient):
|
|
144
143
|
if not animation_steps == 0 or not animation_step_time == 0:
|
145
144
|
if mode.lower() == "dark":
|
146
145
|
back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=animation_steps)
|
147
|
-
|
148
|
-
|
149
|
-
self.dconfigure(back_color=back_colors[ii])
|
150
|
-
self._draw()
|
151
|
-
|
152
|
-
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
146
|
+
border_colors = self.generate_hex2hex(self.attributes.border_color, m["border_color"],
|
147
|
+
steps=animation_steps)
|
153
148
|
else:
|
154
149
|
back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=animation_steps)
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
150
|
+
border_colors = self.generate_hex2hex(self.attributes.border_color, m["border_color"],
|
151
|
+
steps=animation_steps)
|
152
|
+
for i in range(animation_steps):
|
153
|
+
def update(ii=i): # 使用默认参数立即捕获i的值
|
154
|
+
self.dconfigure(back_color=back_colors[ii], border_color=border_colors[ii])
|
155
|
+
self._draw()
|
159
156
|
|
160
|
-
|
157
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
161
158
|
|
162
159
|
self.after(animation_steps * animation_step_time + 50, lambda: self.update_children())
|
163
160
|
else:
|
164
|
-
|
165
|
-
|
166
|
-
else:
|
167
|
-
self.dconfigure(back_color=m["back_color"])
|
161
|
+
self.dconfigure(back_color=m["back_color"])
|
162
|
+
self.dconfigure(border_color=m["border_color"])
|
168
163
|
self._draw()
|
169
164
|
|
170
165
|
def _draw(self, event=None):
|
171
166
|
self.config(background=self.attributes.back_color)
|
167
|
+
if not hasattr(self, "border"):
|
168
|
+
self.border = Frame(self, height=1.2, background=self.attributes.border_color)
|
169
|
+
else:
|
170
|
+
self.border.configure(background=self.attributes.border_color)
|
171
|
+
self.border.pack(fill="x", expand="yes", side="bottom")
|
172
172
|
|
173
173
|
def _event_configure(self, event=None):
|
174
174
|
self._draw(event)
|
tkflu/popupmenu.py
CHANGED
@@ -8,7 +8,7 @@ class FluPopupMenuWindow(FluPopupWindow):
|
|
8
8
|
|
9
9
|
|
10
10
|
class FluPopupMenu(FluFrame):
|
11
|
-
def __init__(self, *args, width=100, height=46, transparent_color=
|
11
|
+
def __init__(self, *args, width=100, height=46, transparent_color=None, style="popupmenu", **kwargs):
|
12
12
|
self.window = FluPopupMenuWindow(transparent_color=transparent_color, width=width, height=height)
|
13
13
|
|
14
14
|
super().__init__(self.window, *args, style=style, **kwargs)
|
tkflu/popupwindow.py
CHANGED
@@ -1,23 +1,40 @@
|
|
1
1
|
from tkinter import Toplevel
|
2
2
|
|
3
|
+
from vbuild import hasSass
|
4
|
+
|
3
5
|
|
4
6
|
class FluPopupWindow(Toplevel):
|
5
|
-
def __init__(self, *args, transparent_color=
|
7
|
+
def __init__(self, *args, transparent_color=None, mode="light", width=100, height=46, custom=True, **kwargs):
|
6
8
|
super().__init__(*args, background=transparent_color, **kwargs)
|
7
9
|
|
8
10
|
self.theme(mode=mode)
|
9
11
|
|
12
|
+
self._transparent_color = transparent_color
|
13
|
+
|
10
14
|
if width > 0 and height > 0:
|
11
15
|
self.geometry(f"{width}x{height}")
|
12
16
|
|
13
17
|
if custom:
|
14
|
-
self.transient_color = transparent_color
|
15
18
|
self.overrideredirect(True)
|
16
|
-
|
19
|
+
|
20
|
+
self._draw()
|
17
21
|
|
18
22
|
self.withdraw()
|
19
23
|
|
20
24
|
self.bind("<FocusOut>", self._event_focusout, add="+")
|
25
|
+
self.bind("<Configure>", self._draw)
|
26
|
+
|
27
|
+
def _draw(self, event=None):
|
28
|
+
if hasattr(self, "tk"):
|
29
|
+
if self.overrideredirect():
|
30
|
+
if self._transparent_color is None:
|
31
|
+
from .designs.window import window
|
32
|
+
self.transparent_color = window(self.mode)["transparent_color"]
|
33
|
+
else:
|
34
|
+
self.transparent_color = self._transparent_color
|
35
|
+
#print(self.transparent_color)
|
36
|
+
self.wm_attributes("-transparentcolor", self.transparent_color)
|
37
|
+
self.configure(background=self.transparent_color)
|
21
38
|
|
22
39
|
def _event_focusout(self, event=None):
|
23
40
|
"""self.wm_attributes("-alpha", 1)
|
@@ -39,28 +56,35 @@ class FluPopupWindow(Toplevel):
|
|
39
56
|
self.withdraw()
|
40
57
|
|
41
58
|
def popup(self, x, y):
|
42
|
-
self.geometry(f"+{x}+{y}")
|
43
|
-
#self.focus_set()
|
44
|
-
self.wm_attributes("-alpha", 0.0)
|
45
|
-
self.deiconify()
|
46
59
|
|
47
60
|
from .designs.animation import get_animation_steps, get_animation_step_time
|
48
61
|
|
49
62
|
FRAMES_COUNT = get_animation_steps()
|
50
63
|
FRAME_DELAY = get_animation_step_time()
|
51
64
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
65
|
+
#print(FRAMES_COUNT,FRAME_DELAY)
|
66
|
+
|
67
|
+
self.geometry(f"+{x}+{y}")
|
68
|
+
#self.focus_set()
|
69
|
+
if FRAMES_COUNT != 0 or FRAME_DELAY != 0:
|
70
|
+
self.wm_attributes("-alpha", 0.0)
|
71
|
+
self.deiconify()
|
72
|
+
|
73
|
+
def fade_in(step=0):
|
74
|
+
alpha = step / FRAMES_COUNT # 按帧数变化,从0到1
|
75
|
+
self.wm_attributes("-alpha", alpha)
|
76
|
+
if step < FRAMES_COUNT:
|
77
|
+
# 每执行一次,增加一次透明度,间隔由帧数决定
|
78
|
+
self.after(int(round(FRAME_DELAY*FRAMES_COUNT / FRAMES_COUNT)), lambda: fade_in(step + 1))
|
58
79
|
|
59
|
-
|
80
|
+
fade_in() # 启动动画
|
81
|
+
else:
|
82
|
+
self.deiconify()
|
60
83
|
|
61
84
|
def theme(self, mode=None):
|
62
85
|
if mode:
|
63
86
|
self.mode = mode
|
87
|
+
self._draw()
|
64
88
|
for widget in self.winfo_children():
|
65
89
|
if hasattr(widget, "theme"):
|
66
90
|
widget.theme(mode=self.mode.lower())
|