tkfluent 0.1.1__tar.gz → 0.1.3__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 (64) hide show
  1. {tkfluent-0.1.1 → tkfluent-0.1.3}/PKG-INFO +13 -5
  2. {tkfluent-0.1.1 → tkfluent-0.1.3}/README.md +8 -0
  3. {tkfluent-0.1.1 → tkfluent-0.1.3}/pyproject.toml +5 -5
  4. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/__init__.py +3 -1
  5. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/__main__.py +3 -1
  6. tkfluent-0.1.3/tkflu/button.py +448 -0
  7. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/bwm.py +18 -10
  8. tkfluent-0.1.3/tkflu/demos/designer.py +33 -0
  9. tkfluent-0.1.3/tkflu/demos/grad2.py +17 -0
  10. tkfluent-0.1.3/tkflu/demos/grad3.py +16 -0
  11. tkfluent-0.1.3/tkflu/designs/__init__.py +3 -0
  12. tkfluent-0.1.3/tkflu/designs/animation.py +37 -0
  13. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/gradient.py +2 -0
  14. tkfluent-0.1.3/tkflu/designs/label.py +10 -0
  15. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/menubar.py +0 -3
  16. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/primary_color.py +5 -5
  17. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/frame.py +24 -9
  18. tkfluent-0.1.3/tkflu/image.py +4 -0
  19. tkfluent-0.1.3/tkflu/label.py +80 -0
  20. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/menu.py +1 -1
  21. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/menubar.py +33 -21
  22. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/text.py +34 -2
  23. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/thememanager.py +7 -21
  24. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/togglebutton.py +83 -84
  25. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/tooltip.py +11 -6
  26. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/toplevel.py +17 -1
  27. tkfluent-0.1.1/tkflu/button.py +0 -345
  28. tkfluent-0.1.1/tkflu/demos/grad2.py +0 -140
  29. tkfluent-0.1.1/tkflu/demos/grad3.py +0 -11
  30. tkfluent-0.1.1/tkflu/designs/__init__.py +0 -2
  31. tkfluent-0.1.1/tkflu/image.py +0 -0
  32. tkfluent-0.1.1/tkflu/label.py +0 -65
  33. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/badge.py +0 -0
  34. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/checkbox.py +0 -0
  35. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/constants.py +0 -0
  36. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/customwindow.py +0 -0
  37. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/customwindow2.py +0 -0
  38. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/defs.py +0 -0
  39. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/demos/__init__.py +0 -0
  40. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/demos/acrylic1.py +0 -0
  41. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/demos/demo1.py +0 -0
  42. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/demos/grad.py +0 -0
  43. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/demos/test.py +0 -0
  44. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/demos/tooltip.py +0 -0
  45. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/badge.py +0 -0
  46. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/button.py +0 -0
  47. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/design.py +0 -0
  48. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/entry.py +0 -0
  49. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/fonts/__init__.py +0 -0
  50. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/fonts/segoeui.ttf +0 -0
  51. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/frame.py +0 -0
  52. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/slider.py +0 -0
  53. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/text.py +0 -0
  54. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/tooltip.py +0 -0
  55. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/designs/window.py +0 -0
  56. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/entry.py +0 -0
  57. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/icons.py +0 -0
  58. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/listbox.py +0 -0
  59. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/litenav.py +0 -0
  60. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/popupmenu.py +0 -0
  61. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/popupwindow.py +0 -0
  62. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/scrollbar.py +0 -0
  63. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/slider.py +0 -0
  64. {tkfluent-0.1.1 → tkfluent-0.1.3}/tkflu/window.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tkfluent
3
- Version: 0.1.1
4
- Summary: Fluent Design for Tkinter
3
+ Version: 0.1.3
4
+ Summary: Fluent(SunValley) Design for Tkinter. Modern GUI
5
5
  License: GPL-3.0
6
- Keywords: tkfluent,tksvg,tkinter,fluent,modern,UI,interface
6
+ Keywords: tkfluent,tksvg,tkinter,fluent,modern,GUI,interface
7
7
  Author: XiangQinxi
8
8
  Author-email: xiangqinxi@outlook.com
9
9
  Requires-Python: >=3.8,<4.0
