tkfluent 0.1.1__tar.gz → 0.1.2__tar.gz
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.
- {tkfluent-0.1.1 → tkfluent-0.1.2}/PKG-INFO +1 -1
- {tkfluent-0.1.1 → tkfluent-0.1.2}/pyproject.toml +1 -1
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/__main__.py +3 -1
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/button.py +19 -12
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/bwm.py +10 -5
- tkfluent-0.1.2/tkflu/demos/designer.py +33 -0
- tkfluent-0.1.2/tkflu/demos/grad2.py +17 -0
- tkfluent-0.1.2/tkflu/demos/grad3.py +16 -0
- tkfluent-0.1.2/tkflu/designs/__init__.py +3 -0
- tkfluent-0.1.2/tkflu/designs/animation.py +37 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/gradient.py +2 -0
- tkfluent-0.1.2/tkflu/designs/label.py +10 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/menubar.py +0 -3
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/primary_color.py +5 -5
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/frame.py +20 -5
- tkfluent-0.1.2/tkflu/label.py +78 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/menu.py +1 -1
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/menubar.py +17 -12
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/thememanager.py +4 -19
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/togglebutton.py +10 -17
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/toplevel.py +17 -1
- tkfluent-0.1.1/tkflu/demos/grad2.py +0 -140
- tkfluent-0.1.1/tkflu/demos/grad3.py +0 -11
- tkfluent-0.1.1/tkflu/designs/__init__.py +0 -2
- tkfluent-0.1.1/tkflu/label.py +0 -65
- {tkfluent-0.1.1 → tkfluent-0.1.2}/README.md +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/__init__.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/badge.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/checkbox.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/constants.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/customwindow.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/customwindow2.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/defs.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/__init__.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/acrylic1.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/demo1.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/grad.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/test.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/tooltip.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/badge.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/button.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/design.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/entry.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/fonts/__init__.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/fonts/segoeui.ttf +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/frame.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/slider.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/text.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/tooltip.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/window.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/entry.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/icons.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/image.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/listbox.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/litenav.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/popupmenu.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/popupwindow.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/scrollbar.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/slider.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/text.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/tooltip.py +0 -0
- {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/window.py +0 -0
@@ -201,12 +201,17 @@ class FluButton(FluButtonCanvas, DDrawWidget, FluToolTipBase, FluGradient):
|
|
201
201
|
else:
|
202
202
|
self._light()
|
203
203
|
|
204
|
-
def _theme(self, mode, style,
|
204
|
+
def _theme(self, mode, style, animation_steps: int = None, animation_step_time: int = None):
|
205
|
+
if animation_steps is None:
|
206
|
+
from .designs.animation import get_animation_steps
|
207
|
+
animation_steps = get_animation_steps()
|
208
|
+
if animation_step_time is None:
|
209
|
+
from .designs.animation import get_animation_step_time
|
210
|
+
animation_step_time = get_animation_step_time()
|
205
211
|
r = button(mode, style, "rest")
|
206
212
|
h = button(mode, style, "hover")
|
207
213
|
p = button(mode, style, "pressed")
|
208
214
|
d = button(mode, style, "disabled")
|
209
|
-
steps = animate_steps
|
210
215
|
if self.dcget("state") == "normal":
|
211
216
|
if self.enter:
|
212
217
|
if self.button1:
|
@@ -217,35 +222,37 @@ class FluButton(FluButtonCanvas, DDrawWidget, FluToolTipBase, FluGradient):
|
|
217
222
|
now = r
|
218
223
|
else:
|
219
224
|
now = d
|
225
|
+
#print(animation_step_time)
|
226
|
+
#print(type(animation_step_time))
|
220
227
|
if hasattr(self.attributes.rest, "back_color"):
|
221
228
|
back_colors = self.generate_hex2hex(
|
222
|
-
self.attributes.rest.back_color, now["back_color"],
|
229
|
+
self.attributes.rest.back_color, now["back_color"], animation_steps
|
223
230
|
)
|
224
231
|
border_colors = self.generate_hex2hex(
|
225
|
-
self.attributes.rest.border_color, now["border_color"],
|
232
|
+
self.attributes.rest.border_color, now["border_color"], animation_steps
|
226
233
|
)
|
227
234
|
if self.attributes.rest.border_color2 is None:
|
228
235
|
self.attributes.rest.border_color2 = self.attributes.rest.border_color
|
229
236
|
if now["border_color2"] is None:
|
230
237
|
now["border_color2"] = now["border_color"]
|
231
238
|
border_colors2 = self.generate_hex2hex(
|
232
|
-
self.attributes.rest.border_color2, now["border_color2"],
|
239
|
+
self.attributes.rest.border_color2, now["border_color2"], animation_steps
|
233
240
|
)
|
234
241
|
text_colors = self.generate_hex2hex(
|
235
|
-
self.attributes.rest.text_color, now["text_color"],
|
242
|
+
self.attributes.rest.text_color, now["text_color"], animation_steps
|
236
243
|
)
|
237
244
|
import numpy as np
|
238
245
|
back_opacitys = np.linspace(
|
239
|
-
float(self.attributes.rest.back_opacity), float(now["back_opacity"]),
|
246
|
+
float(self.attributes.rest.back_opacity), float(now["back_opacity"]), animation_steps).tolist()
|
240
247
|
border_color_opacitys = np.linspace(
|
241
|
-
float(self.attributes.rest.border_color_opacity), float(now["border_color_opacity"]),
|
248
|
+
float(self.attributes.rest.border_color_opacity), float(now["border_color_opacity"]), animation_steps).tolist()
|
242
249
|
if self.attributes.rest.border_color2_opacity is None:
|
243
250
|
self.attributes.rest.border_color2_opacity = self.attributes.rest.border_color_opacity
|
244
251
|
if now["border_color2_opacity"] is None:
|
245
252
|
now["border_color2_opacity"] = now["border_color_opacity"]
|
246
253
|
border_color2_opacitys = np.linspace(
|
247
|
-
float(self.attributes.rest.border_color2_opacity), float(now["border_color2_opacity"]),
|
248
|
-
for i in range(
|
254
|
+
float(self.attributes.rest.border_color2_opacity), float(now["border_color2_opacity"]), animation_steps).tolist()
|
255
|
+
for i in range(animation_steps):
|
249
256
|
def update(ii=i):
|
250
257
|
from easydict import EasyDict
|
251
258
|
tempcolor = EasyDict(
|
@@ -263,8 +270,8 @@ class FluButton(FluButtonCanvas, DDrawWidget, FluToolTipBase, FluGradient):
|
|
263
270
|
)
|
264
271
|
self._draw(None, tempcolor)
|
265
272
|
|
266
|
-
self.after(i *
|
267
|
-
self.after(
|
273
|
+
self.after(i * animation_step_time, update)
|
274
|
+
#self.after(animation_steps * animation_step_time + 10, lambda: self._draw(None, None))
|
268
275
|
|
269
276
|
self.dconfigure(
|
270
277
|
rest={
|
@@ -126,20 +126,25 @@ class BWm(FluGradient):
|
|
126
126
|
else:
|
127
127
|
self._light()
|
128
128
|
|
129
|
-
def _theme(self, mode):
|
129
|
+
def _theme(self, mode, animation_steps: int = None, animation_step_time: int = None):
|
130
130
|
from .designs.window import window
|
131
131
|
n = window(mode)
|
132
132
|
"""if self.attributes.back_color is not None:
|
133
133
|
n["back_color"] = self.attributes.back_color"""
|
134
|
-
|
134
|
+
if animation_steps is None:
|
135
|
+
from .designs.animation import get_animation_steps
|
136
|
+
animation_steps = get_animation_steps()
|
137
|
+
if animation_step_time is None:
|
138
|
+
from .designs.animation import get_animation_step_time
|
139
|
+
animation_step_time = get_animation_step_time()
|
135
140
|
if self.dcget("back_color"):
|
136
|
-
back_colors = self.generate_hex2hex(self.dcget("back_color"), n["back_color"], steps=
|
137
|
-
for i in range(
|
141
|
+
back_colors = self.generate_hex2hex(self.dcget("back_color"), n["back_color"], steps=animation_steps)
|
142
|
+
for i in range(animation_steps):
|
138
143
|
def update(ii=i): # 使用默认参数立即捕获i的值
|
139
144
|
self.dconfigure(back_color=back_colors[ii])
|
140
145
|
self._draw()
|
141
146
|
|
142
|
-
self.after(i *
|
147
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
143
148
|
|
144
149
|
self.dconfigure(
|
145
150
|
back_color=n["back_color"],
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from tkflu import *
|
2
|
+
|
3
|
+
set_animation_steps(10)
|
4
|
+
set_animation_step_time(10)
|
5
|
+
|
6
|
+
root = FluWindow()
|
7
|
+
root.title("tkfluent designer")
|
8
|
+
root.geometry("500x300")
|
9
|
+
|
10
|
+
theme_manager = FluThemeManager(root)
|
11
|
+
|
12
|
+
menubar = FluMenuBar(root)
|
13
|
+
|
14
|
+
menu1 = FluMenu()
|
15
|
+
menu1.geometry("90x90")
|
16
|
+
menu1.add_command(label="Light", command=lambda: theme_manager.mode("light"))
|
17
|
+
menu1.add_command(label="Dark", command=lambda: theme_manager.mode("dark"))
|
18
|
+
|
19
|
+
def func1():
|
20
|
+
messagebox = FluToplevel()
|
21
|
+
messagebox.geometry("300x200")
|
22
|
+
|
23
|
+
label = FluLabel(messagebox, text="This is a example for tkfluent!", width=160, height=32)
|
24
|
+
label.pack(anchor="center")
|
25
|
+
|
26
|
+
menubar.add_command(label="File", style="standard", width=40, command=lambda: print("File -> Clicked"))
|
27
|
+
menubar.add_cascade(label="Theme Mode", style="standard", width=100, menu=menu1)
|
28
|
+
menubar.add_command(label="About", style="standard", width=40, command=lambda: func1())
|
29
|
+
|
30
|
+
menubar.show()
|
31
|
+
|
32
|
+
|
33
|
+
root.mainloop()
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from tkflu import *
|
2
|
+
|
3
|
+
set_animation_steps(20)
|
4
|
+
set_animation_step_time(50)
|
5
|
+
|
6
|
+
root = FluWindow()
|
7
|
+
|
8
|
+
theme_manager = FluThemeManager(root)
|
9
|
+
|
10
|
+
frame = FluFrame(root, mode="light", style="standard")
|
11
|
+
|
12
|
+
btn = FluButton(frame, text="Button", mode="light", style="standard", command=lambda: theme_manager.toggle())
|
13
|
+
btn.pack(padx=20, pady=20, fill="both", expand="yes")
|
14
|
+
|
15
|
+
frame.pack(padx=20, pady=20, fill="both", expand="yes")
|
16
|
+
|
17
|
+
root.mainloop()
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from tkflu import *
|
2
|
+
|
3
|
+
set_animation_steps(20)
|
4
|
+
set_animation_step_time(20)
|
5
|
+
|
6
|
+
root = FluWindow()
|
7
|
+
|
8
|
+
theme_manager = FluThemeManager(root)
|
9
|
+
|
10
|
+
button = FluButton(root, text="Button", mode="light", style="standard", command=lambda: theme_manager.toggle())
|
11
|
+
button.pack(padx=20, pady=20, fill="both", expand="yes")
|
12
|
+
|
13
|
+
label = FluLabel(root, text="Label", mode="light")
|
14
|
+
label.pack(padx=20, pady=20, fill="both", expand="yes")
|
15
|
+
|
16
|
+
root.mainloop()
|
@@ -0,0 +1,37 @@
|
|
1
|
+
from os import environ
|
2
|
+
|
3
|
+
|
4
|
+
def set_animation_steps(steps: int):
|
5
|
+
environ["tkfluent.animation_steps"] = str(steps)
|
6
|
+
|
7
|
+
def get_animation_steps():
|
8
|
+
return int(environ["tkfluent.animation_steps"])
|
9
|
+
|
10
|
+
def set_animation_step_time(step_time: int):
|
11
|
+
environ["tkfluent.animation_step_time"] = str(step_time)
|
12
|
+
|
13
|
+
def get_animation_step_time():
|
14
|
+
return int(environ["tkfluent.animation_step_time"])
|
15
|
+
|
16
|
+
if "tkfluent.animation_steps" not in environ:
|
17
|
+
set_animation_steps(10)
|
18
|
+
if "tkfluent.animation_step_time" not in environ:
|
19
|
+
set_animation_step_time(10)
|
20
|
+
|
21
|
+
|
22
|
+
class FluAnimation(object):
|
23
|
+
def animation_steps(self, steps: int = None):
|
24
|
+
if steps:
|
25
|
+
from os import environ
|
26
|
+
environ["tkfluent.animation_steps"] = str(steps)
|
27
|
+
else:
|
28
|
+
from os import environ
|
29
|
+
return int(environ["tkfluent.animation_steps"])
|
30
|
+
|
31
|
+
def animation_step_time(self, step_time: int = None):
|
32
|
+
if step_time:
|
33
|
+
from os import environ
|
34
|
+
environ["tkfluent.animation_step_time"] = str(step_time)
|
35
|
+
else:
|
36
|
+
from os import environ
|
37
|
+
return int(environ["tkfluent.animation_step_time"])
|
@@ -1,16 +1,16 @@
|
|
1
|
+
from os import environ
|
2
|
+
|
3
|
+
|
1
4
|
def set_primary_color(color: tuple = None):
|
2
|
-
from os import environ
|
3
5
|
from json import dumps
|
4
6
|
environ["tkfluent.primary_color"] = dumps(color)
|
5
7
|
|
6
|
-
|
7
8
|
def get_primary_color():
|
8
|
-
from os import environ
|
9
9
|
from json import loads
|
10
10
|
return loads(environ["tkfluent.primary_color"])
|
11
11
|
|
12
|
-
|
13
|
-
set_primary_color(("#005fb8", "#60cdff"))
|
12
|
+
if "tkfluent.primary_color" not in environ:
|
13
|
+
set_primary_color(("#005fb8", "#60cdff"))
|
14
14
|
|
15
15
|
|
16
16
|
class FluPrimaryColor(object):
|
@@ -180,16 +180,26 @@ class FluFrame(Frame, DObject, FluGradient):
|
|
180
180
|
else:
|
181
181
|
self._light()
|
182
182
|
|
183
|
-
def _theme(self, mode, style,
|
183
|
+
def _theme(self, mode, style, animation_steps: int = None, animation_step_time: int = None):
|
184
184
|
n = frame(mode, style)
|
185
|
+
|
186
|
+
if animation_steps is None:
|
187
|
+
from .designs.animation import get_animation_steps
|
188
|
+
animation_steps = get_animation_steps()
|
189
|
+
if animation_step_time is None:
|
190
|
+
from .designs.animation import get_animation_step_time
|
191
|
+
animation_step_time = get_animation_step_time()
|
192
|
+
|
185
193
|
if hasattr(self.attributes, "back_color") and hasattr(n, "back_color"):
|
186
|
-
back_colors = self.generate_hex2hex(self.attributes.back_color, n["back_color"], steps=
|
187
|
-
for i in range(
|
194
|
+
back_colors = self.generate_hex2hex(self.attributes.back_color, n["back_color"], steps=animation_steps)
|
195
|
+
for i in range(animation_steps):
|
188
196
|
def update(ii=i): # 使用默认参数立即捕获i的值
|
197
|
+
print(back_colors[ii])
|
189
198
|
self._draw(tempcolor=back_colors[ii])
|
199
|
+
self.update()
|
190
200
|
|
191
|
-
self.after(i *
|
192
|
-
self.after(
|
201
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
202
|
+
self.after(animation_steps * animation_step_time + 10, lambda: self._draw())
|
193
203
|
self.dconfigure(
|
194
204
|
back_color=n["back_color"],
|
195
205
|
border_color=n["border_color"],
|
@@ -310,5 +320,10 @@ class FluFrame(Frame, DObject, FluGradient):
|
|
310
320
|
height=self.canvas.winfo_height() - _border_width * 2 - _radius
|
311
321
|
)
|
312
322
|
|
323
|
+
self.update()
|
324
|
+
|
325
|
+
self.after(100, lambda: self.update())
|
326
|
+
self.after(100, lambda: self.config(background=_back_color))
|
327
|
+
|
313
328
|
def _event_configure(self, event=None):
|
314
329
|
self._draw(event)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
from tkdeft.windows.drawwidget import DDrawWidget
|
2
|
+
from .tooltip import FluToolTipBase
|
3
|
+
from .designs.gradient import FluGradient
|
4
|
+
|
5
|
+
|
6
|
+
class FluLabel(DDrawWidget, FluToolTipBase, FluGradient):
|
7
|
+
def __init__(self, *args,
|
8
|
+
text="",
|
9
|
+
width=120,
|
10
|
+
height=32,
|
11
|
+
font=None,
|
12
|
+
mode="light",
|
13
|
+
**kwargs):
|
14
|
+
self._init(mode)
|
15
|
+
|
16
|
+
super().__init__(*args, width=width, height=height, **kwargs)
|
17
|
+
|
18
|
+
self.dconfigure(
|
19
|
+
text=text,
|
20
|
+
)
|
21
|
+
|
22
|
+
from .defs import set_default_font
|
23
|
+
set_default_font(font, self.attributes)
|
24
|
+
|
25
|
+
def _init(self, mode):
|
26
|
+
|
27
|
+
from easydict import EasyDict
|
28
|
+
|
29
|
+
self.attributes = EasyDict(
|
30
|
+
{
|
31
|
+
"text": "",
|
32
|
+
"command": None,
|
33
|
+
"font": None,
|
34
|
+
|
35
|
+
"text_color": "#1b1b1b",
|
36
|
+
}
|
37
|
+
)
|
38
|
+
|
39
|
+
self.theme(mode=mode)
|
40
|
+
|
41
|
+
def _draw(self, event=None, tempcolor=None):
|
42
|
+
super()._draw(event)
|
43
|
+
|
44
|
+
self.delete("all")
|
45
|
+
|
46
|
+
if tempcolor:
|
47
|
+
_text_color = tempcolor
|
48
|
+
else:
|
49
|
+
_text_color = self.attributes.text_color
|
50
|
+
|
51
|
+
self.element_text = self.create_text(
|
52
|
+
self.winfo_width() / 2, self.winfo_height() / 2, anchor="center",
|
53
|
+
fill=_text_color, text=self.attributes.text, font=self.attributes.font
|
54
|
+
)
|
55
|
+
|
56
|
+
def theme(self, mode="light", animation_steps: int = None, animation_step_time: int = None):
|
57
|
+
from .designs.label import label
|
58
|
+
self.mode = mode
|
59
|
+
m = label(mode)
|
60
|
+
|
61
|
+
if animation_steps is None:
|
62
|
+
from .designs.animation import get_animation_steps
|
63
|
+
animation_steps = get_animation_steps()
|
64
|
+
if animation_step_time is None:
|
65
|
+
from .designs.animation import get_animation_step_time
|
66
|
+
animation_step_time = get_animation_step_time()
|
67
|
+
|
68
|
+
if hasattr(self, "tk"):
|
69
|
+
if self.attributes.text_color != m["text_color"]:
|
70
|
+
text_colors = self.generate_hex2hex(self.attributes.text_color, m["text_color"], steps=animation_steps)
|
71
|
+
for i in range(animation_steps):
|
72
|
+
def update(ii=i): # 使用默认参数立即捕获i的值
|
73
|
+
self._draw(tempcolor=text_colors[ii])
|
74
|
+
|
75
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
76
|
+
self.dconfigure(
|
77
|
+
text_color=m["text_color"]
|
78
|
+
)
|
@@ -88,7 +88,7 @@ class FluMenu(FluPopupMenu, FluToolTipBase):
|
|
88
88
|
def command(event=None):
|
89
89
|
#print(menu._w)
|
90
90
|
|
91
|
-
menu.popup(widget.winfo_rootx()+widget.winfo_width()+
|
91
|
+
menu.popup(widget.winfo_rootx()+widget.winfo_width()+self.winfo_width(), widget.winfo_rooty())
|
92
92
|
menu.window.deiconify()
|
93
93
|
menu.window.attributes("-topmost")
|
94
94
|
|
@@ -130,30 +130,35 @@ class FluMenuBar(Frame, DObject, FluGradient):
|
|
130
130
|
widget._draw()
|
131
131
|
widget.update()
|
132
132
|
|
133
|
-
def theme_myself(self, mode="light",
|
133
|
+
def theme_myself(self, mode="light", animation_steps: int = None, animation_step_time: int = None):
|
134
|
+
if animation_steps is None:
|
135
|
+
from .designs.animation import get_animation_steps
|
136
|
+
animation_steps = get_animation_steps()
|
137
|
+
if animation_step_time is None:
|
138
|
+
from .designs.animation import get_animation_step_time
|
139
|
+
animation_step_time = get_animation_step_time()
|
134
140
|
from .designs.menubar import menubar
|
135
141
|
m = menubar(mode)
|
136
142
|
self.mode = mode
|
137
|
-
if
|
138
|
-
if
|
139
|
-
back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=
|
140
|
-
for i in range(
|
143
|
+
if hasattr(self, "tk"):
|
144
|
+
if mode.lower() == "dark":
|
145
|
+
back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=animation_steps)
|
146
|
+
for i in range(animation_steps):
|
141
147
|
def update(ii=i): # 使用默认参数立即捕获i的值
|
142
148
|
self.dconfigure(back_color=back_colors[ii])
|
143
149
|
self._draw()
|
144
150
|
|
145
|
-
self.after(i *
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=10)
|
150
|
-
for i in range(10):
|
151
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
152
|
+
else:
|
153
|
+
back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=animation_steps)
|
154
|
+
for i in range(animation_steps):
|
151
155
|
def update(ii=i): # 使用默认参数立即捕获i的值
|
152
156
|
self.dconfigure(back_color=back_colors[ii])
|
153
157
|
self._draw()
|
154
158
|
|
155
|
-
self.after(i *
|
159
|
+
self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
|
156
160
|
|
161
|
+
self.after(animation_steps * animation_step_time + 50, lambda: self.update_children())
|
157
162
|
|
158
163
|
def _draw(self, event=None):
|
159
164
|
self.config(background=self.attributes.back_color)
|
@@ -13,7 +13,7 @@ class FluThemeManager(object):
|
|
13
13
|
self.mode(self._mode)
|
14
14
|
self._window.after(delay, lambda: self.mode(self._mode))
|
15
15
|
|
16
|
-
def mode(self, mode: str, delay: int or None =
|
16
|
+
def mode(self, mode: str, delay: int or None = 50):
|
17
17
|
def _():
|
18
18
|
self._mode = mode
|
19
19
|
if hasattr(self._window, "theme"):
|
@@ -40,27 +40,12 @@ class FluThemeManager(object):
|
|
40
40
|
if hasattr(widget, "update_children"):
|
41
41
|
widget.update_children()
|
42
42
|
widget.update()
|
43
|
-
#self._window.
|
43
|
+
#print(len(self._window.winfo_children()))
|
44
|
+
self._window.after(delay+len(self._window.winfo_children()), __)
|
44
45
|
|
45
46
|
def toggle(self, delay: int or None = None):
|
46
47
|
if self._mode == "light":
|
47
48
|
mode = "dark"
|
48
49
|
else:
|
49
50
|
mode = "light"
|
50
|
-
|
51
|
-
self._mode = mode
|
52
|
-
if hasattr(self._window, "theme"):
|
53
|
-
self._window.theme(mode=mode)
|
54
|
-
if hasattr(self._window, "_draw"):
|
55
|
-
self._window._draw()
|
56
|
-
self._window.update()
|
57
|
-
for widget in self._window.winfo_children():
|
58
|
-
if hasattr(widget, "theme"):
|
59
|
-
widget.theme(mode=mode)
|
60
|
-
if hasattr(widget, "_draw"):
|
61
|
-
widget._draw()
|
62
|
-
widget.update()
|
63
|
-
if delay:
|
64
|
-
self._window.after(delay, _)
|
65
|
-
else:
|
66
|
-
_()
|
51
|
+
self.mode(mode)
|
@@ -391,21 +391,14 @@ class FluToggleButton(FluToggleButtonCanvas, DDrawWidget, FluToolTipBase, FluGra
|
|
391
391
|
def invoke(self):
|
392
392
|
self.attributes.command()
|
393
393
|
|
394
|
-
def toggle(self,
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
"border_color2_opacity": "0.3",
|
403
|
-
"border_width": 1,
|
404
|
-
"radius": 6,
|
405
|
-
"text_color": "#000000",
|
406
|
-
:return:
|
407
|
-
"""
|
408
|
-
steps = animate_steps
|
394
|
+
def toggle(self, animation_steps: int = None, animation_step_time: int = None):
|
395
|
+
if animation_steps is None:
|
396
|
+
from .designs.animation import get_animation_steps
|
397
|
+
animation_steps = get_animation_steps()
|
398
|
+
if animation_step_time is None:
|
399
|
+
from .designs.animation import get_animation_step_time
|
400
|
+
animation_step_time = get_animation_step_time()
|
401
|
+
steps = animation_steps
|
409
402
|
check = self.attributes.check
|
410
403
|
uncheck = self.attributes.uncheck
|
411
404
|
if uncheck.pressed.border_color2 is None:
|
@@ -476,5 +469,5 @@ class FluToggleButton(FluToggleButtonCanvas, DDrawWidget, FluToolTipBase, FluGra
|
|
476
469
|
}
|
477
470
|
)
|
478
471
|
self._draw(None, tempcolor)
|
479
|
-
self.after(i*
|
480
|
-
self.after(steps*
|
472
|
+
self.after(i*animation_step_time, update)
|
473
|
+
self.after(steps*animation_step_time+10, lambda: self._draw(None, None))
|
@@ -18,12 +18,28 @@ class FluToplevel(Toplevel, BWm, DObject):
|
|
18
18
|
:param kwargs: 参照tkinter.TK.__init__
|
19
19
|
"""
|
20
20
|
|
21
|
+
Toplevel.__init__(self, *args, **kwargs)
|
22
|
+
|
21
23
|
self._init(mode)
|
22
24
|
|
23
25
|
self.custom = False
|
24
26
|
|
25
|
-
|
27
|
+
# 设置窗口图标
|
28
|
+
from .icons import light
|
29
|
+
from tkinter import PhotoImage
|
30
|
+
self.iconphoto(False, PhotoImage(file=light()))
|
26
31
|
|
27
32
|
self.bind("<Configure>", self._event_configure, add="+")
|
28
33
|
self.bind("<Escape>", self._event_key_esc, add="+")
|
29
34
|
self.protocol("WM_DELETE_WINDOW", self._event_delete_window)
|
35
|
+
|
36
|
+
def theme(self, mode: str):
|
37
|
+
super().theme(mode)
|
38
|
+
self._mode = mode
|
39
|
+
for widget in self.winfo_children():
|
40
|
+
if hasattr(widget, "theme"):
|
41
|
+
widget.theme(mode=mode)
|
42
|
+
if hasattr(widget, "_draw"):
|
43
|
+
widget._draw()
|
44
|
+
if hasattr(widget, "update_children"):
|
45
|
+
widget.update_children()
|
@@ -1,140 +0,0 @@
|
|
1
|
-
import tkinter as tk
|
2
|
-
from tkinter import ttk
|
3
|
-
import numpy as np
|
4
|
-
|
5
|
-
|
6
|
-
class GradientLabelApp:
|
7
|
-
def __init__(self, root):
|
8
|
-
self.root = root
|
9
|
-
self.root.title("Tkinter渐变标签演示")
|
10
|
-
self.root.geometry("400x200")
|
11
|
-
|
12
|
-
# 渐变控制变量
|
13
|
-
self.is_animating = False
|
14
|
-
self.current_step = 0
|
15
|
-
self.gradient_steps = 20 # 渐变步数
|
16
|
-
|
17
|
-
# 创建UI组件
|
18
|
-
self.create_widgets()
|
19
|
-
|
20
|
-
# 预生成渐变序列 (从蓝色到红色)
|
21
|
-
self.gradient = self.generate_gradient_hex(
|
22
|
-
"#ffffff",
|
23
|
-
"#005fb8",
|
24
|
-
self.gradient_steps
|
25
|
-
)
|
26
|
-
|
27
|
-
def create_widgets(self):
|
28
|
-
"""创建界面组件"""
|
29
|
-
# 渐变显示标签
|
30
|
-
self.label = tk.Label(
|
31
|
-
self.root,
|
32
|
-
text="渐变背景标签",
|
33
|
-
font=('Arial', 20),
|
34
|
-
relief='raised',
|
35
|
-
borderwidth=2
|
36
|
-
)
|
37
|
-
self.label.pack(pady=20, ipadx=50, ipady=30, fill='x', padx=20)
|
38
|
-
|
39
|
-
# 控制按钮框架
|
40
|
-
button_frame = ttk.Frame(self.root)
|
41
|
-
button_frame.pack(pady=10)
|
42
|
-
|
43
|
-
# 开始按钮
|
44
|
-
self.start_button = ttk.Button(
|
45
|
-
button_frame,
|
46
|
-
text="开始渐变",
|
47
|
-
command=self.toggle_animation
|
48
|
-
)
|
49
|
-
self.start_button.pack(side='left', padx=5)
|
50
|
-
|
51
|
-
# 重置按钮
|
52
|
-
ttk.Button(
|
53
|
-
button_frame,
|
54
|
-
text="重置",
|
55
|
-
command=self.reset_animation
|
56
|
-
).pack(side='left', padx=5)
|
57
|
-
|
58
|
-
def generate_gradient(self, start_color, end_color, steps):
|
59
|
-
"""生成颜色渐变序列"""
|
60
|
-
gradient = []
|
61
|
-
for t in np.linspace(0, 1, steps):
|
62
|
-
r = int(start_color[0] + (end_color[0] - start_color[0]) * t)
|
63
|
-
g = int(start_color[1] + (end_color[1] - start_color[1]) * t)
|
64
|
-
b = int(start_color[2] + (end_color[2] - start_color[2]) * t)
|
65
|
-
gradient.append(f"#{r:02x}{g:02x}{b:02x}")
|
66
|
-
return gradient
|
67
|
-
|
68
|
-
def generate_gradient_hex(self, start_hex, end_hex, steps):
|
69
|
-
"""
|
70
|
-
专为HEX颜色设计的渐变生成器
|
71
|
-
:param start_hex: 起始颜色 HEX格式 (如 "#FF0000")
|
72
|
-
:param end_hex: 结束颜色 HEX格式 (如 "#0000FF")
|
73
|
-
:param steps: 渐变步数
|
74
|
-
:return: HEX格式的颜色列表
|
75
|
-
"""
|
76
|
-
|
77
|
-
# 去除#号并转换为RGB元组
|
78
|
-
def hex_to_rgb(h):
|
79
|
-
h = h.lstrip('#')
|
80
|
-
return tuple(int(h[i:i + 2], 16) for i in (0, 2, 4))
|
81
|
-
|
82
|
-
# RGB转HEX
|
83
|
-
def rgb_to_hex(rgb):
|
84
|
-
return f"#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}"
|
85
|
-
|
86
|
-
rgb_start = hex_to_rgb(start_hex)
|
87
|
-
rgb_end = hex_to_rgb(end_hex)
|
88
|
-
|
89
|
-
gradient = []
|
90
|
-
for t in np.linspace(0, 1, steps):
|
91
|
-
# 计算每个通道的中间值
|
92
|
-
r = int(rgb_start[0] + (rgb_end[0] - rgb_start[0]) * t)
|
93
|
-
g = int(rgb_start[1] + (rgb_end[1] - rgb_start[1]) * t)
|
94
|
-
b = int(rgb_start[2] + (rgb_end[2] - rgb_start[2]) * t)
|
95
|
-
|
96
|
-
# 确保值在0-255范围内并转换为HEX
|
97
|
-
gradient.append(rgb_to_hex((
|
98
|
-
max(0, min(255, r)),
|
99
|
-
max(0, min(255, g)),
|
100
|
-
max(0, min(255, b))
|
101
|
-
)))
|
102
|
-
|
103
|
-
return gradient
|
104
|
-
|
105
|
-
def toggle_animation(self):
|
106
|
-
"""切换动画状态"""
|
107
|
-
self.is_animating = not self.is_animating
|
108
|
-
self.start_button.config(
|
109
|
-
text="停止渐变" if self.is_animating else "开始渐变"
|
110
|
-
)
|
111
|
-
if self.is_animating:
|
112
|
-
self.animate_gradient()
|
113
|
-
|
114
|
-
def animate_gradient(self):
|
115
|
-
"""执行渐变动画"""
|
116
|
-
if not self.is_animating:
|
117
|
-
return
|
118
|
-
|
119
|
-
# 更新标签背景色
|
120
|
-
color = self.gradient[self.current_step]
|
121
|
-
self.label.config(background=color)
|
122
|
-
|
123
|
-
# 更新步进
|
124
|
-
self.current_step = (self.current_step + 1) % len(self.gradient)
|
125
|
-
|
126
|
-
# 50ms后继续下一帧 (约20FPS)
|
127
|
-
self.root.after(50, self.animate_gradient)
|
128
|
-
|
129
|
-
def reset_animation(self):
|
130
|
-
"""重置动画状态"""
|
131
|
-
self.is_animating = False
|
132
|
-
self.current_step = 0
|
133
|
-
self.start_button.config(text="开始渐变")
|
134
|
-
self.label.config(background='SystemButtonFace') # 恢复默认背景色
|
135
|
-
|
136
|
-
|
137
|
-
if __name__ == "__main__":
|
138
|
-
root = tk.Tk()
|
139
|
-
app = GradientLabelApp(root)
|
140
|
-
root.mainloop()
|
tkfluent-0.1.1/tkflu/label.py
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
from tkdeft.windows.drawwidget import DDrawWidget
|
2
|
-
from .tooltip import FluToolTipBase
|
3
|
-
|
4
|
-
|
5
|
-
class FluLabel(DDrawWidget, FluToolTipBase):
|
6
|
-
def __init__(self, *args,
|
7
|
-
text="",
|
8
|
-
width=120,
|
9
|
-
height=32,
|
10
|
-
font=None,
|
11
|
-
mode="light",
|
12
|
-
**kwargs):
|
13
|
-
self._init(mode)
|
14
|
-
|
15
|
-
super().__init__(*args, width=width, height=height, **kwargs)
|
16
|
-
|
17
|
-
self.dconfigure(
|
18
|
-
text=text,
|
19
|
-
)
|
20
|
-
|
21
|
-
from .defs import set_default_font
|
22
|
-
set_default_font(font, self.attributes)
|
23
|
-
|
24
|
-
def _init(self, mode):
|
25
|
-
|
26
|
-
from easydict import EasyDict
|
27
|
-
|
28
|
-
self.attributes = EasyDict(
|
29
|
-
{
|
30
|
-
"text": "",
|
31
|
-
"command": None,
|
32
|
-
"font": None,
|
33
|
-
|
34
|
-
"text_color": "#1b1b1b",
|
35
|
-
}
|
36
|
-
)
|
37
|
-
|
38
|
-
self.theme(mode=mode)
|
39
|
-
|
40
|
-
def _draw(self, event=None):
|
41
|
-
super()._draw(event)
|
42
|
-
|
43
|
-
self.delete("all")
|
44
|
-
|
45
|
-
self.element_text = self.create_text(
|
46
|
-
self.winfo_width() / 2, self.winfo_height() / 2, anchor="center",
|
47
|
-
fill=self.attributes.text_color, text=self.attributes.text, font=self.attributes.font
|
48
|
-
)
|
49
|
-
|
50
|
-
def theme(self, mode="light"):
|
51
|
-
self.mode = mode
|
52
|
-
if mode.lower() == "dark":
|
53
|
-
self._dark()
|
54
|
-
else:
|
55
|
-
self._light()
|
56
|
-
|
57
|
-
def _light(self):
|
58
|
-
self.dconfigure(
|
59
|
-
text_color="#000000"
|
60
|
-
)
|
61
|
-
|
62
|
-
def _dark(self):
|
63
|
-
self.dconfigure(
|
64
|
-
text_color="#ffffff"
|
65
|
-
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|