tkfluent 0.0.6__tar.gz → 0.0.8__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 (56) hide show
  1. {tkfluent-0.0.6 → tkfluent-0.0.8}/PKG-INFO +5 -2
  2. tkfluent-0.0.8/README.md +5 -0
  3. {tkfluent-0.0.6 → tkfluent-0.0.8}/pyproject.toml +1 -1
  4. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/__init__.py +3 -0
  5. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/__main__.py +32 -3
  6. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/button.py +8 -5
  7. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/constants.py +5 -0
  8. tkfluent-0.0.8/tkflu/defs.py +41 -0
  9. tkfluent-0.0.8/tkflu/designs/slider.py +253 -0
  10. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/window.py +2 -2
  11. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/entry.py +3 -1
  12. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/menu.py +4 -4
  13. tkfluent-0.0.8/tkflu/slider.py +404 -0
  14. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/text.py +5 -1
  15. tkfluent-0.0.6/README.md +0 -3
  16. tkfluent-0.0.6/tkflu/defs.py +0 -16
  17. tkfluent-0.0.6/tkflu/designs/__pycache__/__init__.cpython-311.pyc +0 -0
  18. tkfluent-0.0.6/tkflu/designs/__pycache__/badge.cpython-311.pyc +0 -0
  19. tkfluent-0.0.6/tkflu/designs/__pycache__/button.cpython-311.pyc +0 -0
  20. tkfluent-0.0.6/tkflu/designs/__pycache__/design.cpython-311.pyc +0 -0
  21. tkfluent-0.0.6/tkflu/designs/__pycache__/entry.cpython-311.pyc +0 -0
  22. tkfluent-0.0.6/tkflu/designs/__pycache__/frame.cpython-311.pyc +0 -0
  23. tkfluent-0.0.6/tkflu/designs/__pycache__/primary_color.cpython-311.pyc +0 -0
  24. tkfluent-0.0.6/tkflu/designs/__pycache__/text.cpython-311.pyc +0 -0
  25. tkfluent-0.0.6/tkflu/designs/__pycache__/window.cpython-311.pyc +0 -0
  26. tkfluent-0.0.6/tkflu/designs/fonts/__pycache__/__init__.cpython-311.pyc +0 -0
  27. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/badge.py +0 -0
  28. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/bwm.py +0 -0
  29. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/checkbox.py +0 -0
  30. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/customwindow.py +0 -0
  31. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/customwindow2.py +0 -0
  32. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/__init__.py +0 -0
  33. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/badge.py +0 -0
  34. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/button.py +0 -0
  35. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/design.py +0 -0
  36. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/entry.py +0 -0
  37. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/fonts/__init__.py +0 -0
  38. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/fonts/segoeui.ttf +0 -0
  39. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/frame.py +0 -0
  40. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/primary_color.py +0 -0
  41. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/designs/text.py +0 -0
  42. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/frame.py +0 -0
  43. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/icons.py +0 -0
  44. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/image.py +0 -0
  45. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/label.py +0 -0
  46. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/listbox.py +0 -0
  47. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/litenav.py +0 -0
  48. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/menubar.py +0 -0
  49. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/popupmenu.py +0 -0
  50. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/popupwindow.py +0 -0
  51. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/scrollbar.py +0 -0
  52. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/thememanager.py +0 -0
  53. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/togglebutton.py +0 -0
  54. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/tooltip.py +0 -0
  55. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/toplevel.py +0 -0
  56. {tkfluent-0.0.6 → tkfluent-0.0.8}/tkflu/window.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: tkfluent
3
- Version: 0.0.6
3
+ Version: 0.0.8
4
4
  Summary: Fluent Design for Tkinter
5
5
  Author: XiangQinxi
6
6
  Author-email: xiangqinxi@outlook.com
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.9
12
12
  Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
15
16
  Requires-Dist: easydict (>=1.13,<2.0)
16
17
  Requires-Dist: pillow (>=10.2.0,<11.0.0)
17
18
  Requires-Dist: svgwrite (>=1.4.3,<2.0.0)
@@ -24,3 +25,5 @@ Description-Content-Type: text/markdown
24
25
  # tkfluent
25
26
 
26
27
  `tkinter`现代化组件库。设计来于`Fluent` `WinUI3` 设计
