Python-FastUI-Widgets 1.0.0__py3-none-any.whl

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 (107) hide show
  1. fastuiwidgets/__init__.py +12 -0
  2. fastuiwidgets/_rc/__init__.py +0 -0
  3. fastuiwidgets/_rc/resource.py +98835 -0
  4. fastuiwidgets/common/__init__.py +12 -0
  5. fastuiwidgets/common/animation.py +530 -0
  6. fastuiwidgets/common/auto_wrap.py +164 -0
  7. fastuiwidgets/common/color.py +95 -0
  8. fastuiwidgets/common/config.py +423 -0
  9. fastuiwidgets/common/exception_handler.py +31 -0
  10. fastuiwidgets/common/font.py +38 -0
  11. fastuiwidgets/common/icon.py +703 -0
  12. fastuiwidgets/common/image_utils.py +198 -0
  13. fastuiwidgets/common/overload.py +47 -0
  14. fastuiwidgets/common/router.py +133 -0
  15. fastuiwidgets/common/screen.py +25 -0
  16. fastuiwidgets/common/smooth_scroll.py +141 -0
  17. fastuiwidgets/common/style_sheet.py +512 -0
  18. fastuiwidgets/common/theme_listener.py +27 -0
  19. fastuiwidgets/common/translator.py +14 -0
  20. fastuiwidgets/components/__init__.py +6 -0
  21. fastuiwidgets/components/date_time/__init__.py +4 -0
  22. fastuiwidgets/components/date_time/calendar_picker.py +121 -0
  23. fastuiwidgets/components/date_time/calendar_view.py +671 -0
  24. fastuiwidgets/components/date_time/date_picker.py +245 -0
  25. fastuiwidgets/components/date_time/fast_calendar_view.py +487 -0
  26. fastuiwidgets/components/date_time/picker_base.py +632 -0
  27. fastuiwidgets/components/date_time/time_picker.py +223 -0
  28. fastuiwidgets/components/dialog_box/__init__.py +6 -0
  29. fastuiwidgets/components/dialog_box/color_dialog.py +414 -0
  30. fastuiwidgets/components/dialog_box/dialog.py +167 -0
  31. fastuiwidgets/components/dialog_box/folder_list_dialog.py +307 -0
  32. fastuiwidgets/components/dialog_box/mask_dialog_base.py +120 -0
  33. fastuiwidgets/components/dialog_box/message_box_base.py +92 -0
  34. fastuiwidgets/components/dialog_box/message_dialog.py +65 -0
  35. fastuiwidgets/components/layout/__init__.py +3 -0
  36. fastuiwidgets/components/layout/expand_layout.py +96 -0
  37. fastuiwidgets/components/layout/flow_layout.py +236 -0
  38. fastuiwidgets/components/layout/v_box_layout.py +41 -0
  39. fastuiwidgets/components/material/__init__.py +6 -0
  40. fastuiwidgets/components/material/acrylic_combo_box.py +96 -0
  41. fastuiwidgets/components/material/acrylic_flyout.py +105 -0
  42. fastuiwidgets/components/material/acrylic_line_edit.py +27 -0
  43. fastuiwidgets/components/material/acrylic_menu.py +204 -0
  44. fastuiwidgets/components/material/acrylic_tool_tip.py +39 -0
  45. fastuiwidgets/components/material/acrylic_widget.py +42 -0
  46. fastuiwidgets/components/navigation/__init__.py +9 -0
  47. fastuiwidgets/components/navigation/breadcrumb.py +350 -0
  48. fastuiwidgets/components/navigation/navigation_bar.py +416 -0
  49. fastuiwidgets/components/navigation/navigation_interface.py +268 -0
  50. fastuiwidgets/components/navigation/navigation_panel.py +657 -0
  51. fastuiwidgets/components/navigation/navigation_widget.py +686 -0
  52. fastuiwidgets/components/navigation/pivot.py +272 -0
  53. fastuiwidgets/components/navigation/segmented_widget.py +174 -0
  54. fastuiwidgets/components/settings/__init__.py +8 -0
  55. fastuiwidgets/components/settings/custom_color_setting_card.py +139 -0
  56. fastuiwidgets/components/settings/expand_setting_card.py +390 -0
  57. fastuiwidgets/components/settings/folder_list_setting_card.py +134 -0
  58. fastuiwidgets/components/settings/options_setting_card.py +86 -0
  59. fastuiwidgets/components/settings/setting_card.py +449 -0
  60. fastuiwidgets/components/settings/setting_card_group.py +48 -0
  61. fastuiwidgets/components/widgets/__init__.py +41 -0
  62. fastuiwidgets/components/widgets/acrylic_label.py +261 -0
  63. fastuiwidgets/components/widgets/button.py +1059 -0
  64. fastuiwidgets/components/widgets/card_widget.py +369 -0
  65. fastuiwidgets/components/widgets/check_box.py +203 -0
  66. fastuiwidgets/components/widgets/combo_box.py +556 -0
  67. fastuiwidgets/components/widgets/command_bar.py +636 -0
  68. fastuiwidgets/components/widgets/cycle_list_widget.py +251 -0
  69. fastuiwidgets/components/widgets/flip_view.py +430 -0
  70. fastuiwidgets/components/widgets/flyout.py +521 -0
  71. fastuiwidgets/components/widgets/frameless_window.py +49 -0
  72. fastuiwidgets/components/widgets/icon_widget.py +53 -0
  73. fastuiwidgets/components/widgets/info_badge.py +483 -0
  74. fastuiwidgets/components/widgets/info_bar.py +596 -0
  75. fastuiwidgets/components/widgets/label.py +553 -0
  76. fastuiwidgets/components/widgets/line_edit.py +551 -0
  77. fastuiwidgets/components/widgets/list_view.py +158 -0
  78. fastuiwidgets/components/widgets/menu.py +1318 -0
  79. fastuiwidgets/components/widgets/pips_pager.py +331 -0
  80. fastuiwidgets/components/widgets/progress_bar.py +311 -0
  81. fastuiwidgets/components/widgets/progress_ring.py +212 -0
  82. fastuiwidgets/components/widgets/scroll_area.py +125 -0
  83. fastuiwidgets/components/widgets/scroll_bar.py +673 -0
  84. fastuiwidgets/components/widgets/separator.py +43 -0
  85. fastuiwidgets/components/widgets/slider.py +307 -0
  86. fastuiwidgets/components/widgets/spin_box.py +306 -0
  87. fastuiwidgets/components/widgets/stacked_widget.py +211 -0
  88. fastuiwidgets/components/widgets/state_tool_tip.py +188 -0
  89. fastuiwidgets/components/widgets/switch_button.py +312 -0
  90. fastuiwidgets/components/widgets/tab_view.py +804 -0
  91. fastuiwidgets/components/widgets/table_view.py +360 -0
  92. fastuiwidgets/components/widgets/teaching_tip.py +657 -0
  93. fastuiwidgets/components/widgets/tool_tip.py +460 -0
  94. fastuiwidgets/components/widgets/tree_view.py +216 -0
  95. fastuiwidgets/multimedia/__init__.py +3 -0
  96. fastuiwidgets/multimedia/media_play_bar.py +319 -0
  97. fastuiwidgets/multimedia/media_player.py +124 -0
  98. fastuiwidgets/multimedia/video_widget.py +93 -0
  99. fastuiwidgets/window/__init__.py +2 -0
  100. fastuiwidgets/window/fluent_window.py +413 -0
  101. fastuiwidgets/window/splash_screen.py +92 -0
  102. fastuiwidgets/window/stacked_widget.py +66 -0
  103. python_fastui_widgets-1.0.0.dist-info/METADATA +30 -0
  104. python_fastui_widgets-1.0.0.dist-info/RECORD +107 -0
  105. python_fastui_widgets-1.0.0.dist-info/WHEEL +5 -0
  106. python_fastui_widgets-1.0.0.dist-info/licenses/LICENSE +674 -0
  107. python_fastui_widgets-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,95 @@