@@ -27,10 +27,10 @@ Classifier: Programming Language :: Python :: 3.13
27
27
  Classifier: Programming Language :: Tcl
28
28
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
29
29
  Requires-Dist: easydict (>=1.13,<2.0)
30
- Requires-Dist: numpy (>=2.3.1,<3.0.0)
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,<0.0.10)
33
+ Requires-Dist: tkdeft (==0.0.9)
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
@@ -44,10 +44,18 @@ Description-Content-Type: text/markdown
44
44
  ![Light.png](https://img.picui.cn/free/2025/06/22/6857e613bc150.png)
45
45
  ![Dark.png](https://img.picui.cn/free/2025/06/22/6857e613b7fc2.png)
46
46
 
47
+ ## 文档
48
+ 请查阅[tkfluent文档网站](https://tkfluent.netlify.app/)。
49
+ 使用`mkdocs`和`mkdocs-material`构建,由`netlify`部署
50
+
51
+ ## 贡献者
52
+ 1. [真_人工智障](https://github.com/TotoWang-hhh)
53
+
47
54
  ## 依赖图
48
55
  ```bash
49
56
  PS .\tkfluent> poetry show --tree
50
57
  easydict 1.13 Access dict values as attributes (works recursively).
58
+ numpy 1.24.4 Fundamental package for array computing in Python
51
59
  pillow 10.4.0 Python Imaging Library (Fork)
52
60
  svgwrite 1.4.3 A Python library to create SVG drawings.
53
61
  tkdeft 0.0.9 使用tkinter+tksvg开发的现代化界面库
@@ -6,10 +6,18 @@
6
6
  ![Light.png](https://img.picui.cn/free/2025/06/22/6857e613bc150.png)
7
7
  ![Dark.png](https://img.picui.cn/free/2025/06/22/6857e613b7fc2.png)
8
8
 
9
+ ## 文档
10
+ 请查阅[tkfluent文档网站](https://tkfluent.netlify.app/)。
11
+ 使用`mkdocs`和`mkdocs-material`构建,由`netlify`部署
12
+
13
+ ## 贡献者
14
+ 1. [真_人工智障](https://github.com/TotoWang-hhh)
15
+
9
16
  ## 依赖图
10
17
  ```bash
11
18
  PS .\tkfluent> poetry show --tree
12
19
  easydict 1.13 Access dict values as attributes (works recursively).
20
+ numpy 1.24.4 Fundamental package for array computing in Python
13
21
  pillow 10.4.0 Python Imaging Library (Fork)
14
22
  svgwrite 1.4.3 A Python library to create SVG drawings.
15
23
  tkdeft 0.0.9 使用tkinter+tksvg开发的现代化界面库
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "tkfluent"
3
- version = "0.1.1"
4
- description = "Fluent Design for Tkinter"
3
+ version = "0.1.3"
4
+ description = "Fluent(SunValley) Design for Tkinter. Modern GUI"
5
5
  authors = ["XiangQinxi <xiangqinxi@outlook.com>"]
6
6
  readme = "README.md"
7
7
  documentation = "https://tkfluent.netlify.app"
@@ -9,7 +9,7 @@ packages = [
9
9
  { include = "tkflu" }
10
10
  ]
11
11
  license = "GPL-3.0"
12
- keywords = [ "tkfluent", "tksvg", "tkinter", "fluent", "modern", "UI", "interface" ]
12
+ keywords = [ "tkfluent", "tksvg", "tkinter", "fluent", "modern", "GUI", "interface" ]
13
13
  classifiers = [
14
14
  "Development Status :: 4 - Beta",
15
15
  "Environment :: MacOS X",
@@ -36,9 +36,9 @@ 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.0.9"
40
40
  easydict = "^1.13"
41
- numpy = "^2.3.1"
41
+ numpy = "*"
42
42
 
43
43
  [build-system]
44
44
  requires = ["poetry-core"]
@@ -1,9 +1,11 @@
1
- """
1
+ """
2
2
 
3
3
  Fluent设计的tkinter组件库(模板)
4
4
 
5
5
  -------------
6
6
  作者:XiangQinxi
7
+
8
+ 贡献者:totowang-hhh
7
9
  -------------
8
10
  """
9
11
 
@@ -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
+ purple_primary_color()
6
+ set_animation_steps(10)
7
+ set_animation_step_time(10)
6
8
 
7
9
  def togglestate():
8
10
  if button1.dcget("state") == NORMAL:
@@ -0,0 +1,448 @@
1
+ from tkdeft.windows.draw import DSvgDraw
2
+ from tkdeft.windows.canvas import DCanvas
3
+ from tkdeft.windows.drawwidget import DDrawWidget
4
+
5
+ from .designs.button import button
6
+
7
+ from typing import Union
8
+
9
+
10
+ class FluButtonDraw(DSvgDraw):
11
+ def create_roundrect(self,
12
+ x1: Union[int, float], y1: Union[int, float], x2: Union[int, float], y2: Union[int, float],
13
+ radius: Union[int, float], radiusy: Union[int, float] = None, temppath: Union[str, None] = None,
14
+ fill: Union[str, tuple]="transparent", fill_opacity: Union[int, float]=1,
15
+ outline: Union[str, tuple] = "black", outline2: Union[str, tuple] = None,
16
+ outline_opacity: Union[int, float] = 1, outline2_opacity: Union[int, float] = 1, width: Union[int, float] = 1,
17
+ ) -> str:
18
+ """
19
+ 用于生成svg圆角矩形图片,图片默认将会保存至临时文件夹。
20
+
21
+ Parameters:
22
+ x1: 第一个x轴的坐标
23
+ y1: 第一个y轴的坐标
24
+ x2: 第二个x轴的坐标,与x1连起来
25
+ y2: 第二个y轴的坐标,与y1连起来
26
+ radius: 圆角大小
27
+ radiusy: 圆角大小(y轴方向),如果不设置,将默认为参数radius的值
28
+ temppath: 临时文件地址,如果你不知道,就别设置
29
+ fill: 背景颜色
30
+ fill_opacity: 背景透明度
31
+ outline: 边框颜色
32
+ outline2: 边框颜色2(渐变),如果取了这个值,边框将会变为渐变,从左到右,outline为第一个渐变色,outline2为第二个渐变色
33
+ outline_opacity: 边框透明度
34
+ outline2_opacity: 第二个边框渐变颜色的透明度,如果outline没有设置,则这个值不会被用到
35
+ width: 边框宽度
36
+
37
+ Returns:
38
+ svg图片保存地址
39
+ """
40
+ if radiusy:
41
+ _rx = radius
42
+ _ry = radiusy
43
+ else:
44
+ _rx, _ry = radius, radius
45
+ drawing = self.create_drawing(x2 - x1, y2 - y1, temppath=temppath)
46
+ if outline2:
47
+ border = drawing[1].linearGradient(start=(x1, y1), end=(x1, y2), id="DButton.Border",
48
+ gradientUnits="userSpaceOnUse") # 渐变色配置
49
+ border.add_stop_color("0.9", outline, outline_opacity) # 第一个渐变色的位置、第一个渐变色、第一个渐变色的透明度
50
+ border.add_stop_color("1", outline2, outline2_opacity) # 第二个渐变色的位置、第二个渐变色、第二个渐变色的透明度
51
+ drawing[1].defs.add(border)
52
+ stroke = f"url(#{border.get_id()})"
53
+ stroke_opacity = 1
54
+ else:
55
+ stroke = outline
56
+ stroke_opacity = outline_opacity
57
+ drawing[1].add(
58
+ drawing[1].rect(
59
+ (x1, y1), (x2 - x1, y2 - y1), _rx, _ry,
60
+ fill=fill, fill_opacity=fill_opacity,
61
+ stroke=stroke, stroke_width=width, stroke_opacity=stroke_opacity,
62
+ transform="translate(0.500000 0.500000)"
63
+ )
64
+ )
65
+ drawing[1].save()
66
+ return drawing[0]
67
+
68
+
69
+ class FluButtonCanvas(DCanvas):
70
+
71
+ draw = FluButtonDraw # 设置svg绘图引擎
72
+
73
+ def create_round_rectangle(self,
74
+ x1: Union[int, float], y1: Union[int, float], x2: Union[int, float], y2: Union[int, float],
75
+ r1: Union[int, float], r2: Union[int, float] = None, temppath: Union[str, None] = None,
76
+ fill: Union[str, tuple]="transparent", fill_opacity: Union[int, float] = 1,
77
+ outline: Union[str, tuple] = "black", outline2: Union[str, tuple] = "black",
78
+ outline_opacity: Union[int, float] = 1, outline2_opacity: Union[int, float] = 1,
79
+ width: Union[int, float] = 1, *args, **kwargs
80
+ ) -> int:
81
+ """
82
+ 在画布上创建个圆角矩形
83
+
84
+ Parameters:
85
+ x1: 第一个x轴的坐标
86
+ y1: 第一个y轴的坐标
87
+ x2: 第二个x轴的坐标,与x1连起来
88
+ y2: 第二个y轴的坐标,与y1连起来
89
+ r1: 圆角大小
90
+ r2: 圆角大小(y轴方向),如果不设置,将默认为参数r1的值
91
+ temppath: 临时文件地址,如果你不知道,就别设置
92
+ fill: 背景颜色
93
+ fill_opacity: 背景透明度
94
+ outline: 边框颜色
95
+ outline2: 边框颜色2(渐变),如果取了这个值,边框将会变为渐变,从左到右,outline为第一个渐变色,outline2为第二个渐变色
96
+ outline_opacity: 边框透明度
97
+ outline2_opacity: 第二个边框渐变颜色的透明度,如果outline没有设置,则这个值不会被用到
98
+ width: 边框宽度
99
+
100
+ Returns: svg图片保存地址
101
+ """
102
+ self._img = self.svgdraw.create_roundrect(
103
+ x1, y1, x2, y2, r1, r2, temppath=temppath,
104
+ fill=fill, fill_opacity=fill_opacity,
105
+ outline=outline, outline2=outline2, outline_opacity=outline_opacity, outline2_opacity=outline2_opacity,
106
+ width=width,
107
+ ) # 创建个svg圆角矩形图片
108
+ self._tkimg = self.svgdraw.create_tksvg_image(self._img) # 用tksvg读取svg图片
109
+ return self.create_image(x1, y1, anchor="nw", image=self._tkimg, *args, **kwargs) # 在画布上创建个以svg图片为图片的元件
110
+
111
+ create_roundrect = create_round_rectangle # 缩写
112
+
113
+
114
+ from .constants import MODE, STATE, BUTTONSTYLE
115
+ from .tooltip import FluToolTipBase
116
+ from .designs.gradient import FluGradient
117
+ from tkinter import Event
118
+ from tkinter.font import Font
119
+
120
+ class FluButton(FluButtonCanvas, DDrawWidget, FluToolTipBase, FluGradient):
121
+ def __init__(self, *args,
122
+ text: Union[str, int, float]= "",
123
+ width: Union[int, float] = 120,
124
+ height: Union[int, float] = 32,
125
+ command: callable = None,
126
+ font: Union[Font, tuple] = None,
127
+ mode: MODE = "light",
128
+ style: BUTTONSTYLE = "standard",
129
+ state: STATE = "normal",
130
+ **kwargs) -> None:
131
+ """
132
+ 按钮组件
133
+
134
+ Parameters:
135
+ text: 按钮的标签文本
136
+ width: 默认宽带
137
+ height: 默认高度
138
+ command: 点击时出发的事件
139
+ font: 自定义标签字体
140
+ mode: 按钮深浅主题,参考tkflu.constants.MODE
141
+ style: 按钮样式,参考tkflu.constants.BUTTONSTYLE
142
+ state: 按钮的状态,参考tkflu.constants.STATE
143
+ """
144
+ self._init(mode, style)
145
+
146
+ super().__init__(*args, width=width, height=height, **kwargs)
147
+
148
+ if command is None:
149
+ def empty(): pass
150
+
151
+ command = empty
152
+
153
+ self.dconfigure(
154
+ text=text,
155
+ command=command,
156
+ state=state,
157
+ )
158
+
159
+ self.bind("<<Clicked>>", lambda event=None: self.focus_set(), add="+")
160
+ self.bind("<<Clicked>>", lambda event=None: self.attributes.command(), add="+")
161
+
162
+ self.bind("<Return>", lambda event=None: self.attributes.command(), add="+") # 可以使用回车键模拟点击
163
+
164
+ from .defs import set_default_font
165
+ set_default_font(font, self.attributes)
166
+
167
+ def _init(self, mode: MODE, style: BUTTONSTYLE):
168
+
169
+ """
170
+ 初始化按钮,正常情况下无需在程序中调用
171
+
172
+ Parameters:
173
+ mode: 按钮深浅主题,参考tkflu.constants.MODE
174
+ style: 按钮样式,参考tkflu.constants.BUTTONSTYLE
175
+ """
176
+
177
+ from easydict import EasyDict
178
+
179
+ self.enter = False
180
+ self.button1 = False
181
+
182
+ self.attributes = EasyDict(
183
+ {
184
+ "text": "",
185
+ "command": None,
186
+ "font": None,
187
+ "state": "normal",
188
+
189
+ "rest": {},
190
+ "hover": {},
191
+ "pressed": {},
192
+ "disabled": {}
193
+ }
194
+ )
195
+
196
+ self.theme(mode=mode, style=style)
197
+
198
+ def _draw(self, event: Union[Event, None] = None, tempcolor: Union[dict, None] = None):
199
+ """
200
+
201
+ Parameters:
202
+ 绘制按钮
203
+ """
204
+ super()._draw(event)
205
+
206
+ width = self.winfo_width()
207
+ height = self.winfo_height()
208
+ # 提前定义,反正多次调用浪费资源
209
+
210
+ state = self.dcget("state")
211
+
212
+ _dict = None
213
+
214
+ if not tempcolor:
215
+ if state == "normal":
216
+ if self.enter:
217
+ if self.button1:
218
+ _dict = self.attributes.pressed
219
+ else:
220
+ _dict = self.attributes.hover
221
+ else:
222
+ _dict = self.attributes.rest
223
+ else:
224
+ _dict = self.attributes.disabled
225
+
226
+ _back_color = _dict.back_color
227
+ _back_opacity = _dict.back_opacity
228
+ _border_color = _dict.border_color
229
+ _border_color_opacity = _dict.border_color_opacity
230
+ _border_color2 = _dict.border_color2
231
+ _border_color2_opacity = _dict.border_color2_opacity
232
+ _border_width = _dict.border_width
233
+ _radius = _dict.radius
234
+ _text_color = _dict.text_color
235
+ else:
236
+ _back_color = tempcolor.back_color
237
+ _back_opacity = tempcolor.back_opacity
238
+ _border_color = tempcolor.border_color
239
+ _border_color_opacity = tempcolor.border_color_opacity
240
+ _border_color2 = tempcolor.border_color2
241
+ _border_color2_opacity = tempcolor.border_color2_opacity
242
+ _border_width = tempcolor.border_width
243
+ _radius = tempcolor.radius
244
+ _text_color = tempcolor.text_color
245
+
246
+ if hasattr(self, "element_border"):
247
+ self.delete(self.element_border)
248
+
249
+ self.element_border = self.create_round_rectangle(
250
+ 0, 0, width, height, _radius, temppath=self.temppath,
251
+ fill=_back_color, fill_opacity=_back_opacity,
252
+ outline=_border_color, outline_opacity=_border_color_opacity, outline2=_border_color2,
253
+ outline2_opacity=_border_color2_opacity,
254
+ width=_border_width,
255
+ )
256
+
257
+ if hasattr(self, "element_text"):
258
+ self.itemconfigure(self.element_text, fill=_text_color, text=self.attributes.text, font=self.attributes.font)
259
+ self.coords(self.element_text, width / 2, height / 2)
260
+ else:
261
+ self.element_text = self.create_text(
262
+ width / 2, height / 2, anchor="center",
263
+ fill=_text_color, text=self.attributes.text, font=self.attributes.font
264
+ )
265
+ self.tag_raise(self.element_text, self.element_border)
266
+
267
+ self.update()
268
+
269
+ def theme(self, mode: MODE = None, style: BUTTONSTYLE = None):
270
+ if mode:
271
+ self.mode = mode
272
+ if style:
273
+ self.style = style
274
+ theme_handlers = {
275
+ ("light", "accent"): self._light_accent,
276
+ ("light", "menu"): self._light_menu,
277
+ ("light", "standard"): self._light,
278
+ ("dark", "accent"): self._dark_accent,
279
+ ("dark", "menu"): self._dark_menu,
280
+ ("dark", "standard"): self._dark,
281
+ }
282
+ handler = theme_handlers.get((self.mode.lower(), self.style.lower()))
283
+ handler()
284
+ """if self.mode.lower() == "dark":
285
+ if self.style.lower() == "accent":
286
+ self._dark_accent()
287
+ elif self.style.lower() == "menu":
288
+ self._dark_menu()
289
+ else:
290
+ self._dark()
291
+ else:
292
+ if self.style.lower() == "accent":
293
+ self._light_accent()
294
+ elif self.style.lower() == "menu":
295
+ self._light_menu()
296
+ else:
297
+ self._light()"""
298
+
299
+ def _theme(self, mode: MODE, style: BUTTONSTYLE, animation_steps: int = None, animation_step_time: int = None):
300
+ if animation_steps is None:
301
+ from .designs.animation import get_animation_steps
302
+ animation_steps = get_animation_steps()
303
+ if animation_step_time is None:
304
+ from .designs.animation import get_animation_step_time
305
+ animation_step_time = get_animation_step_time()
306
+ r = button(mode, style, "rest")
307
+ h = button(mode, style, "hover")
308
+ p = button(mode, style, "pressed")
309
+ d = button(mode, style, "disabled")
310
+ if not animation_steps == 0 or not animation_step_time == 0:
311
+ if self.dcget("state") == "normal":
312
+ if self.enter:
313
+ if self.button1:
314
+ now = p
315
+ else:
316
+ now = h
317
+ else:
318
+ now = r
319
+ else:
320
+ now = d
321
+ #print(animation_step_time)
322
+ #print(type(animation_step_time))
323
+ if hasattr(self.attributes.rest, "back_color"):
324
+ back_colors = self.generate_hex2hex(
325
+ self.attributes.rest.back_color, now["back_color"], animation_steps
326
+ )
327
+ border_colors = self.generate_hex2hex(
328
+ self.attributes.rest.border_color, now["border_color"], animation_steps
329
+ )
330
+ if self.attributes.rest.border_color2 is None:
331
+ self.attributes.rest.border_color2 = self.attributes.rest.border_color
332
+ if now["border_color2"] is None:
333
+ now["border_color2"] = now["border_color"]
334
+ border_colors2 = self.generate_hex2hex(
335
+ self.attributes.rest.border_color2, now["border_color2"], animation_steps
336
+ )
337
+ text_colors = self.generate_hex2hex(
338
+ self.attributes.rest.text_color, now["text_color"], animation_steps
339
+ )
340
+ import numpy as np
341
+ back_opacitys = np.linspace(
342
+ float(self.attributes.rest.back_opacity), float(now["back_opacity"]), animation_steps).tolist()
343
+ border_color_opacitys = np.linspace(
344
+ float(self.attributes.rest.border_color_opacity), float(now["border_color_opacity"]), animation_steps).tolist()
345
+ if self.attributes.rest.border_color2_opacity is None:
346
+ self.attributes.rest.border_color2_opacity = self.attributes.rest.border_color_opacity
347
+ if now["border_color2_opacity"] is None:
348
+ now["border_color2_opacity"] = now["border_color_opacity"]
349
+ border_color2_opacitys = np.linspace(
350
+ float(self.attributes.rest.border_color2_opacity), float(now["border_color2_opacity"]), animation_steps).tolist()
351
+ for i in range(animation_steps):
352
+ def update(ii=i):
353
+ from easydict import EasyDict
354
+ tempcolor = EasyDict(
355
+ {
356
+ "back_color": back_colors[ii],
357
+ "back_opacity": back_opacitys[ii],
358
+ "border_color": border_colors[ii],
359
+ "border_color_opacity": str(border_color_opacitys[ii]),
360
+ "border_color2": border_colors2[ii],
361
+ "border_color2_opacity": str(border_color2_opacitys[ii]),
362
+ "border_width": 1,
363
+ "text_color": text_colors[ii],
364
+ "radius": 6,
365
+ }
366
+ )
367
+ self._draw(None, tempcolor)
368
+
369
+ self.after(i * animation_step_time, update)
370
+ #self.after(animation_steps * animation_step_time + 10, lambda: self._draw(None, None))
371
+
372
+ self.dconfigure(
373
+ rest={
374
+ "back_color": r["back_color"],
375
+ "back_opacity": r["back_opacity"],
376
+ "border_color": r["border_color"],
377
+ "border_color_opacity": r["border_color_opacity"],
378
+ "border_color2": r["border_color2"],
379
+ "border_color2_opacity": r["border_color2_opacity"],
380
+ "border_width": r["border_width"],
381
+ "radius": r["radius"],
382
+ "text_color": r["text_color"],
383
+ },
384
+ hover={
385
+ "back_color": h["back_color"],
386
+ "back_opacity": h["back_opacity"],
387
+ "border_color": h["border_color"],
388
+ "border_color_opacity": h["border_color_opacity"],
389
+ "border_color2": h["border_color2"],
390
+ "border_color2_opacity": h["border_color2_opacity"],
391
+ "border_width": h["border_width"],
392
+ "radius": h["radius"],
393
+ "text_color": h["text_color"],
394
+ },
395
+ pressed={
396
+ "back_color": p["back_color"],
397
+ "back_opacity": p["back_opacity"],
398
+ "border_color": p["border_color"],
399
+ "border_color_opacity": p["border_color_opacity"],
400
+ "border_color2": p["border_color2"],
401
+ "border_color2_opacity": p["border_color2_opacity"],
402
+ "border_width": p["border_width"],
403
+ "radius": p["radius"],
404
+ "text_color": p["text_color"],
405
+ },
406
+ disabled={
407
+ "back_color": d["back_color"],
408
+ "back_opacity": d["back_opacity"],
409
+ "border_color": d["border_color"],
410
+ "border_color_opacity": d["border_color_opacity"],
411
+ "border_color2": d["border_color2"],
412
+ "border_color2_opacity": d["border_color2_opacity"],
413
+ "border_width": d["border_width"],
414
+ "radius": d["radius"],
415
+ "text_color": d["text_color"],
416
+ }
417
+ )
418
+
419
+ def _light(self):
420
+ self._theme("light", "standard")
421
+
422
+ def _light_menu(self):
423
+ self._theme("light", "menu")
424
+
425
+ def _light_accent(self):
426
+ self._theme("light", "accent")
427
+
428
+ def _dark(self):
429
+ self._theme("dark", "standard")
430
+
431
+ def _dark_menu(self):
432
+ self._theme("dark", "menu")
433
+
434
+ def _dark_accent(self):
435
+ self._theme("dark", "accent")
436
+
437
+ def invoke(self):
438
+ self.attributes.command()
439
+
440
+ def _event_off_button1(self, event: Event = None):
441
+ self.button1 = False
442
+
443
+ self._draw(event)
444
+
445
+ if self.enter:
446
+ # self.focus_set()
447
+ if self.dcget("state") == "normal":
448
+ self.event_generate("<<Clicked>>")
@@ -126,20 +126,26 @@ 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
-
135
- 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):
138
- def update(ii=i): # 使用默认参数立即捕获i的值
139
- self.dconfigure(back_color=back_colors[ii])
140
- self._draw()
141
-
142
- self.after(i * 10, update) # 直接传递函数,不需要lambda
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()
140
+ if not animation_steps == 0 or not animation_step_time == 0:
141
+ if self.dcget("back_color"):
142
+ back_colors = self.generate_hex2hex(self.dcget("back_color"), n["back_color"], steps=animation_steps)
143
+ for i in range(animation_steps):
144
+ def update(ii=i): # 使用默认参数立即捕获i的值
145
+ self.dconfigure(back_color=back_colors[ii])
146
+ self._draw()
147
+
148
+ self.after(i * animation_step_time, update) # 直接传递函数,不需要lambda
143
149
 
144
150
  self.dconfigure(
145
151
  back_color=n["back_color"],
@@ -181,6 +187,8 @@ class BWm(FluGradient):
181
187
  if platform == "win32":
182
188
  if way == 0:
183
189
  from .customwindow import CustomWindow
190
+ import warnings
191
+ warnings.warn("This is EXPERIMENTAL! Please consider way=1 in production.")
184
192
  self.customwindow = CustomWindow(self, wait=wait)
185
193
  self.customwindow.bind_drag(self.titlebar)
186
194
  self.customwindow.bind_drag(self.titlelabel)
@@ -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(20)
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()