28
+
29
+ ![](https://learn.microsoft.com/zh-cn/windows/apps/images/logo-winui.png)
@@ -0,0 +1,5 @@
1
+ # tkfluent
2
+
3
+ `tkinter`现代化组件库。设计来于`Fluent` `WinUI3` 设计
4
+
5
+ ![](https://learn.microsoft.com/zh-cn/windows/apps/images/logo-winui.png)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "tkfluent"
3
- version = "0.0.6"
3
+ version = "0.0.8"
4
4
  description = "Fluent Design for Tkinter"
5
5
  authors = ["XiangQinxi <xiangqinxi@outlook.com>"]
6
6
  readme = "README.md"
@@ -9,15 +9,18 @@ Fluent设计的tkinter组件库(模板)
9
9
 
10
10
  from .badge import FluBadge
11
11
  from .button import FluButton
12
+ from .bwm import BWm
12
13
  from .constants import *
13
14
  from .defs import *
14
15
  from .entry import FluEntry
15
16
  from .frame import FluFrame
17
+ from .icons import *
16
18
  from .label import FluLabel
17
19
  from .menu import FluMenu
18
20
  from .menubar import FluMenuBar
19
21
  from .popupmenu import FluPopupMenu, FluPopupMenuWindow
20
22
  from .popupwindow import FluPopupWindow
23
+ from .slider import FluSlider
21
24
  from .text import FluText
22
25
  from .thememanager import FluThemeManager
23
26
  from .togglebutton import FluToggleButton
@@ -2,11 +2,28 @@ from tkflu import *
2
2
  from tkinter import *
3
3
  from tkinter.font import *
4
4
 
5
- orange_primary_color()
6
-
5
+ from tkflu.listbox import FluListBox
6
+
7
+ blue_primary_color()
8
+
9
+ def togglestate():
10
+ if button1.dcget("state") == NORMAL:
11
+ button1.dconfigure(state=DISABLED)
12
+ button2.dconfigure(state=DISABLED)
13
+ entry1.dconfigure(state=DISABLED)
14
+ button1._draw()
15
+ button2._draw()
16
+ entry1._draw()
17
+ else:
18
+ button1.dconfigure(state=NORMAL)
19
+ button2.dconfigure(state=NORMAL)
20
+ entry1.dconfigure(state=NORMAL)
21
+ button1._draw()
22
+ button2._draw()
23
+ entry1._draw()
7
24
  root = FluWindow()
8
25
  #root.wincustom(way=0)
9
- root.wm_geometry("360x500")
26
+ root.geometry("360x600")
10
27
 
11
28
  popupmenu = FluPopupMenu()
12
29
 
@@ -72,6 +89,11 @@ togglebutton2 = FluToggleButton(
72
89
  )
73
90
  togglebutton2.pack(fill="x", padx=5, pady=5)
74
91
 
92
+ togglebutton3 = FluToggleButton(
93
+ frame, text="Toggle State", command=lambda: togglestate()
94
+ )
95
+ togglebutton3.pack(fill="x", padx=5, pady=5)
96
+
75
97
  entry1 = FluEntry(frame)
76
98
  entry1.pack(fill="x", padx=5, pady=5)
77
99
 
@@ -81,6 +103,13 @@ entry2.pack(fill="x", padx=5, pady=5)
81
103
  text1 = FluText(frame)
82
104
  text1.pack(fill="x", padx=5, pady=5)
83
105
 
106
+ slider1 = FluSlider(frame, value=0)
107
+ slider1.pack(fill="x", padx=5, pady=5)
108
+
109
+ """listbox1 = FluListBox(frame)
110
+ listbox1.dconfigure()
111
+ listbox1.pack(fill="x", padx=5, pady=5)"""
112
+
84
113
  frame.pack(fill="both", expand="yes", side="right", padx=5, pady=5)
85
114
 
86
115
  root.mainloop()
@@ -61,6 +61,9 @@ class FluButtonCanvas(DCanvas):
61
61
  create_roundrect = create_round_rectangle
62
62
 
63
63
 
64
+ from .constants import MODE, STATE, BUTTONSTYLE
65
+
66
+
64
67
  class FluButton(FluButtonCanvas, DDrawWidget):
65
68
  def __init__(self, *args,
66
69
  text="",
@@ -68,9 +71,9 @@ class FluButton(FluButtonCanvas, DDrawWidget):
68
71
  height=32,
69
72
  command=None,
70
73
  font=None,
71
- mode="light",
72
- style="standard",
73
- state="normal",
74
+ mode: MODE = "light",
75
+ style: BUTTONSTYLE = "standard",
76
+ state: STATE = "normal",
74
77
  **kwargs):
75
78
  self._init(mode, style)
76
79
 
@@ -95,7 +98,7 @@ class FluButton(FluButtonCanvas, DDrawWidget):
95
98
  from .defs import set_default_font
96
99
  set_default_font(font, self.attributes)
97
100
 
98
- def _init(self, mode, style):
101
+ def _init(self, mode: MODE, style: STATE):
99
102
 
100
103
  from easydict import EasyDict
101
104
 
@@ -161,7 +164,7 @@ class FluButton(FluButtonCanvas, DDrawWidget):
161
164
  fill=_text_color, text=self.attributes.text, font=self.attributes.font
162
165
  )
163
166
 
164
- def theme(self, mode=None, style=None):
167
+ def theme(self, mode: MODE = None, style: BUTTONSTYLE = None):
165
168
  if mode:
166
169
  self.mode = mode
167
170
  if style:
@@ -1,15 +1,20 @@
1
+ from typing import Literal
2
+
1
3
  NO = FALSE = OFF = 0
2
4
  YES = TRUE = ON = 1
3
5
 
4
6
  # Modes
5
7
  LIGHT = 'light'
6
8
  DARK = 'dark'
9
+ MODE = Literal["light", "dark"]
7
10
 
8
11
  # States
9
12
  NORMAL = 'normal'
10
13
  DISABLED = 'disabled'
14
+ STATE = Literal["normal", "disabled"]
11
15
 
12
16
  # FluButton Styles
13
17
  STANDARD = 'standard'
14
18
  ACCENT = 'accent'
15
19
  MENU = 'menu'
20
+ BUTTONSTYLE = Literal["standard", "accent", "menu"]
@@ -0,0 +1,41 @@
1
+ def toggle_theme(toggle_button, thememanager):
2
+ if toggle_button.dcget('checked'):
3
+ thememanager.mode("dark")
4
+ else:
5
+ thememanager.mode("light")
6
+
7
+
8
+ def set_default_font(font, attributes):
9
+ if font is None:
10
+ from .designs.fonts import SegoeFont
11
+ attributes.font = SegoeFont()
12
+
13
+
14
+ def red_primary_color():
15
+ from .designs.primary_color import set_primary_color
16
+ set_primary_color(("#d20e1e", "#f46762"))
17
+
18
+
19
+ def orange_primary_color():
20
+ from .designs.primary_color import set_primary_color
21
+ set_primary_color(("#c53201", "#fe7e34"))
22
+
23
+
24
+ def yellow_primary_color():
25
+ from .designs.primary_color import set_primary_color
26
+ set_primary_color(("#e19d00", "#ffd52a"))
27
+
28
+
29
+ def green_primary_color():
30
+ from .designs.primary_color import set_primary_color
31
+ set_primary_color(("#0e6d0e", "#45e532"))
32
+
33
+
34
+ def blue_primary_color():
35
+ from .designs.primary_color import set_primary_color
36
+ set_primary_color(("#005fb8", "#60cdff"))
37
+
38
+
39
+ def purple_primary_color():
40
+ from .designs.primary_color import set_primary_color
41
+ set_primary_color(("#4f4dce", "#b5adeb"))
@@ -0,0 +1,253 @@
1
+ from .primary_color import get_primary_color
2
+
3
+
4
+ def slider(mode: str, state: str):
5
+ mode = mode.lower()
6
+ state = state.lower()
7
+
8
+ if mode == "light":
9
+ if state == "rest":
10
+ return {
11
+ "radius": 2,
12
+ "thumb": {
13
+ "radius": 12,
14
+ "inner_radius": 6,
15
+
16
+ "back_color": "#FFFFFF",
17
+ "back_opacity": 1,
18
+
19
+ "border_color": "#000000",
20
+ "border_color_opacity": 0.058824,
21
+
22
+ "border_color2": "#000000",
23
+ "border_color2_opacity": 0.160784,
24
+
25
+ "inner_back_color": get_primary_color()[0],
26
+ "inner_back_opacity": 1,
27
+ },
28
+ "track": {
29
+ "width": 4,
30
+
31
+ "back_color": get_primary_color()[0],
32
+ "back_opacity": 1
33
+ },
34
+ "rail": {
35
+ "back_color": "#000000",
36
+ "back_opacity": 0.445800
37
+ }
38
+ }
39
+ elif state == "hover":
40
+ return {
41
+ "radius": 2,
42
+ "thumb": {
43
+ "radius": 12,
44
+ "inner_radius": 8,
45
+
46
+ "back_color": "#FFFFFF",
47
+ "back_opacity": 1,
48
+
49
+ "border_color": "#000000",
50
+ "border_color_opacity": 0.058824,
51
+
52
+ "border_color2": "#000000",
53
+ "border_color2_opacity": 0.160784,
54
+
55
+ "inner_back_color": get_primary_color()[0],
56
+ "inner_back_opacity": 1,
57
+ },
58
+ "track": {
59
+ "width": 4,
60
+
61
+ "back_color": get_primary_color()[0],
62
+ "back_opacity": 1
63
+ },
64
+ "rail": {
65
+ "back_color": "#000000",
66
+ "back_opacity": 0.445800
67
+ }
68
+ }
69
+ elif state == "pressed":
70
+ return {
71
+ "radius": 2,
72
+ "thumb": {
73
+ "radius": 12,
74
+ "inner_radius": 5,
75
+
76
+ "back_color": "#FFFFFF",
77
+ "back_opacity": 1,
78
+
79
+ "border_color": "#000000",
80
+ "border_color_opacity": 0.058824,
81
+
82
+ "border_color2": "#000000",
83
+ "border_color2_opacity": 0.160784,
84
+
85
+ "inner_back_color": get_primary_color()[0],
86
+ "inner_back_opacity": 0.8,
87
+ },
88
+ "track": {
89
+ "width": 4,
90
+
91
+ "back_color": get_primary_color()[0],
92
+ "back_opacity": 1
93
+ },
94
+ "rail": {
95
+ "back_color": "#000000",
96
+ "back_opacity": 0.445800
97
+ }
98
+ }
99
+ elif state == "disabled":
100
+ return {
101
+ "radius": 2,
102
+ "thumb": {
103
+ "radius": 12,
104
+ "inner_radius": 6,
105
+
106
+ "back_color": "#FFFFFF",
107
+ "back_opacity": 1,
108
+
109
+ "border_color": "#000000",
110
+ "border_color_opacity": 0.058824,
111
+
112
+ "border_color2": "#000000",
113
+ "border_color2_opacity": 0.160784,
114
+
115
+ "inner_back_color": "#000000",
116
+ "inner_back_opacity": 0.317300,
117
+ },
118
+ "track": {
119
+ "width": 4,
120
+
121
+ "back_color": "#000000",
122
+ "back_opacity": 0.216900
123
+ },
124
+ "rail": {
125
+ "back_color": "#000000",
126
+ "back_opacity": 0.317300
127
+ }
128
+ }
129
+ else:
130
+ if state == "rest":
131
+ return {
132
+ "radius": 2,
133
+ "thumb": {
134
+ "radius": 12,
135
+
136
+ "inner_radius": 6,
137
+ "inner_back_color": get_primary_color()[1],
138
+ "inner_back_opacity": 1,
139
+
140
+ "back_color": "#454545",
141
+ "back_opacity": 1,
142
+
143
+ "border_color": "#FFFFFF",
144
+ "border_color_opacity": 0.094118,
145
+
146
+ "border_color2": "#FFFFFF",
147
+ "border_color2_opacity": 0.070588,
148
+
149
+ },
150
+ "track": {
151
+ "width": 4,
152
+
153
+ "back_color": get_primary_color()[1],
154
+ "back_opacity": 1
155
+ },
156
+ "rail": {
157
+ "back_color": "#FFFFFF",
158
+ "back_opacity": 0.544200
159
+ }
160
+ }
161
+ elif state == "hover":
162
+ return {
163
+ "radius": 2,
164
+ "thumb": {
165
+ "radius": 12,
166
+
167
+ "inner_radius": 8,
168
+ "inner_back_color": get_primary_color()[1],
169
+ "inner_back_opacity": 1,
170
+
171
+ "back_color": "#454545",
172
+ "back_opacity": 1,
173
+
174
+ "border_color": "#FFFFFF",
175
+ "border_color_opacity": 0.094118,
176
+
177
+ "border_color2": "#FFFFFF",
178
+ "border_color2_opacity": 0.070588,
179
+
180
+ },
181
+ "track": {
182
+ "width": 4,
183
+
184
+ "back_color": get_primary_color()[1],
185
+ "back_opacity": 1
186
+ },
187
+ "rail": {
188
+ "back_color": "#FFFFFF",
189
+ "back_opacity": 0.544200
190
+ }
191
+ }
192
+ elif state == "pressed":
193
+ return {
194
+ "radius": 2,
195
+ "thumb": {
196
+ "radius": 12,
197
+
198
+ "inner_radius": 5,
199
+ "inner_back_color": get_primary_color()[1],
200
+ "inner_back_opacity": 0.8,
201
+
202
+ "back_color": "#454545",
203
+ "back_opacity": 1,
204
+
205
+ "border_color": "#FFFFFF",
206
+ "border_color_opacity": 0.094118,
207
+
208
+ "border_color2": "#FFFFFF",
209
+ "border_color2_opacity": 0.070588,
210
+
211
+ },
212
+ "track": {
213
+ "width": 4,
214
+
215
+ "back_color": get_primary_color()[1],
216
+ "back_opacity": 1
217
+ },
218
+ "rail": {
219
+ "back_color": "#FFFFFF",
220
+ "back_opacity": 0.544200
221
+ }
222
+ }
223
+ elif state == "disabled":
224
+ return {
225
+ "radius": 2,
226
+ "thumb": {
227
+ "radius": 12,
228
+
229
+ "inner_radius": 6,
230
+ "inner_back_color": "#FFFFFF",
231
+ "inner_back_opacity": 0.158100,
232
+
233
+ "back_color": "#454545",
234
+ "back_opacity": 1,
235
+
236
+ "border_color": "#FFFFFF",
237
+ "border_color_opacity": 0.094118,
238
+
239
+ "border_color2": "#FFFFFF",
240
+ "border_color2_opacity": 0.070588,
241
+
242
+ },
243
+ "track": {
244
+ "width": 4,
245
+
246
+ "back_color": "#FFFFFF",
247
+ "back_opacity": 0.158100
248
+ },
249
+ "rail": {
250
+ "back_color": "#FFFFFF",
251
+ "back_opacity": 0.544200
252
+ }
253
+ }
@@ -1,7 +1,7 @@
1
1
  def window(mode):
2
2
  if mode.lower() == "light":
3
3
  return {
4
- "back_color": "#ffffff",
4
+ "back_color": "#f9f9f9",
5
5
  "text_color": "#000000",
6
6
  "closebutton": {
7
7
  "back_color": "#cf392d",
@@ -11,7 +11,7 @@ def window(mode):
11
11
  }
12
12
  else:
13
13
  return {
14
- "back_color": "#202020",
14
+ "back_color": "#282828",
15
15
  "text_color": "#ffffff",
16
16
  "closebutton": {
17
17
  "back_color": "#c42b1c",
@@ -96,7 +96,7 @@ class FluEntry(FluEntryCanvas, DDrawWidget):
96
96
 
97
97
  super().__init__(*args, width=width, height=height, cursor=cursor, **kwargs)
98
98
 
99
- self.bind("<FocusIn>", self._event_focus_in, add="+")
99
+ self.bind("<Button-1>", lambda e: self.entry.focus_set())
100
100
 
101
101
  self.dconfigure(
102
102
  state=state,
@@ -188,6 +188,8 @@ class FluEntry(FluEntryCanvas, DDrawWidget):
188
188
  height=self.winfo_height() - _border_width * 2 - _radius
189
189
  )
190
190
 
191
+ self.tag_raise(self.element_text)
192
+
191
193
  def _event_focus_in(self, event=None):
192
194
  self.isfocus = True
193
195
 
@@ -84,19 +84,19 @@ class FluMenu(FluPopupMenu):
84
84
  else:
85
85
  id = widget._w
86
86
 
87
- def command():
87
+ def command(event=None):
88
88
  print(menu._w)
89
- menu.focus_set()
90
89
 
91
90
  menu.popup(widget.winfo_rootx()+widget.winfo_width()+100, widget.winfo_rooty())
92
91
  menu.window.deiconify()
93
92
  menu.window.attributes("-topmost")
94
93
 
95
94
  if hasattr(widget, "dconfigure"):
96
- widget.dconfigure(text=label, command=command)
95
+ widget.dconfigure(text=label)
97
96
  else:
98
97
  if hasattr(widget, "configure"):
99
- widget.configure(text=label, command=command)
98
+ widget.configure(text=label)
99
+ widget.bind("<Enter>", command, add="+")
100
100
  if hasattr(widget, "theme"):
101
101
  widget.theme(style=style)
102
102
 
@@ -0,0 +1,404 @@
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.slider import slider
6
+
7
+
8
+ class FluSliderDraw(DSvgDraw):
9
+ def create_slider(
10
+ self,
11
+ x1, y1, x2, y2,
12
+ x3, # 滑块的x坐标
13
+ r1, # 滑块外圆半径
14
+ r2, # 滑块内圆半径
15
+ temppath=None,
16
+ fill="transparent", fill_opacity=1, # 滑块外圆的背景颜色、透明度
17
+ radius=3, # 滑块进度条圆角大小
18
+ outline="transparent", outline_opacity=1, # 滑块伪阴影的渐变色中的第一个渐变颜色、透明度
19
+ outline2="transparent", outline2_opacity=1, # 滑块伪阴影的渐变色中的第二个渐变颜色、透明度
20
+ inner_fill="transparent", inner_fill_opacity=1, # 滑块内圆的背景颜色、透明度
21
+ track_fill="transparent", track_height=4, track_opacity=1, # 滑块进度条的选中部分矩形的背景颜色、高度、透明度
22
+ rail_fill="transparent", rail_opacity=1 #
23
+ ):
24
+ drawing = self.create_drawing(x2 - x1, y2 - y1, temppath=temppath, fill_opacity=0)
25
+
26
+ border = drawing[1].linearGradient(start=(r1, 1), end=(r1, r1 * 2 - 1), id="DButton.Border",
27
+ gradientUnits="userSpaceOnUse")
28
+ border.add_stop_color(0.500208, outline, outline_opacity)
29
+ border.add_stop_color(0.954545, outline2, outline2_opacity)
30
+ drawing[1].defs.add(border)
31
+ stroke = f"url(#{border.get_id()})"
32
+ print("x1:", x1, "\n", "y1:", y1, "\n", "x2:", x2, "\n", "y2:", y2, "\n", "r1:", r1, "\n", sep="")
33
+
34
+ x = x1 + r1 - 4
35
+ xx = x2 - r1 + 4
36
+
37
+ print("track_x1:", x, "\n", "track_x2:", xx, sep="")
38
+
39
+ print("")
40
+
41
+ drawing[1].add(
42
+ drawing[1].rect(
43
+ (x, (y2 - y1) / 2 - track_height / 2),
44
+ # 矩形x位置:画布最左的x坐标 + 滑块外半径 - 滑块内半径
45
+ # 矩形y位置:画布高度(画布最上的y坐标 - 画布最上的y坐标)一半 - 进度条的高度的一半
46
+ (xx - x, track_height),
47
+ # 矩形宽度:画布最右的x坐标 - 滑块外半径 + 滑块内半径 | 矩形高度:进度条的高度
48
+ rx=radius,
49
+ fill=rail_fill, fill_opacity=rail_opacity
50
+ )
51
+ ) # 滑块进度未选中区域 (占全部)
52
+
53
+ drawing[1].add(
54
+ drawing[1].rect(
55
+ (x, (y2 - y1) / 2 - track_height / 2),
56
+ # 矩形x位置:画布最左的x坐标 + 滑块外半径 - 滑块内半径
57
+ # 矩形y位置:画布高度(画布最上的y坐标 - 画布最上的y坐标)一半 - 进度条的高度的一半
58
+ (x3 - x, track_height),
59
+ # 矩形宽度:(滑块的x坐标 - 矩形x位置) | 矩形高度:进度条的高度
60
+ rx=radius,
61
+ fill=track_fill, fill_opacity=track_opacity, fill_rule="evenodd"
62
+ )
63
+ ) # 滑块进度左边的选中区域 (只左部分)
64
+
65
+ x = x3
66
+ y = (y2 - y1) / 2
67
+
68
+ drawing[1].add(
69
+ drawing[1].circle(
70
+ (x, y), r1,
71
+ fill=stroke, fill_opacity=1, fill_rule="evenodd"
72
+ )
73
+ ) # 圆形滑块的伪阴影边框
74
+ drawing[1].add(
75
+ drawing[1].circle(
76
+ (x, y), r1 - 1,
77
+ fill=fill, fill_opacity=fill_opacity, fill_rule="nonzero"
78
+ )
79
+ ) # 圆形滑块的外填充
80
+ drawing[1].add(
81
+ drawing[1].circle(
82
+ (x, y), r2,
83
+ fill=inner_fill, fill_opacity=inner_fill_opacity, fill_rule="nonzero"
84
+ )
85
+ ) # 圆形滑块的内填充
86
+ drawing[1].save()
87
+ return drawing[0]
88
+
89
+
90
+ class FluSliderCanvas(DCanvas):
91
+ draw = FluSliderDraw
92
+
93
+ def create_slider(self,
94
+ x1, y1, x2, y2, x3, r1, r2, temppath=None,
95
+ fill="transparent", fill_opacity=1, radius=3,
96
+ outline="transparent", outline_opacity=1,
97
+ outline2="transparent", outline2_opacity=1,
98
+ inner_fill="transparent", inner_fill_opacity=1,
99
+ track_fill="transparent", track_height=4, track_opacity=1,
100
+ rail_fill="transparent", rail_opacity=1
101
+ ):
102
+ self._img = self.svgdraw.create_slider(
103
+ x1, y1, x2, y2, x3, r1, r2, temppath=temppath,
104
+ fill=fill, fill_opacity=fill_opacity, radius=radius,
105
+ outline=outline, outline_opacity=outline_opacity,
106
+ outline2=outline2, outline2_opacity=outline2_opacity,
107
+ inner_fill=inner_fill, inner_fill_opacity=inner_fill_opacity,
108
+ track_fill=track_fill, track_height=track_height, track_opacity=track_opacity,
109
+ rail_fill=rail_fill, rail_opacity=rail_opacity
110
+ )
111
+ self._tkimg = self.svgdraw.create_tksvg_image(self._img)
112
+ return self.create_image(x1, y1, anchor="nw", image=self._tkimg)
113
+
114
+
115
+ class FluSlider(FluSliderCanvas, DDrawWidget):
116
+ def __init__(self, *args,
117
+ text="",
118
+ width=70,
119
+ height=28,
120
+ font=None,
121
+ mode="light",
122
+ state="normal",
123
+ value=20,
124
+ max=100,
125
+ min=0,
126
+ **kwargs
127
+ ):
128
+
129
+ """
130
+
131
+ 初始化类
132
+
133
+ :param args: 参照tkinter.Canvas.__init__
134
+ :param text:
135
+ :param width:
136
+ :param height:
137
+ :param font:
138
+ :param mode: Fluent主题模式 分为 “light” “dark”
139
+ :param style:
140
+ :param kwargs: 参照tkinter.Canvas.__init__
141
+ """
142
+
143
+ self._init(mode)
144
+
145
+ self.dconfigure(
146
+ state=state,
147
+ value=value,
148
+ max=max, min=min,
149
+ )
150
+
151
+ super().__init__(*args, width=width, height=height, **kwargs)
152
+
153
+ self.bind("<<Clicked>>", lambda event=None: self.focus_set(), add="+")
154
+
155
+ self.bind("<Motion>", self._event_button1_motion)
156
+
157
+ from .defs import set_default_font
158
+ set_default_font(font, self.attributes)
159
+
160
+ def _init(self, mode):
161
+ from easydict import EasyDict
162
+
163
+ self.attributes = EasyDict(
164
+ {
165
+ "command": None,
166
+ "state": None,
167
+
168
+ "value": 20,
169
+ "max": 100,
170
+ "min": 0,
171
+
172
+ "rest": {},
173
+ "hover": {},
174
+ "pressed": {},
175
+ "disabled": {},
176
+ }
177
+ )
178
+
179
+ self.theme(mode)
180
+
181
+ def _draw(self, event=None):
182
+
183
+ """
184
+ 重新绘制组件
185
+
186
+ :param event:
187
+ """
188
+
189
+ super()._draw(event)
190
+
191
+ print("width:", self.winfo_width(), "\n", "height:", self.winfo_height(), sep="")
192
+
193
+ print("")
194
+
195
+ self.delete("all")
196
+
197
+ state = self.dcget("state")
198
+
199
+ _dict = None
200
+
201
+ if state == "normal":
202
+ if event:
203
+ if self.enter:
204
+ if self.button1:
205
+ _dict = self.attributes.pressed
206
+ else:
207
+ _dict = self.attributes.hover
208
+ else:
209
+ _dict = self.attributes.rest
210
+ else:
211
+ _dict = self.attributes.rest
212
+ else:
213
+ _dict = self.attributes.disabled
214
+
215
+ _radius = _dict.radius
216
+
217
+ _track_height = _dict.track.width
218
+ _track_back_color = _dict.track.back_color
219
+ _track_back_opacity = _dict.track.back_opacity
220
+
221
+ _rail_back_color = _dict.rail.back_color
222
+ _rail_back_opacity = _dict.rail.back_opacity
223
+
224
+ _thumb_radius = _dict.thumb.radius
225
+ _thumb_inner_radius = _dict.thumb.inner_radius
226
+
227
+ _thumb_back_color = _dict.thumb.back_color
228
+ _thumb_back_opacity = _dict.thumb.back_opacity
229
+
230
+ _thumb_border_color = _dict.thumb.border_color
231
+ _thumb_border_color_opacity = _dict.thumb.border_color_opacity
232
+
233
+ _thumb_border_color2 = _dict.thumb.border_color2
234
+ _thumb_border_color2_opacity = _dict.thumb.border_color2_opacity
235
+
236
+ _thumb_inner_back_color = _dict.thumb.inner_back_color
237
+ _thumb_inner_back_opacity = _dict.thumb.inner_back_opacity
238
+
239
+ thumb_xp = self.attributes.value / (self.attributes.max - self.attributes.min) # 滑块对应数值的比例
240
+ thumb_x = (self.winfo_width() - (_thumb_radius + 4) * 2) * thumb_xp # 滑块对应数值的x左边
241
+
242
+ self.attributes["^r"] = _thumb_radius # 滑块进度条x坐标
243
+ self.attributes["^x"] = _thumb_radius - 4 # 滑块进度条
244
+ self.attributes["^xx"] = self.winfo_width() - _thumb_radius + 4
245
+
246
+ self.element_thumb = self.create_slider(
247
+ 0, 0, self.winfo_width(), self.winfo_height(), thumb_x, _thumb_radius, _thumb_inner_radius,
248
+ temppath=self.temppath,
249
+ fill=_thumb_back_color, fill_opacity=_thumb_back_opacity, radius=_radius,
250
+ outline=_thumb_border_color, outline_opacity=_thumb_border_color_opacity,
251
+ outline2=_thumb_border_color2, outline2_opacity=_thumb_border_color2_opacity,
252
+ inner_fill=_thumb_inner_back_color, inner_fill_opacity=_thumb_inner_back_opacity,
253
+ track_height=_track_height, track_fill=_track_back_color, track_opacity=_track_back_opacity,
254
+ rail_fill=_rail_back_color, rail_opacity=_rail_back_opacity
255
+ )
256
+
257
+ def pos(self, event):
258
+ if self.enter:
259
+ if self.button1:
260
+ valuep = (event.x - self.attributes["^x"]) / (self.attributes["^xx"] - self.attributes["^x"]) # 数值的比例:(鼠标点击的x坐标 - 滑块进度条的x坐标) ÷ 滑块进度条的宽度
261
+ value = (event.x - self.attributes["max"] - self.attributes["min"]) # 数值的比例 × 数值范围(最大数值 - 最小数值)
262
+ value = ((event.x + self.attributes["^r"]) / (self.winfo_width())) * self.attributes.max
263
+ self.dconfigure(
264
+ value=value
265
+ )
266
+ print("value:", value, sep="")
267
+ print("")
268
+
269
+ def _event_button1_motion(self, event):
270
+ self.pos(event)
271
+
272
+ def _event_on_button1(self, event=None):
273
+ super()._event_on_button1(event=event)
274
+ self.pos(event)
275
+
276
+ def theme(self, mode=None):
277
+ if mode:
278
+ self.mode = mode
279
+ if self.mode.lower() == "dark":
280
+ self._dark()
281
+ else:
282
+ self._light()
283
+
284
+ def _theme(self, mode):
285
+ r = slider(mode, "rest")
286
+ h = slider(mode, "hover")
287
+ p = slider(mode, "pressed")
288
+ d = slider(mode, "disabled")
289
+ self.dconfigure(
290
+ rest={
291
+ "radius": r["radius"],
292
+ "thumb": {
293
+ "radius": r["thumb"]["radius"],
294
+ "inner_radius": r["thumb"]["inner_radius"],
295
+
296
+ "back_color": r["thumb"]["back_color"],
297
+ "back_opacity": r["thumb"]["back_opacity"],
298
+
299
+ "border_color": r["thumb"]["border_color"],
300
+ "border_color_opacity": r["thumb"]["border_color_opacity"],
301
+ "border_color2": r["thumb"]["border_color2"],
302
+ "border_color2_opacity": r["thumb"]["border_color2_opacity"],
303
+
304
+ "inner_back_color": r["thumb"]["inner_back_color"],
305
+ "inner_back_opacity": r["thumb"]["inner_back_opacity"],
306
+ },
307
+ "track": {
308
+ "back_color": r["track"]["back_color"],
309
+ "back_opacity": r["track"]["back_opacity"],
310
+ "width": r["track"]["width"]
311
+ },
312
+ "rail": {
313
+ "back_color": r["rail"]["back_color"],
314
+ "back_opacity": r["rail"]["back_opacity"],
315
+ }
316
+ },
317
+ hover={
318
+ "radius": h["radius"],
319
+ "thumb": {
320
+ "radius": h["thumb"]["radius"],
321
+ "inner_radius": h["thumb"]["inner_radius"],
322
+
323
+ "back_color": h["thumb"]["back_color"],
324
+ "back_opacity": h["thumb"]["back_opacity"],
325
+
326
+ "border_color": h["thumb"]["border_color"],
327
+ "border_color_opacity": h["thumb"]["border_color_opacity"],
328
+ "border_color2": h["thumb"]["border_color2"],
329
+ "border_color2_opacity": h["thumb"]["border_color2_opacity"],
330
+
331
+ "inner_back_color": h["thumb"]["inner_back_color"],
332
+ "inner_back_opacity": h["thumb"]["inner_back_opacity"],
333
+ },
334
+ "track": {
335
+ "back_color": h["track"]["back_color"],
336
+ "back_opacity": h["track"]["back_opacity"],
337
+ "width": h["track"]["width"]
338
+ },
339
+ "rail": {
340
+ "back_color": h["rail"]["back_color"],
341
+ "back_opacity": h["rail"]["back_opacity"],
342
+ }
343
+ },
344
+ pressed={
345
+ "radius": p["radius"],
346
+ "thumb": {
347
+ "radius": p["thumb"]["radius"],
348
+ "inner_radius": p["thumb"]["inner_radius"],
349
+
350
+ "back_color": p["thumb"]["back_color"],
351
+ "back_opacity": p["thumb"]["back_opacity"],
352
+
353
+ "border_color": p["thumb"]["border_color"],
354
+ "border_color_opacity": p["thumb"]["border_color_opacity"],
355
+ "border_color2": p["thumb"]["border_color2"],
356
+ "border_color2_opacity": p["thumb"]["border_color2_opacity"],
357
+
358
+ "inner_back_color": p["thumb"]["inner_back_color"],
359
+ "inner_back_opacity": p["thumb"]["inner_back_opacity"],
360
+ },
361
+ "track": {
362
+ "back_color": p["track"]["back_color"],
363
+ "back_opacity": p["track"]["back_opacity"],
364
+ "width": p["track"]["width"]
365
+ },
366
+ "rail": {
367
+ "back_color": p["rail"]["back_color"],
368
+ "back_opacity": p["rail"]["back_opacity"],
369
+ }
370
+ },
371
+ disabled={
372
+ "radius": d["radius"],
373
+ "thumb": {
374
+ "radius": d["thumb"]["radius"],
375
+ "inner_radius": d["thumb"]["inner_radius"],
376
+
377
+ "back_color": d["thumb"]["back_color"],
378
+ "back_opacity": d["thumb"]["back_opacity"],
379
+
380
+ "border_color": d["thumb"]["border_color"],
381
+ "border_color_opacity": d["thumb"]["border_color_opacity"],
382
+ "border_color2": d["thumb"]["border_color2"],
383
+ "border_color2_opacity": d["thumb"]["border_color2_opacity"],
384
+
385
+ "inner_back_color": d["thumb"]["inner_back_color"],
386
+ "inner_back_opacity": d["thumb"]["inner_back_opacity"],
387
+ },
388
+ "track": {
389
+ "back_color": d["track"]["back_color"],
390
+ "back_opacity": d["track"]["back_opacity"],
391
+ "width": d["track"]["width"]
392
+ },
393
+ "rail": {
394
+ "back_color": d["rail"]["back_color"],
395
+ "back_opacity": d["rail"]["back_opacity"],
396
+ }
397
+ }
398
+ )
399
+
400
+ def _light(self):
401
+ self._theme("light")
402
+
403
+ def _dark(self):
404
+ self._theme("dark")
@@ -96,7 +96,7 @@ class FluText(FluTextCanvas, DDrawWidget):
96
96
 
97
97
  super().__init__(*args, width=width, height=height, cursor=cursor, **kwargs)
98
98
 
99
- self.bind("<FocusIn>", self._event_focus_in, add="+")
99
+ self.bind("<Button-1>", lambda e: self.text.focus_set(), add="+")
100
100
 
101
101
  self.dconfigure(
102
102
  state=state,
@@ -191,9 +191,13 @@ class FluText(FluTextCanvas, DDrawWidget):
191
191
  height=self.winfo_height() - _border_width * 2 - _radius
192
192
  )
193
193
 
194
+ #self.tag_raise(self.element_text)
195
+
194
196
  def _event_focus_in(self, event=None):
195
197
  self.isfocus = True
196
198
 
199
+ self.text.focus_set()
200
+
197
201
  self._draw(event)
198
202
 
199
203
  def _event_focus_out(self, event=None):
tkfluent-0.0.6/README.md DELETED
@@ -1,3 +0,0 @@
1
- # tkfluent
2
-
3
- `tkinter`现代化组件库。设计来于`Fluent` `WinUI3` 设计
@@ -1,16 +0,0 @@
1
- def toggle_theme(toggle_button, thememanager):
2
- if toggle_button.dcget('checked'):
3
- thememanager.mode("dark")
4
- else:
5
- thememanager.mode("light")
6
-
7
-
8
- def set_default_font(font, attributes):
9
- if font is None:
10
- from .designs.fonts import SegoeFont
11
- attributes.font = SegoeFont()
12
-
13
-
14
- def orange_primary_color():
15
- from .designs.primary_color import set_primary_color
16
- set_primary_color(("#c53201", "#fe7e34"))
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