1
+ # coding: utf-8
2
+ from enum import Enum
3
+
4
+ from PySide6.QtGui import QColor
5
+
6
+ from .style_sheet import themeColor, Theme, isDarkTheme
7
+ from .config import isDarkThemeMode
8
+
9
+
10
+ class FluentThemeColor(Enum):
11
+ """ Fluent theme color
12
+
13
+ Refer to: https://www.figma.com/file/iM7EPX8Jn37zjeSezb43cF
14
+ """
15
+ YELLOW_GOLD = "#FFB900"
16
+ GOLD = "#FF8C00"
17
+ ORANGE_BRIGHT = "#F7630C"
18
+ ORANGE_DARK = "#CA5010"
19
+ RUST = "#DA3B01"
20
+ PALE_RUST = "#EF6950"
21
+ BRICK_RED = "#D13438"
22
+ MOD_RED = "#FF4343"
23
+ PALE_RED = "#E74856"
24
+ RED = "#E81123"
25
+ ROSE_BRIGHT = "#EA005E"
26
+ ROSE = "#C30052"
27
+ PLUM_LIGHT = "#E3008C"
28
+ PLUM = "#BF0077"
29
+ ORCHID_LIGHT = "#BF0077"
30
+ ORCHID = "#9A0089"
31
+ DEFAULT_BLUE = "#0078D7"
32
+ NAVY_BLUE = "#0063B1"
33
+ PURPLE_SHADOW = "#8E8CD8"
34
+ PURPLE_SHADOW_DARK = "#6B69D6"
35
+ IRIS_PASTEL = "#8764B8"
36
+ IRIS_SPRING = "#744DA9"
37
+ VIOLET_RED_LIGHT = "#B146C2"
38
+ VIOLET_RED = "#881798"
39
+ COOL_BLUE_BRIGHT = "#0099BC"
40
+ COOL_BLUR = "#2D7D9A"
41
+ SEAFOAM = "#00B7C3"
42
+ SEAFOAM_TEAL = "#038387"
43
+ MINT_LIGHT = "#00B294"
44
+ MINT_DARK = "#018574"
45
+ TURF_GREEN = "#00CC6A"
46
+ SPORT_GREEN = "#10893E"
47
+ GRAY = "#7A7574"
48
+ GRAY_BROWN = "#5D5A58"
49
+ STEAL_BLUE = "#68768A"
50
+ METAL_BLUE = "#515C6B"
51
+ PALE_MOSS = "#567C73"
52
+ MOSS = "#486860"
53
+ MEADOW_GREEN = "#498205"
54
+ GREEN = "#107C10"
55
+ OVERCAST = "#767676"
56
+ STORM = "#4C4A48"
57
+ BLUE_GRAY = "#69797E"
58
+ GRAY_DARK = "#4A5459"
59
+ LIDDY_GREEN = "#647C64"
60
+ SAGE = "#525E54"
61
+ CAMOUFLAGE_DESERT = "#847545"
62
+ CAMOUFLAGE = "#7E735F"
63
+
64
+ def color(self):
65
+ return QColor(self.value)
66
+
67
+
68
+
69
+ class FluentSystemColor(Enum):
70
+
71
+ SUCCESS_FOREGROUND = ("#0f7b0f", "#6ccb5f")
72
+ CAUTION_FOREGROUND = ("#9d5d00", "#fce100")
73
+ CRITICAL_FOREGROUND = ("#c42b1c", "#ff99a4")
74
+
75
+ SUCCESS_BACKGROUND = ("#dff6dd", "#393d1b")
76
+ CAUTION_BACKGROUND = ("#fff4ce", "#433519")
77
+ CRITICAL_BACKGROUND = ("#fde7e9", "#442726")
78
+
79
+ def color(self, theme=Theme.AUTO) -> QColor:
80
+ color = self.value[1] if isDarkThemeMode(theme) else self.value[0]
81
+ return QColor(color)
82
+
83
+
84
+
85
+ def validColor(color: QColor, default: QColor) -> QColor:
86
+ return color if color.isValid() else default
87
+
88
+
89
+ def fallbackThemeColor(color: QColor):
90
+ return color if color.isValid() else themeColor()
91
+
92
+
93
+ def autoFallbackThemeColor(light: QColor, dark: QColor):
94
+ color = dark if isDarkTheme() else light
95
+ return fallbackThemeColor(color)
@@ -0,0 +1,423 @@
1
+ # coding:utf-8
2
+ import json
3
+ from copy import deepcopy
4
+ from enum import Enum
5
+ from pathlib import Path
6
+ from typing import List
7
+
8
+ import darkdetect
9
+ from PySide6.QtCore import QObject, Signal
10
+ from PySide6.QtGui import QColor
11
+
12
+ from .exception_handler import exceptionHandler
13
+
14
+
15
+ ALERT = "\n\033[1;33m📢 Tips:\033[0m QFluentWidgets Pro is now released. Click \033[1;96mhttps://fastuiwidgets.com/pages/pro\033[0m to learn more about it.\n"
16
+
17
+
18
+ class Theme(Enum):
19
+ """ Theme enumeration """
20
+
21
+ LIGHT = "Light"
22
+ DARK = "Dark"
23
+ AUTO = "Auto"
24
+
25
+
26
+ class ConfigValidator:
27
+ """ Config validator """
28
+
29
+ def validate(self, value):
30
+ """ Verify whether the value is legal """
31
+ return True
32
+
33
+ def correct(self, value):
34
+ """ correct illegal value """
35
+ return value
36
+
37
+
38
+ class RangeValidator(ConfigValidator):
39
+ """ Range validator """
40
+
41
+ def __init__(self, min, max):
42
+ self.min = min
43
+ self.max = max
44
+ self.range = (min, max)
45
+
46
+ def validate(self, value):
47
+ return self.min <= value <= self.max
48
+
49
+ def correct(self, value):
50
+ return min(max(self.min, value), self.max)
51
+
52
+
53
+ class OptionsValidator(ConfigValidator):
54
+ """ Options validator """
55
+
56
+ def __init__(self, options):
57
+ if not options:
58
+ raise ValueError("The `options` can't be empty.")
59
+
60
+ if isinstance(options, Enum):
61
+ options = options._member_map_.values()
62
+
63
+ self.options = list(options)
64
+
65
+ def validate(self, value):
66
+ return value in self.options
67
+
68
+ def correct(self, value):
69
+ return value if self.validate(value) else self.options[0]
70
+
71
+
72
+ class BoolValidator(OptionsValidator):
73
+ """ Boolean validator """
74
+
75
+ def __init__(self):
76
+ super().__init__([True, False])
77
+
78
+
79
+ class FolderValidator(ConfigValidator):
80
+ """ Folder validator """
81
+
82
+ def validate(self, value):
83
+ return Path(value).exists()
84
+
85
+ def correct(self, value):
86
+ path = Path(value)
87
+ path.mkdir(exist_ok=True, parents=True)
88
+ return str(path.absolute()).replace("\\", "/")
89
+
90
+
91
+ class FolderListValidator(ConfigValidator):
92
+ """ Folder list validator """
93
+
94
+ def validate(self, value):
95
+ return all(Path(i).exists() for i in value)
96
+
97
+ def correct(self, value: List[str]):
98
+ folders = []
99
+ for folder in value:
100
+ path = Path(folder)
101
+ if path.exists():
102
+ folders.append(str(path.absolute()).replace("\\", "/"))
103
+
104
+ return folders
105
+
106
+
107
+ class ColorValidator(ConfigValidator):
108
+ """ RGB color validator """
109
+
110
+ def __init__(self, default):
111
+ self.default = QColor(default)
112
+
113
+ def validate(self, color):
114
+ try:
115
+ return QColor(color).isValid()
116
+ except:
117
+ return False
118
+
119
+ def correct(self, value):
120
+ return QColor(value) if self.validate(value) else self.default
121
+
122
+
123
+ class ConfigSerializer:
124
+ """ Config serializer """
125
+
126
+ def serialize(self, value):
127
+ """ serialize config value """
128
+ return value
129
+
130
+ def deserialize(self, value):
131
+ """ deserialize config from config file's value """
132
+ return value
133
+
134
+
135
+ class EnumSerializer(ConfigSerializer):
136
+ """ enumeration class serializer """
137
+
138
+ def __init__(self, enumClass):
139
+ self.enumClass = enumClass
140
+
141
+ def serialize(self, value):
142
+ return value.value
143
+
144
+ def deserialize(self, value):
145
+ return self.enumClass(value)
146
+
147
+
148
+ class ColorSerializer(ConfigSerializer):
149
+ """ QColor serializer """
150
+
151
+ def serialize(self, value: QColor):
152
+ return value.name(QColor.HexArgb)
153
+
154
+ def deserialize(self, value):
155
+ if isinstance(value, list):
156
+ return QColor(*value)
157
+
158
+ return QColor(value)
159
+
160
+
161
+ class ConfigItem(QObject):
162
+ """ Config item """
163
+
164
+ valueChanged = Signal(object)
165
+
166
+ def __init__(self, group, name, default, validator=None, serializer=None, restart=False):
167
+ """
168
+ Parameters
169
+ ----------
170
+ group: str
171
+ config group name
172
+
173
+ name: str
174
+ config item name, can be empty
175
+
176
+ default:
177
+ default value
178
+
179
+ options: list
180
+ options value
181
+
182
+ serializer: ConfigSerializer
183
+ config serializer
184
+
185
+ restart: bool
186
+ whether to restart the application after updating value
187
+ """
188
+ super().__init__()
189
+ self.group = group
190
+ self.name = name
191
+ self.validator = validator or ConfigValidator()
192
+ self.serializer = serializer or ConfigSerializer()
193
+ self.__value = default
194
+ self.value = default
195
+ self.restart = restart
196
+ self.defaultValue = self.validator.correct(default)
197
+
198
+ @property
199
+ def value(self):
200
+ """ get the value of config item """
201
+ return self.__value
202
+
203
+ @value.setter
204
+ def value(self, v):
205
+ v = self.validator.correct(v)
206
+ ov = self.__value
207
+ self.__value = v
208
+ if ov != v:
209
+ self.valueChanged.emit(v)
210
+
211
+ @property
212
+ def key(self):
213
+ """ get the config key separated by `.` """
214
+ return self.group+"."+self.name if self.name else self.group
215
+
216
+ def __str__(self):
217
+ return f'{self.__class__.__name__}[value={self.value}]'
218
+
219
+ def serialize(self):
220
+ return self.serializer.serialize(self.value)
221
+
222
+ def deserializeFrom(self, value):
223
+ self.value = self.serializer.deserialize(value)
224
+
225
+
226
+ class RangeConfigItem(ConfigItem):
227
+ """ Config item of range """
228
+
229
+ @property
230
+ def range(self):
231
+ """ get the available range of config """
232
+ return self.validator.range
233
+
234
+ def __str__(self):
235
+ return f'{self.__class__.__name__}[range={self.range}, value={self.value}]'
236
+
237
+
238
+ class OptionsConfigItem(ConfigItem):
239
+ """ Config item with options """
240
+
241
+ @property
242
+ def options(self):
243
+ return self.validator.options
244
+
245
+ def __str__(self):
246
+ return f'{self.__class__.__name__}[options={self.options}, value={self.value}]'
247
+
248
+
249
+ class ColorConfigItem(ConfigItem):
250
+ """ Color config item """
251
+
252
+ def __init__(self, group, name, default, restart=False):
253
+ super().__init__(group, name, QColor(default), ColorValidator(default),
254
+ ColorSerializer(), restart)
255
+
256
+ def __str__(self):
257
+ return f'{self.__class__.__name__}[value={self.value.name()}]'
258
+
259
+
260
+ class QConfig(QObject):
261
+ """ Config of app """
262
+
263
+ appRestartSig = Signal()
264
+ themeChanged = Signal(Theme)
265
+ themeChangedFinished = Signal()
266
+ themeColorChanged = Signal(QColor)
267
+
268
+ themeMode = OptionsConfigItem(
269
+ "QFluentWidgets", "ThemeMode", Theme.LIGHT, OptionsValidator(Theme), EnumSerializer(Theme))
270
+ themeColor = ColorConfigItem("QFluentWidgets", "ThemeColor", '#009faa')
271
+
272
+ def __init__(self):
273
+ super().__init__()
274
+ self.file = Path("config/config.json")
275
+ self._theme = Theme.LIGHT
276
+ self._cfg = self
277
+
278
+ def get(self, item):
279
+ """ get the value of config item """
280
+ return item.value
281
+
282
+ def set(self, item, value, save=True, copy=True):
283
+ """ set the value of config item
284
+
285
+ Parameters
286
+ ----------
287
+ item: ConfigItem
288
+ config item
289
+
290
+ value:
291
+ the new value of config item
292
+
293
+ save: bool
294
+ whether to save the change to config file
295
+
296
+ copy: bool
297
+ whether to deep copy the new value
298
+ """
299
+ if item.value == value:
300
+ return
301
+
302
+ # deepcopy new value
303
+ try:
304
+ item.value = deepcopy(value) if copy else value
305
+ except:
306
+ item.value = value
307
+
308
+ if save:
309
+ self.save()
310
+
311
+ if item.restart:
312
+ self._cfg.appRestartSig.emit()
313
+
314
+ if item is self._cfg.themeMode:
315
+ self.theme = value
316
+ self._cfg.themeChanged.emit(value)
317
+
318
+ if item is self._cfg.themeColor:
319
+ self._cfg.themeColorChanged.emit(value)
320
+
321
+ def toDict(self, serialize=True):
322
+ """ convert config items to `dict` """
323
+ items = {}
324
+ for name in dir(self._cfg.__class__):
325
+ item = getattr(self._cfg.__class__, name)
326
+ if not isinstance(item, ConfigItem):
327
+ continue
328
+
329
+ value = item.serialize() if serialize else item.value
330
+ if not items.get(item.group):
331
+ if not item.name:
332
+ items[item.group] = value
333
+ else:
334
+ items[item.group] = {}
335
+
336
+ if item.name:
337
+ items[item.group][item.name] = value
338
+
339
+ return items
340
+
341
+ def save(self):
342
+ """ save config """
343
+ self._cfg.file.parent.mkdir(parents=True, exist_ok=True)
344
+ with open(self._cfg.file, "w", encoding="utf-8") as f:
345
+ json.dump(self._cfg.toDict(), f, ensure_ascii=False, indent=4)
346
+
347
+ @exceptionHandler()
348
+ def load(self, file=None, config=None):
349
+ """ load config
350
+
351
+ Parameters
352
+ ----------
353
+ file: str or Path
354
+ the path of json config file
355
+
356
+ config: Config
357
+ config object to be initialized
358
+ """
359
+ if isinstance(config, QConfig):
360
+ self._cfg = config
361
+ self._cfg.themeChanged.connect(self.themeChanged)
362
+
363
+ if isinstance(file, (str, Path)):
364
+ self._cfg.file = Path(file)
365
+
366
+ try:
367
+ with open(self._cfg.file, encoding="utf-8") as f:
368
+ cfg = json.load(f)
369
+ except:
370
+ cfg = {}
371
+
372
+ # map config items'key to item
373
+ items = {}
374
+ for name in dir(self._cfg.__class__):
375
+ item = getattr(self._cfg.__class__, name)
376
+ if isinstance(item, ConfigItem):
377
+ items[item.key] = item
378
+
379
+ # update the value of config item
380
+ for k, v in cfg.items():
381
+ if not isinstance(v, dict) and items.get(k) is not None:
382
+ items[k].deserializeFrom(v)
383
+ elif isinstance(v, dict):
384
+ for key, value in v.items():
385
+ key = k + "." + key
386
+ if items.get(key) is not None:
387
+ items[key].deserializeFrom(value)
388
+
389
+ self.theme = self.get(self._cfg.themeMode)
390
+
391
+ @property
392
+ def theme(self):
393
+ """ get theme mode, can be `Theme.Light` or `Theme.Dark` """
394
+ return self._cfg._theme
395
+
396
+ @theme.setter
397
+ def theme(self, t):
398
+ """ chaneg the theme without modifying the config file """
399
+ if t == Theme.AUTO:
400
+ t = darkdetect.theme()
401
+ t = Theme(t) if t else Theme.LIGHT
402
+
403
+ self._cfg._theme = t
404
+
405
+
406
+ qconfig = QConfig()
407
+ try:
408
+ print(ALERT)
409
+ except UnicodeEncodeError:
410
+ print(ALERT.replace("📢", ""))
411
+
412
+
413
+ def isDarkTheme():
414
+ """ whether the theme is dark mode """
415
+ return qconfig.theme == Theme.DARK
416
+
417
+ def theme():
418
+ """ get theme mode """
419
+ return qconfig.theme
420
+
421
+ def isDarkThemeMode(theme=Theme.AUTO):
422
+ """ whether the theme is dark mode """
423
+ return theme == Theme.DARK if theme != Theme.AUTO else isDarkTheme()
@@ -0,0 +1,31 @@
1
+ # coding:utf-8
2
+ from copy import deepcopy
3
+
4
+
5
+
6
+ def exceptionHandler(*default):
7
+ """ decorator for exception handling
8
+
9
+ Parameters
10
+ ----------
11
+ *default:
12
+ the default value returned when an exception occurs
13
+ """
14
+
15
+ def outer(func):
16
+
17
+ def inner(*args, **kwargs):
18
+ try:
19
+ return func(*args, **kwargs)
20
+ except BaseException as e:
21
+ value = deepcopy(default)
22
+ if len(value) == 0:
23
+ return None
24
+ elif len(value) == 1:
25
+ return value[0]
26
+
27
+ return value
28
+
29
+ return inner
30
+
31
+ return outer
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ from PySide6.QtGui import QFont
3
+ from PySide6.QtWidgets import QWidget
4
+
5
+
6
+ def setFont(widget: QWidget, fontSize=14, weight=QFont.Normal):
7
+ """ set the font of widget
8
+
9
+ Parameters
10
+ ----------
11
+ widget: QWidget
12
+ the widget to set font
13
+
14
+ fontSize: int
15
+ font pixel size
16
+
17
+ weight: `QFont.Weight`
18
+ font weight
19
+ """
20
+ widget.setFont(getFont(fontSize, weight))
21
+
22
+
23
+ def getFont(fontSize=14, weight=QFont.Normal):
24
+ """ create font
25
+
26
+ Parameters
27
+ ----------
28
+ fontSize: int
29
+ font pixel size
30
+
31
+ weight: `QFont.Weight`
32
+ font weight
33
+ """
34
+ font = QFont()
35
+ font.setFamilies(['Segoe UI', 'Microsoft YaHei', 'PingFang SC'])
36
+ font.setPixelSize(fontSize)
37
+ font.setWeight(weight)
38
+ return font