tkfluent 0.1.3__tar.gz → 0.1.5__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 (65) hide show
  1. {tkfluent-0.1.3 → tkfluent-0.1.5}/PKG-INFO +7 -4
  2. {tkfluent-0.1.3 → tkfluent-0.1.5}/README.md +5 -2
  3. {tkfluent-0.1.3 → tkfluent-0.1.5}/pyproject.toml +2 -2
  4. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/__init__.py +1 -0
  5. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/__main__.py +24 -11
  6. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/bwm.py +10 -0
  7. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/designer.py +2 -2
  8. tkfluent-0.1.5/tkflu/demos/screenshot.py +8 -0
  9. tkfluent-0.1.5/tkflu/demos/scroll.py +19 -0
  10. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/__init__.py +3 -1
  11. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/animation.py +2 -2
  12. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/design.py +20 -0
  13. tkfluent-0.1.5/tkflu/designs/fonts/__init__.py +35 -0
  14. tkfluent-0.1.5/tkflu/designs/fonts/segoe_fluent_icons.ttf +0 -0
  15. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/frame.py +2 -2
  16. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/menubar.py +2 -0
  17. tkfluent-0.1.5/tkflu/designs/scrollbar.py +34 -0
  18. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/slider.py +16 -0
  19. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/text.py +5 -5
  20. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/label.py +11 -8
  21. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/menubar.py +17 -15
  22. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/popupmenu.py +1 -1
  23. tkfluent-0.1.5/tkflu/popupwindow.py +70 -0
  24. tkfluent-0.1.5/tkflu/scrollbar.py +414 -0
  25. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/slider.py +182 -93
  26. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/text.py +10 -9
  27. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/thememanager.py +11 -11
  28. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/togglebutton.py +89 -86
  29. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/tooltip.py +5 -19
  30. tkfluent-0.1.3/tkflu/designs/fonts/__init__.py +0 -20
  31. tkfluent-0.1.3/tkflu/popupwindow.py +0 -33
  32. tkfluent-0.1.3/tkflu/scrollbar.py +0 -200
  33. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/badge.py +0 -0
  34. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/button.py +0 -0
  35. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/checkbox.py +0 -0
  36. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/constants.py +0 -0
  37. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/customwindow.py +0 -0
  38. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/customwindow2.py +0 -0
  39. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/defs.py +0 -0
  40. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/__init__.py +0 -0
  41. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/acrylic1.py +0 -0
  42. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/demo1.py +0 -0
  43. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/grad.py +0 -0
  44. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/grad2.py +0 -0
  45. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/grad3.py +0 -0
  46. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/test.py +0 -0
  47. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/demos/tooltip.py +0 -0
  48. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/badge.py +0 -0
  49. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/button.py +0 -0
  50. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/entry.py +0 -0
  51. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/fonts/segoeui.ttf +0 -0
  52. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/gradient.py +0 -0
  53. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/label.py +0 -0
  54. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/primary_color.py +0 -0
  55. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/tooltip.py +0 -0
  56. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/designs/window.py +0 -0
  57. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/entry.py +0 -0
  58. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/frame.py +0 -0
  59. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/icons.py +0 -0
  60. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/image.py +0 -0
  61. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/listbox.py +0 -0
  62. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/litenav.py +0 -0
  63. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/menu.py +0 -0
  64. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/toplevel.py +0 -0
  65. {tkfluent-0.1.3 → tkfluent-0.1.5}/tkflu/window.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tkfluent
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Fluent(SunValley) Design for Tkinter. Modern GUI
5
5
  License: GPL-3.0
6
6
  Keywords: tkfluent,tksvg,tkinter,fluent,modern,GUI,interface
@@ -30,17 +30,20 @@ Requires-Dist: easydict (>=1.13,<2.0)
30
30
  Requires-Dist: numpy
31
31
  Requires-Dist: pillow (>=10.2.0,<11.0.0)
32
32
  Requires-Dist: svgwrite (>=1.4.3,<2.0.0)
33
- Requires-Dist: tkdeft (==0.0.9)
33
+ Requires-Dist: tkdeft (==0.1.1)
34
34
  Requires-Dist: tkextrafont (>=0.6.3,<0.7.0)
35
35
  Requires-Dist: tksvg (>=0.7.4,<0.8.0)
36
36
  Project-URL: Documentation, https://tkfluent.netlify.app
