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.
Files changed (62) hide show
  1. {tkfluent-0.1.1 → tkfluent-0.1.2}/PKG-INFO +1 -1
  2. {tkfluent-0.1.1 → tkfluent-0.1.2}/pyproject.toml +1 -1
  3. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/__main__.py +3 -1
  4. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/button.py +19 -12
  5. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/bwm.py +10 -5
  6. tkfluent-0.1.2/tkflu/demos/designer.py +33 -0
  7. tkfluent-0.1.2/tkflu/demos/grad2.py +17 -0
  8. tkfluent-0.1.2/tkflu/demos/grad3.py +16 -0
  9. tkfluent-0.1.2/tkflu/designs/__init__.py +3 -0
  10. tkfluent-0.1.2/tkflu/designs/animation.py +37 -0
  11. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/gradient.py +2 -0
  12. tkfluent-0.1.2/tkflu/designs/label.py +10 -0
  13. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/menubar.py +0 -3
  14. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/primary_color.py +5 -5
  15. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/frame.py +20 -5
  16. tkfluent-0.1.2/tkflu/label.py +78 -0
  17. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/menu.py +1 -1
  18. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/menubar.py +17 -12
  19. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/thememanager.py +4 -19
  20. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/togglebutton.py +10 -17
  21. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/toplevel.py +17 -1
  22. tkfluent-0.1.1/tkflu/demos/grad2.py +0 -140
  23. tkfluent-0.1.1/tkflu/demos/grad3.py +0 -11
  24. tkfluent-0.1.1/tkflu/designs/__init__.py +0 -2
  25. tkfluent-0.1.1/tkflu/label.py +0 -65
  26. {tkfluent-0.1.1 → tkfluent-0.1.2}/README.md +0 -0
  27. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/__init__.py +0 -0
  28. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/badge.py +0 -0
  29. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/checkbox.py +0 -0
  30. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/constants.py +0 -0
  31. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/customwindow.py +0 -0
  32. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/customwindow2.py +0 -0
  33. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/defs.py +0 -0
  34. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/__init__.py +0 -0
  35. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/acrylic1.py +0 -0
  36. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/demo1.py +0 -0
  37. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/grad.py +0 -0
  38. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/test.py +0 -0
  39. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/demos/tooltip.py +0 -0
  40. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/badge.py +0 -0
  41. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/button.py +0 -0
  42. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/design.py +0 -0
  43. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/entry.py +0 -0
  44. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/fonts/__init__.py +0 -0
  45. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/fonts/segoeui.ttf +0 -0
  46. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/frame.py +0 -0
  47. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/slider.py +0 -0
  48. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/text.py +0 -0
  49. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/tooltip.py +0 -0
  50. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/designs/window.py +0 -0
  51. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/entry.py +0 -0
  52. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/icons.py +0 -0
  53. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/image.py +0 -0
  54. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/listbox.py +0 -0
  55. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/litenav.py +0 -0
  56. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/popupmenu.py +0 -0
  57. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/popupwindow.py +0 -0
  58. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/scrollbar.py +0 -0
  59. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/slider.py +0 -0
  60. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/text.py +0 -0
  61. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/tooltip.py +0 -0
  62. {tkfluent-0.1.1 → tkfluent-0.1.2}/tkflu/window.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tkfluent
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Fluent Design for Tkinter
5
5
  License: GPL-3.0
6
6
  Keywords: tkfluent,tksvg,tkinter,fluent,modern,UI,interface
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "tkfluent"
3
- version = "0.1.1"
3
+ version = "0.1.2"
4
4
  description = "Fluent Design for Tkinter"
5
5
  authors = ["XiangQinxi <xiangqinxi@outlook.com>"]
6
6
  readme = "README.md"
@@ -2,7 +2,9 @@ from tkflu import *
2
2
  from tkinter import *
3
3
  from tkinter.font import *
4
4
 
5
- blue_primary_color()
5
+ orange_primary_color()
6
+ set_animation_steps(10)
7
+ set_animation_step_time(20)
6
8
 
7
9
  def togglestate():
8
10
  if button1.dcget("state") == NORMAL:
@@ -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, animate_steps: int = 10):
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"], steps
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"], steps
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"], steps
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"], steps
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"]), steps).tolist()
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"]), steps).tolist()
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"]), steps).tolist()
248
- for i in range(steps):
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 * 10, update)
267
- self.after(steps * 10 + 10, lambda: self._draw(None, None))
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=10)
137
- for i in range(10):
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 * 10, update) # 直接传递函数,不需要lambda
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,3 @@
1
+ from .design import FluDesign
2
+ from .primary_color import FluPrimaryColor, set_primary_color, get_primary_color
3
+ from .animation import FluAnimation, set_animation_steps, set_animation_step_time, get_animation_steps, get_animation_step_time
@@ -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"])
@@ -34,6 +34,8 @@ class FluGradient:
34
34
  rgb_end = self.hex_to_rgb(end_hex)
35
35
  import numpy as np
36
36
  gradient = []
37
+ if steps is None:
38
+ return None
37
39
  for t in np.linspace(0, 1, steps):
38
40
  # 计算每个通道的中间值
39
41
  r = int(rgb_start[0] + (rgb_end[0] - rgb_start[0]) * t)
@@ -0,0 +1,10 @@
1
+ def label(mode: str):
2
+ mode = mode.lower()
3
+ if mode == "light":
4
+ return {
5
+ "text_color": "#000000",
6
+ }
7
+ else:
8
+ return {
9
+ "text_color": "#ffffff",
10
+ }
@@ -1,6 +1,3 @@
1
- from .primary_color import get_primary_color
2
-
3
-
4
1
  def menubar(mode):
5
2
  mode = mode.lower()
6
3
  if mode == "light":
@@ -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, animate_steps: int = 10):
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=10)
187
- for i in range(10):
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 * 10, update) # 直接传递函数,不需要lambda
192
- self.after(animate_steps * 10 + 50, lambda: self.update())
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()+100, widget.winfo_rooty())
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", animate_steps: int = 10):
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 mode.lower() == "dark":
138
- if hasattr(self, "tk"):
139
- back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=10)
140
- for i in range(10):
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 * 10, update) # 直接传递函数,不需要lambda
146
- self.after(animate_steps*10+50, lambda: self.update_children())
147
- else:
148
- if hasattr(self, "tk"):
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 * 20, update) # 直接传递函数,不需要lambda
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 = 0):
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.after(delay+300, __)
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
- def _():
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, animate_steps: int = 10):
395
- """
396
-
397
- "back_color": "#ffffff",
398
- "back_opacity": "0.7",
399
- "border_color": "#000000",
400
- "border_color_opacity": "0.2",
401
- "border_color2": "#000000",
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*10, update)
480
- self.after(steps*10+10, lambda: self._draw(None, None))
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
- Toplevel.__init__(self, *args, **kwargs)
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()
@@ -1,11 +0,0 @@
1
- from tkflu import *
2
-
3
-
4
- root = FluWindow()
5
-
6
- theme_manager = FluThemeManager(root)
7
-
8
- btn = FluButton(root, text="Button", mode="light", style="standard", command=lambda: theme_manager.toggle())
9
- btn.pack()
10
-
11
- root.mainloop()
@@ -1,2 +0,0 @@
1
- from .design import FluDesign
2
- from .primary_color import FluPrimaryColor, set_primary_color, get_primary_color
@@ -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