37
37
  Description-Content-Type: text/markdown
38
38
 
39
- # tkfluent
39
+ <div align="center">
40
40
 
41
+ # tkfluent
41
42
  `tkinter`现代化组件库。设计来于`Fluent` `WinUI3` 设计
42
43
 
43
- ## 效果图
44
+ </div>
45
+
46
+
44
47
  ![Light.png](https://img.picui.cn/free/2025/06/22/6857e613bc150.png)
45
48
  ![Dark.png](https://img.picui.cn/free/2025/06/22/6857e613b7fc2.png)
46
49
 
@@ -1,8 +1,11 @@
1
- # tkfluent
1
+ <div align="center">
2
2
 
3
+ # tkfluent
3
4
  `tkinter`现代化组件库。设计来于`Fluent` `WinUI3` 设计
4
5
 
5
- ## 效果图
6
+ </div>
7
+
8
+
6
9
  ![Light.png](https://img.picui.cn/free/2025/06/22/6857e613bc150.png)
7
10
  ![Dark.png](https://img.picui.cn/free/2025/06/22/6857e613b7fc2.png)
8
11
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "tkfluent"
3
- version = "0.1.3"
3
+ version = "0.1.5"
4
4
  description = "Fluent(SunValley) Design for Tkinter. Modern GUI"
5
5
  authors = ["XiangQinxi <xiangqinxi@outlook.com>"]
6
6
  readme = "README.md"
@@ -36,7 +36,7 @@ tksvg = "^0.7.4"
36
36
  tkextrafont = "^0.6.3"
37
37
  svgwrite = "^1.4.3"
38
38
  pillow = "^10.2.0"
39
- tkdeft = "0.0.9"
39
+ tkdeft = "0.1.1"
40
40
  easydict = "^1.13"
41
41
  numpy = "*"
42
42
 
@@ -22,6 +22,7 @@ from .menu import FluMenu
22
22
  from .menubar import FluMenuBar
23
23
  from .popupmenu import FluPopupMenu, FluPopupMenuWindow
24
24
  from .popupwindow import FluPopupWindow
25
+ from .scrollbar import FluScrollBar
25
26
  from .slider import FluSlider
26
27
  from .text import FluText
27
28
  from .thememanager import FluThemeManager
@@ -2,28 +2,35 @@ from tkflu import *
2
2
  from tkinter import *
3
3
  from tkinter.font import *
4
4
 
5
- purple_primary_color()
5
+ blue_primary_color()
6
6
  set_animation_steps(10)
7
- set_animation_step_time(10)
7
+ set_animation_step_time(20)
8
8
 
9
9
  def togglestate():
10
10
  if button1.dcget("state") == NORMAL:
11
11
  button1.dconfigure(state=DISABLED)
12
12
  button2.dconfigure(state=DISABLED)
13
13
  entry1.dconfigure(state=DISABLED)
14
- button1._draw()
15
- button2._draw()
16
- entry1._draw()
14
+ text1.dconfigure(state=DISABLED)
15
+ togglebutton1.dconfigure(state=DISABLED)
16
+ slider1.dconfigure(state=DISABLED)
17
17
  else:
18
18
  button1.dconfigure(state=NORMAL)
19
19
  button2.dconfigure(state=NORMAL)
20
20
  entry1.dconfigure(state=NORMAL)
21
- button1._draw()
22
- button2._draw()
23
- entry1._draw()
21
+ text1.dconfigure(state=NORMAL)
22
+ togglebutton1.dconfigure(state=NORMAL)
23
+ slider1.dconfigure(state=NORMAL)
24
+ button1._draw()
25
+ button2._draw()
26
+ entry1._draw()
27
+ text1._draw()
28
+ togglebutton1._draw()
29
+ slider1._draw()
30
+
24
31
  root = FluWindow()
25
32
  #root.wincustom(way=0)
26
- root.geometry("360x600")
33
+ root.geometry("360x650")
27
34
 
28
35
  popupmenu = FluPopupMenu()
29
36
 
@@ -63,6 +70,9 @@ menubar.pack(fill="x")
63
70
 
64
71
  frame = FluFrame(root)
65
72
 
73
+ scrollbar1 = FluScrollBar(frame)
74
+ scrollbar1.pack(fill="y", side="right", padx=5, pady=5)
75
+
66
76
  badge1 = FluBadge(frame, text="FluBadge", width=60)
67
77
  badge1.pack(padx=5, pady=5)
68
78
 
@@ -108,7 +118,7 @@ entry1.pack(fill="x", padx=5, pady=5)
108
118
  text1 = FluText(frame)
109
119
  text1.pack(fill="x", padx=5, pady=5)
110
120
 
111
- slider1 = FluSlider(frame, value=0)
121
+ slider1 = FluSlider(frame, value=5, min=0, max=10, tick=False, changed=lambda: print(f"FluSlider -> Changed -> Value: {slider1.dcget('value')}"))
112
122
  slider1.pack(fill="x", padx=5, pady=5)
113
123
 
114
124
  """listbox1 = FluListBox(frame)
@@ -116,5 +126,8 @@ listbox1.dconfigure()
116
126
  listbox1.pack(fill="x", padx=5, pady=5)"""
117
127
 
118
128
  frame.pack(fill="both", expand="yes", side="right", padx=15, pady=15)
119
- frame.update_idletasks()
129
+ #frame.update_idletasks()
130
+
131
+ #thememanager.mode("light")
132
+
120
133
  root.mainloop()
@@ -122,8 +122,18 @@ class BWm(FluGradient):
122
122
 
123
123
  self.mode = mode
124
124
  if mode.lower() == "dark":
125
+ try:
126
+ import pywinstyles
127
+ pywinstyles.apply_style(self, "dark")
128
+ except ModuleNotFoundError:
129
+ pass
125
130
  self._dark()
126
131
  else:
132
+ try:
133
+ import pywinstyles
134
+ pywinstyles.apply_style(self, "light")
135
+ except ModuleNotFoundError:
136
+ pass
127
137
  self._light()
128
138
 
129
139
  def _theme(self, mode, animation_steps: int = None, animation_step_time: int = None):
@@ -24,8 +24,8 @@ def func1():
24
24
  label.pack(anchor="center")
25
25
 
26
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())
27
+ menubar.add_cascade(label="Theme Mode", style="standard", width=85, menu=menu1)
28
+ menubar.add_command(label="About", style="standard", width=45, command=lambda: func1())
29
29
 
30
30
  menubar.show()
31
31
 
@@ -0,0 +1,8 @@
1
+ from tkflu import *
2
+
3
+
4
+ root = FluWindow()
5
+
6
+
7
+
8
+ root.mainloop()
@@ -0,0 +1,19 @@
1
+ from tkinter import *
2
+ from tkflu import *
3
+ from tkflu.designs.scrollbar import scrollbar
4
+
5
+ root = FluWindow()
6
+
7
+ frane = FluFrame(root)
8
+ frane.pack(fill="both", expand="yes", padx=10, pady=10)
9
+
10
+ scrollbar = FluScrollBar(frane, orient=VERTICAL)
11
+ scrollbar.pack(fill="y", side="right")
12
+
13
+ canvas = Canvas(frane, yscrollcommand=scrollbar.set)
14
+ canvas.pack(fill="both", expand="yes", padx=5, pady=5)
15
+
16
+ for i in range(20):
17
+ canvas.create_window(0, i * 30, anchor="nw", window=FluButton(text=f"Button {i}"))
18
+
19
+ root.mainloop()
@@ -1,3 +1,5 @@
1
1
  from .design import FluDesign
2
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
3
+ from .animation import FluAnimation, set_animation_steps, set_animation_step_time, get_animation_steps, get_animation_step_time
4
+ from .gradient import FluGradient
5
+ from .fonts import *
@@ -14,9 +14,9 @@ def get_animation_step_time():
14
14
  return int(environ["tkfluent.animation_step_time"])
15
15
 
16
16
  if "tkfluent.animation_steps" not in environ:
17
- set_animation_steps(10)
17
+ set_animation_steps(0)
18
18
  if "tkfluent.animation_step_time" not in environ:
19
- set_animation_step_time(10)
19
+ set_animation_step_time(0)
20
20
 
21
21
 
22
22
  class FluAnimation(object):
@@ -18,10 +18,30 @@ class FluDesign(object):
18
18
  from .frame import frame
19
19
  return frame(*args, **kwargs)
20
20
 
21
+ def label(self, *args, **kwargs):
22
+ from .label import label
23
+ return label(*args, **kwargs)
24
+
25
+ def menubar(self, *args, **kwargs):
26
+ from .menubar import menubar
27
+ return menubar(*args, **kwargs)
28
+
29
+ def scrollbar(self, *args, **kwargs):
30
+ from .scrollbar import scrollbar
31
+ return scrollbar(*args, **kwargs)
32
+
33
+ def slider(self, *args, **kwargs):
34
+ from .slider import slider
35
+ return slider(*args, **kwargs)
36
+
21
37
  def text(self, *args, **kwargs):
22
38
  from .text import text
23
39
  return text(*args, **kwargs)
24
40
 
41
+ def tooltip(self, *args, **kwargs):
42
+ from .tooltip import tooltip
43
+ return tooltip(*args, **kwargs)
44
+
25
45
  def window(self, *args, **kwargs):
26
46
  from .window import window
27
47
  return window(*args, **kwargs)
@@ -0,0 +1,35 @@
1
+ from os.path import abspath, dirname, join
2
+
3
+ path = abspath(dirname(__file__))
4
+
5
+ segoefont = join(path, "segoeui.ttf")
6
+ segoefluenticons = join(path, "segoe_fluent_icons.ttf")
7
+
8
+ def SegoeFont(size=9, weight="normal"):
9
+ from _tkinter import TclError
10
+ try:
11
+ from tkextrafont import Font
12
+ font = Font(file=segoefont, size=size, family="Segoe UI")
13
+ except TclError:
14
+ try:
15
+ from tkinter.font import Font
16
+ font = Font(size=size, family="Segoe UI", weight=weight)
17
+ except TclError:
18
+ from tkinter.font import nametofont
19
+ font = nametofont("TkDefaultFont").configure(size=size, weight=weight)
20
+ return font
21
+
22
+
23
+ def SegoeFluentIcons(size=9, weight="normal", *args, **kwargs):
24
+ from _tkinter import TclError
25
+ try:
26
+ from tkextrafont import Font
27
+ font = Font(file=segoefluenticons, size=size, family="Segoe Fluent Icons", *args, **kwargs)
28
+ except TclError:
29
+ try:
30
+ from tkinter.font import Font
31
+ font = Font(size=size, family="Segoe Fluent Icons", *args, **kwargs)
32
+ except TclError:
33
+ from tkinter.font import nametofont
34
+ font = nametofont("TkDefaultFont").configure(size=size, weight=weight)
35
+ return font
@@ -21,7 +21,7 @@ def frame(mode, style):
21
21
  else:
22
22
  if style == "standard":
23
23
  return {
24
- "back_color": "#282828",
24
+ "back_color": "#2b2b2b",
25
25
  "border_color": "#000000",
26
26
  "border_color_opacity": 0.100000,
27
27
  "border_width": 2,
@@ -29,7 +29,7 @@ def frame(mode, style):
29
29
  }
30
30
  else:
31
31
  return {
32
- "back_color": "#282828",
32
+ "back_color": "#2b2b2b",
33
33
  "border_color": "#000000",
34
34
  "border_color_opacity": 0.100000,
35
35
  "border_width": 2,
@@ -3,8 +3,10 @@ def menubar(mode):
3
3
  if mode == "light":
4
4
  return {
5
5
  "back_color": "#f3f3f3",
6
+ "border_color": "#e5e5e5",
6
7
  }
7
8
  else:
8
9
  return {
9
10
  "back_color": "#202020",
11
+ "border_color": "#1d1d1d",
10
12
  }
@@ -0,0 +1,34 @@
1
+ def scrollbar(mode):
2
+ """滚动栏设计配置"""
3
+ if mode.lower() == "dark":
4
+ return {
5
+ "rest": {
6
+ "thumb_color": "#9a9a9a",
7
+ "radius": 2,
8
+ },
9
+ "expand": {
10
+ "track_color": "#2b2b2b",
11
+ "thumb_color": "#9f9f9f",
12
+ "radius": 4,
13
+ },
14
+ "disabled": {
15
+ "thumb_color": "#515151",
16
+ "radius": 2,
17
+ }
18
+ }
19
+ else: # light mode
20
+ return {
21
+ "rest": {
22
+ "thumb_color": "#868686",
23
+ "radius": 2,
24
+ },
25
+ "expand": {
26
+ "track_color": "#f8f8f8",
27
+ "thumb_color": "#898989",
28
+ "radius": 4,
29
+ },
30
+ "disabled": {
31
+ "thumb_color": "#9f9f9f",
32
+ "radius": 2,
33
+ }
34
+ }
@@ -13,6 +13,8 @@ def slider(mode: str, state: str):
13
13
  "radius": 12,
14
14
  "inner_radius": 6,
15
15
 
16
+ "width": 28,
17
+
16
18
  "back_color": "#FFFFFF",
17
19
  "back_opacity": 1,
18
20
 
@@ -43,6 +45,8 @@ def slider(mode: str, state: str):
43
45
  "radius": 12,
44
46
  "inner_radius": 8,
45
47
 
48
+ "width": 28,
49
+
46
50
  "back_color": "#FFFFFF",
47
51
  "back_opacity": 1,
48
52
 
@@ -73,6 +77,8 @@ def slider(mode: str, state: str):
73
77
  "radius": 12,
74
78
  "inner_radius": 5,
75
79
 
80
+ "width": 28,
81
+
76
82
  "back_color": "#FFFFFF",
77
83
  "back_opacity": 1,
78
84
 
@@ -103,6 +109,8 @@ def slider(mode: str, state: str):
103
109
  "radius": 12,
104
110
  "inner_radius": 6,
105
111
 
112
+ "width": 28,
113
+
106
114
  "back_color": "#FFFFFF",
107
115
  "back_opacity": 1,
108
116
 
@@ -133,6 +141,8 @@ def slider(mode: str, state: str):
133
141
  "thumb": {
134
142
  "radius": 12,
135
143
 
144
+ "width": 28,
145
+
136
146
  "inner_radius": 6,
137
147
  "inner_back_color": get_primary_color()[1],
138
148
  "inner_back_opacity": 1,
@@ -164,6 +174,8 @@ def slider(mode: str, state: str):
164
174
  "thumb": {
165
175
  "radius": 12,
166
176
 
177
+ "width": 28,
178
+
167
179
  "inner_radius": 8,
168
180
  "inner_back_color": get_primary_color()[1],
169
181
  "inner_back_opacity": 1,
@@ -195,6 +207,8 @@ def slider(mode: str, state: str):
195
207
  "thumb": {
196
208
  "radius": 12,
197
209
 
210
+ "width": 28,
211
+
198
212
  "inner_radius": 5,
199
213
  "inner_back_color": get_primary_color()[1],
200
214
  "inner_back_opacity": 0.8,
@@ -226,6 +240,8 @@ def slider(mode: str, state: str):
226
240
  "thumb": {
227
241
  "radius": 12,
228
242
 
243
+ "width": 28,
244
+
229
245
  "inner_radius": 6,
230
246
  "inner_back_color": "#FFFFFF",
231
247
  "inner_back_opacity": 0.158100,
@@ -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
  }
@@ -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 hasattr(self, "tk"):
71
- if self.attributes.text_color != m["text_color"]:
72
- text_colors = self.generate_hex2hex(self.attributes.text_color, m["text_color"], steps=animation_steps)
73
- for i in range(animation_steps):
74
- def update(ii=i): # 使用默认参数立即捕获i的值
75
- self._draw(tempcolor=text_colors[ii])
76
-
77
- self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
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()
@@ -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
  }
@@ -144,31 +145,32 @@ class FluMenuBar(Frame, DObject, FluGradient):
144
145
  if not animation_steps == 0 or not animation_step_time == 0:
145
146
  if mode.lower() == "dark":
146
147
  back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=animation_steps)
147
- for i in range(animation_steps):
148
- def update(ii=i): # 使用默认参数立即捕获i的值
149
- self.dconfigure(back_color=back_colors[ii])
150
- self._draw()
151
-
152
- self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
148
+ border_colors = self.generate_hex2hex(self.attributes.border_color, m["border_color"],
149
+ steps=animation_steps)
153
150
  else:
154
151
  back_colors = self.generate_hex2hex(self.attributes.back_color, m["back_color"], steps=animation_steps)
155
- for i in range(animation_steps):
156
- def update(ii=i): # 使用默认参数立即捕获i的值
157
- self.dconfigure(back_color=back_colors[ii])
158
- self._draw()
152
+ border_colors = self.generate_hex2hex(self.attributes.border_color, m["border_color"],
153
+ steps=animation_steps)
154
+ for i in range(animation_steps):
155
+ def update(ii=i): # 使用默认参数立即捕获i的值
156
+ self.dconfigure(back_color=back_colors[ii], border_color=border_colors[ii])
157
+ self._draw()
159
158
 
160
- self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
159
+ self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
161
160
 
162
161
  self.after(animation_steps * animation_step_time + 50, lambda: self.update_children())
163
162
  else:
164
- if mode.lower() == "dark":
165
- self.dconfigure(back_color=m["back_color"])
166
- else:
167
- self.dconfigure(back_color=m["back_color"])
163
+ self.dconfigure(back_color=m["back_color"])
164
+ self.dconfigure(border_color=m["border_color"])
168
165
  self._draw()
169
166
 
170
167
  def _draw(self, event=None):
171
168
  self.config(background=self.attributes.back_color)
169
+ if not hasattr(self, "border"):
170
+ self.border = Frame(self, height=1.2, background=self.attributes.border_color)
171
+ else:
172
+ self.border.configure(background=self.attributes.border_color)
173
+ self.border.pack(fill="x", expand="yes", side="bottom")
172
174
 
173
175
  def _event_configure(self, event=None):
174
176
  self._draw(event)
@@ -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="#ffefa2", style="popupmenu", **kwargs):
11
+ def __init__(self, *args, width=100, height=46, transparent_color="gray", 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)
@@ -0,0 +1,70 @@
1
+ from tkinter import Toplevel
2
+
3
+
4
+ class FluPopupWindow(Toplevel):
5
+ def __init__(self, *args, transparent_color="#ebebeb", mode="light", width=100, height=46, custom=True, **kwargs):
6
+ super().__init__(*args, background=transparent_color, **kwargs)
7
+
8
+ self.theme(mode=mode)
9
+
10
+ if width > 0 and height > 0:
11
+ self.geometry(f"{width}x{height}")
12
+
13
+ if custom:
14
+ self.transient_color = transparent_color
15
+ self.overrideredirect(True)
16
+ self.wm_attributes("-transparentcolor", transparent_color)
17
+
18
+ self.withdraw()
19
+
20
+ self.bind("<FocusOut>", self._event_focusout, add="+")
21
+
22
+ def _event_focusout(self, event=None):
23
+ """self.wm_attributes("-alpha", 1)
24
+ self.deiconify()
25
+
26
+ from .designs.animation import get_animation_steps, get_animation_step_time
27
+
28
+ FRAMES_COUNT = get_animation_steps()
29
+ FRAME_DELAY = get_animation_step_time()
30
+
31
+ def fade_out(step=1):
32
+ alpha = step / FRAMES_COUNT # 按帧数变化,从0到1
33
+ self.wm_attributes("-alpha", alpha)
34
+ if step < FRAMES_COUNT:
35
+ # 每执行一次,增加一次透明度,间隔由帧数决定
36
+ self.after(int(round(FRAME_DELAY * FRAMES_COUNT / FRAMES_COUNT)), lambda: fade_out(step - 1))
37
+
38
+ fade_out() # 启动动画"""
39
+ self.withdraw()
40
+
41
+ def popup(self, x, y):
42
+
43
+ from .designs.animation import get_animation_steps, get_animation_step_time
44
+
45
+ FRAMES_COUNT = get_animation_steps()
46
+ FRAME_DELAY = get_animation_step_time()
47
+
48
+ self.geometry(f"+{x}+{y}")
49
+ #self.focus_set()
50
+ if not FRAMES_COUNT == 0 or not FRAME_DELAY == 0:
51
+ self.wm_attributes("-alpha", 0.0)
52
+ self.deiconify()
53
+
54
+ def fade_in(step=0):
55
+ alpha = step / FRAMES_COUNT # 按帧数变化,从0到1
56
+ self.wm_attributes("-alpha", alpha)
57
+ if step < FRAMES_COUNT:
58
+ # 每执行一次,增加一次透明度,间隔由帧数决定
59
+ self.after(int(round(FRAME_DELAY*FRAMES_COUNT / FRAMES_COUNT)), lambda: fade_in(step + 1))
60
+
61
+ fade_in() # 启动动画
62
+ else:
63
+ self.deiconify()
64
+
65
+ def theme(self, mode=None):
66
+ if mode:
67
+ self.mode = mode
68
+ for widget in self.winfo_children():
69
+ if hasattr(widget, "theme"):
70
+ widget.theme(mode=self.mode.lower())