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,413 @@
1
+ # coding:utf-8
2
+ from typing import Union
3
+ import sys
4
+
5
+ from PySide6.QtCore import Qt, QSize, QRect
6
+ from PySide6.QtGui import QIcon, QPainter, QColor
7
+ from PySide6.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QLabel, QApplication
8
+
9
+ from ..common.config import qconfig
10
+ from ..common.icon import FluentIconBase
11
+ from ..common.router import qrouter
12
+ from ..common.style_sheet import FluentStyleSheet, isDarkTheme, setTheme, Theme
13
+ from ..common.animation import BackgroundAnimationWidget
14
+ from ..components.widgets.frameless_window import FramelessWindow
15
+ from ..components.navigation import (NavigationInterface, NavigationBar, NavigationItemPosition,
16
+ NavigationBarPushButton, NavigationTreeWidget)
17
+ from .stacked_widget import StackedWidget
18
+
19
+ from fframelesswindow import TitleBar, TitleBarBase
20
+
21
+
22
+ class FluentWindowBase(BackgroundAnimationWidget, FramelessWindow):
23
+ """ Fluent window base class """
24
+
25
+ def __init__(self, parent=None):
26
+ self._isMicaEnabled = False
27
+ self._lightBackgroundColor = QColor(240, 244, 249)
28
+ self._darkBackgroundColor = QColor(32, 32, 32)
29
+ super().__init__(parent=parent)
30
+
31
+ self.hBoxLayout = QHBoxLayout(self)
32
+ self.stackedWidget = StackedWidget(self)
33
+ self.navigationInterface = None
34
+
35
+ # initialize layout
36
+ self.hBoxLayout.setSpacing(0)
37
+ self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
38
+
39
+ FluentStyleSheet.FLUENT_WINDOW.apply(self.stackedWidget)
40
+
41
+ # enable mica effect on win11
42
+ self.setMicaEffectEnabled(True)
43
+
44
+ # show system title bar buttons on macOS
45
+ if sys.platform == "darwin":
46
+ self.setSystemTitleBarButtonVisible(True)
47
+
48
+ qconfig.themeChangedFinished.connect(self._onThemeChangedFinished)
49
+
50
+ def addSubInterface(self, interface: QWidget, icon: Union[FluentIconBase, QIcon, str], text: str,
51
+ position=NavigationItemPosition.TOP):
52
+ """ add sub interface """
53
+ raise NotImplementedError
54
+
55
+ def removeInterface(self, interface: QWidget, isDelete=False):
56
+ """ remove sub interface
57
+
58
+ Parameters
59
+ ----------
60
+ interface: QWidget
61
+ sub interface to be removed
62
+
63
+ isDelete: bool
64
+ whether to delete the sub interface
65
+ """
66
+ raise NotImplementedError
67
+
68
+ def switchTo(self, interface: QWidget):
69
+ self.stackedWidget.setCurrentWidget(interface, popOut=False)
70
+
71
+ def _onCurrentInterfaceChanged(self, index: int):
72
+ widget = self.stackedWidget.widget(index)
73
+ self.navigationInterface.setCurrentItem(widget.objectName())
74
+ qrouter.push(self.stackedWidget, widget.objectName())
75
+
76
+ self._updateStackedBackground()
77
+
78
+ def _updateStackedBackground(self):
79
+ isTransparent = self.stackedWidget.currentWidget().property("isStackedTransparent")
80
+ if bool(self.stackedWidget.property("isTransparent")) == isTransparent:
81
+ return
82
+
83
+ self.stackedWidget.setProperty("isTransparent", isTransparent)
84
+ self.stackedWidget.setStyle(QApplication.style())
85
+
86
+ def setCustomBackgroundColor(self, light, dark):
87
+ """ set custom background color
88
+
89
+ Parameters
90
+ ----------
91
+ light, dark: QColor | Qt.GlobalColor | str
92
+ background color in light/dark theme mode
93
+ """
94
+ self._lightBackgroundColor = QColor(light)
95
+ self._darkBackgroundColor = QColor(dark)
96
+ self._updateBackgroundColor()
97
+
98
+ def _normalBackgroundColor(self):
99
+ if not self.isMicaEffectEnabled():
100
+ return self._darkBackgroundColor if isDarkTheme() else self._lightBackgroundColor
101
+
102
+ return QColor(0, 0, 0, 0)
103
+
104
+ def _onThemeChangedFinished(self):
105
+ if self.isMicaEffectEnabled():
106
+ self.windowEffect.setMicaEffect(self.winId(), isDarkTheme())
107
+
108
+ def paintEvent(self, e):
109
+ super().paintEvent(e)
110
+ painter = QPainter(self)
111
+ painter.setPen(Qt.NoPen)
112
+ painter.setBrush(self.backgroundColor)
113
+ painter.drawRect(self.rect())
114
+
115
+ def setMicaEffectEnabled(self, isEnabled: bool):
116
+ """ set whether the mica effect is enabled, only available on Win11 """
117
+ if sys.platform != 'win32' or sys.getwindowsversion().build < 22000:
118
+ return
119
+
120
+ self._isMicaEnabled = isEnabled
121
+
122
+ if isEnabled:
123
+ self.windowEffect.setMicaEffect(self.winId(), isDarkTheme())
124
+ else:
125
+ self.windowEffect.removeBackgroundEffect(self.winId())
126
+
127
+ self.setBackgroundColor(self._normalBackgroundColor())
128
+
129
+ def isMicaEffectEnabled(self):
130
+ return self._isMicaEnabled
131
+
132
+ def systemTitleBarRect(self, size: QSize) -> QRect:
133
+ """ Returns the system title bar rect, only works for macOS
134
+
135
+ Parameters
136
+ ----------
137
+ size: QSize
138
+ original system title bar rect
139
+ """
140
+ return QRect(size.width() - 75, 0 if self.isFullScreen() else 9, 75, size.height())
141
+
142
+ def setTitleBar(self, titleBar):
143
+ super().setTitleBar(titleBar)
144
+
145
+ # hide title bar buttons on macOS
146
+ if sys.platform == "darwin" and self.isSystemButtonVisible() and isinstance(titleBar, TitleBarBase):
147
+ titleBar.minBtn.hide()
148
+ titleBar.maxBtn.hide()
149
+ titleBar.closeBtn.hide()
150
+
151
+
152
+ class FluentTitleBar(TitleBar):
153
+ """ Fluent title bar"""
154
+
155
+ def __init__(self, parent):
156
+ super().__init__(parent)
157
+ self.setFixedHeight(48)
158
+ self.hBoxLayout.removeWidget(self.minBtn)
159
+ self.hBoxLayout.removeWidget(self.maxBtn)
160
+ self.hBoxLayout.removeWidget(self.closeBtn)
161
+
162
+ # add window icon
163
+ self.iconLabel = QLabel(self)
164
+ self.iconLabel.setFixedSize(18, 18)
165
+ self.hBoxLayout.insertWidget(0, self.iconLabel, 0, Qt.AlignLeft | Qt.AlignVCenter)
166
+ self.window().windowIconChanged.connect(self.setIcon)
167
+
168
+ # add title label
169
+ self.titleLabel = QLabel(self)
170
+ self.hBoxLayout.insertWidget(1, self.titleLabel, 0, Qt.AlignLeft | Qt.AlignVCenter)
171
+ self.titleLabel.setObjectName('titleLabel')
172
+ self.window().windowTitleChanged.connect(self.setTitle)
173
+
174
+ self.vBoxLayout = QVBoxLayout()
175
+ self.buttonLayout = QHBoxLayout()
176
+ self.buttonLayout.setSpacing(0)
177
+ self.buttonLayout.setContentsMargins(0, 0, 0, 0)
178
+ self.buttonLayout.setAlignment(Qt.AlignTop)
179
+ self.buttonLayout.addWidget(self.minBtn)
180
+ self.buttonLayout.addWidget(self.maxBtn)
181
+ self.buttonLayout.addWidget(self.closeBtn)
182
+ self.vBoxLayout.addLayout(self.buttonLayout)
183
+ self.vBoxLayout.addStretch(1)
184
+ self.hBoxLayout.addLayout(self.vBoxLayout, 0)
185
+
186
+ FluentStyleSheet.FLUENT_WINDOW.apply(self)
187
+
188
+ def setTitle(self, title):
189
+ self.titleLabel.setText(title)
190
+ self.titleLabel.adjustSize()
191
+
192
+ def setIcon(self, icon):
193
+ self.iconLabel.setPixmap(QIcon(icon).pixmap(18, 18))
194
+
195
+
196
+ class FluentWindow(FluentWindowBase):
197
+ """ Fluent window """
198
+
199
+ def __init__(self, parent=None):
200
+ super().__init__(parent)
201
+ self.setTitleBar(FluentTitleBar(self))
202
+
203
+ self.navigationInterface = NavigationInterface(self, showReturnButton=True)
204
+ self.widgetLayout = QHBoxLayout()
205
+
206
+ # initialize layout
207
+ self.hBoxLayout.addWidget(self.navigationInterface)
208
+ self.hBoxLayout.addLayout(self.widgetLayout)
209
+ self.hBoxLayout.setStretchFactor(self.widgetLayout, 1)
210
+
211
+ self.widgetLayout.addWidget(self.stackedWidget)
212
+ self.widgetLayout.setContentsMargins(0, 48, 0, 0)
213
+
214
+ self.navigationInterface.displayModeChanged.connect(self.titleBar.raise_)
215
+ self.titleBar.raise_()
216
+
217
+ def addSubInterface(self, interface: QWidget, icon: Union[FluentIconBase, QIcon, str], text: str,
218
+ position=NavigationItemPosition.TOP, parent=None, isTransparent=False) -> NavigationTreeWidget:
219
+ """ add sub interface, the object name of `interface` should be set already
220
+ before calling this method
221
+
222
+ Parameters
223
+ ----------
224
+ interface: QWidget
225
+ the subinterface to be added
226
+
227
+ icon: FluentIconBase | QIcon | str
228
+ the icon of navigation item
229
+
230
+ text: str
231
+ the text of navigation item
232
+
233
+ position: NavigationItemPosition
234
+ the position of navigation item
235
+
236
+ parent: QWidget
237
+ the parent of navigation item
238
+
239
+ isTransparent: bool
240
+ whether to use transparent background
241
+ """
242
+ if not interface.objectName():
243
+ raise ValueError("The object name of `interface` can't be empty string.")
244
+ if parent and not parent.objectName():
245
+ raise ValueError("The object name of `parent` can't be empty string.")
246
+
247
+ interface.setProperty("isStackedTransparent", isTransparent)
248
+ self.stackedWidget.addWidget(interface)
249
+
250
+ # add navigation item
251
+ routeKey = interface.objectName()
252
+ item = self.navigationInterface.addItem(
253
+ routeKey=routeKey,
254
+ icon=icon,
255
+ text=text,
256
+ onClick=lambda: self.switchTo(interface),
257
+ position=position,
258
+ tooltip=text,
259
+ parentRouteKey=parent.objectName() if parent else None
260
+ )
261
+
262
+ # initialize selected item
263
+ if self.stackedWidget.count() == 1:
264
+ self.stackedWidget.currentChanged.connect(self._onCurrentInterfaceChanged)
265
+ self.navigationInterface.setCurrentItem(routeKey)
266
+ qrouter.setDefaultRouteKey(self.stackedWidget, routeKey)
267
+
268
+ self._updateStackedBackground()
269
+
270
+ return item
271
+
272
+ def removeInterface(self, interface, isDelete=False):
273
+ self.navigationInterface.removeWidget(interface.objectName())
274
+ self.stackedWidget.removeWidget(interface)
275
+ interface.hide()
276
+
277
+ if isDelete:
278
+ interface.deleteLater()
279
+
280
+ def resizeEvent(self, e):
281
+ self.titleBar.move(46, 0)
282
+ self.titleBar.resize(self.width()-46, self.titleBar.height())
283
+
284
+
285
+ class MSFluentTitleBar(FluentTitleBar):
286
+
287
+ def __init__(self, parent):
288
+ super().__init__(parent)
289
+ self.hBoxLayout.insertSpacing(0, 20)
290
+ self.hBoxLayout.insertSpacing(2, 2)
291
+
292
+
293
+ class MSFluentWindow(FluentWindowBase):
294
+ """ Fluent window in Microsoft Store style """
295
+
296
+ def __init__(self, parent=None):
297
+ super().__init__(parent)
298
+ self.setTitleBar(MSFluentTitleBar(self))
299
+
300
+ self.navigationInterface = NavigationBar(self)
301
+
302
+ # initialize layout
303
+ self.hBoxLayout.setContentsMargins(0, 48, 0, 0)
304
+ self.hBoxLayout.addWidget(self.navigationInterface)
305
+ self.hBoxLayout.addWidget(self.stackedWidget, 1)
306
+
307
+ self.titleBar.raise_()
308
+ self.titleBar.setAttribute(Qt.WA_StyledBackground)
309
+
310
+ def addSubInterface(self, interface: QWidget, icon: Union[FluentIconBase, QIcon, str], text: str,
311
+ selectedIcon=None, position=NavigationItemPosition.TOP, isTransparent=False) -> NavigationBarPushButton:
312
+ """ add sub interface, the object name of `interface` should be set already
313
+ before calling this method
314
+
315
+ Parameters
316
+ ----------
317
+ interface: QWidget
318
+ the subinterface to be added
319
+
320
+ icon: FluentIconBase | QIcon | str
321
+ the icon of navigation item
322
+
323
+ text: str
324
+ the text of navigation item
325
+
326
+ selectedIcon: str | QIcon | FluentIconBase
327
+ the icon of navigation item in selected state
328
+
329
+ position: NavigationItemPosition
330
+ the position of navigation item
331
+ """
332
+ if not interface.objectName():
333
+ raise ValueError("The object name of `interface` can't be empty string.")
334
+
335
+ interface.setProperty("isStackedTransparent", isTransparent)
336
+ self.stackedWidget.addWidget(interface)
337
+
338
+ # add navigation item
339
+ routeKey = interface.objectName()
340
+ item = self.navigationInterface.addItem(
341
+ routeKey=routeKey,
342
+ icon=icon,
343
+ text=text,
344
+ onClick=lambda: self.switchTo(interface),
345
+ selectedIcon=selectedIcon,
346
+ position=position
347
+ )
348
+
349
+ if self.stackedWidget.count() == 1:
350
+ self.stackedWidget.currentChanged.connect(self._onCurrentInterfaceChanged)
351
+ self.navigationInterface.setCurrentItem(routeKey)
352
+ qrouter.setDefaultRouteKey(self.stackedWidget, routeKey)
353
+
354
+ self._updateStackedBackground()
355
+
356
+ return item
357
+
358
+ def removeInterface(self, interface, isDelete=False):
359
+ self.navigationInterface.removeWidget(interface.objectName())
360
+ self.stackedWidget.removeWidget(interface)
361
+ interface.hide()
362
+
363
+ if isDelete:
364
+ interface.deleteLater()
365
+
366
+
367
+ class SplitTitleBar(TitleBar):
368
+
369
+ def __init__(self, parent):
370
+ super().__init__(parent)
371
+ # add window icon
372
+ self.iconLabel = QLabel(self)
373
+ self.iconLabel.setFixedSize(18, 18)
374
+ self.hBoxLayout.insertSpacing(0, 12)
375
+ self.hBoxLayout.insertWidget(1, self.iconLabel, 0, Qt.AlignLeft | Qt.AlignBottom)
376
+ self.window().windowIconChanged.connect(self.setIcon)
377
+
378
+ # add title label
379
+ self.titleLabel = QLabel(self)
380
+ self.hBoxLayout.insertWidget(2, self.titleLabel, 0, Qt.AlignLeft | Qt.AlignBottom)
381
+ self.titleLabel.setObjectName('titleLabel')
382
+ self.window().windowTitleChanged.connect(self.setTitle)
383
+
384
+ FluentStyleSheet.FLUENT_WINDOW.apply(self)
385
+
386
+ def setTitle(self, title):
387
+ self.titleLabel.setText(title)
388
+ self.titleLabel.adjustSize()
389
+
390
+ def setIcon(self, icon):
391
+ self.iconLabel.setPixmap(QIcon(icon).pixmap(18, 18))
392
+
393
+
394
+ class SplitFluentWindow(FluentWindow):
395
+ """ Fluent window with split style """
396
+
397
+ def __init__(self, parent=None):
398
+ super().__init__(parent)
399
+ self.setTitleBar(SplitTitleBar(self))
400
+
401
+ if sys.platform == "darwin":
402
+ self.titleBar.setFixedHeight(48)
403
+
404
+ self.widgetLayout.setContentsMargins(0, 0, 0, 0)
405
+
406
+ self.titleBar.raise_()
407
+ self.navigationInterface.displayModeChanged.connect(self.titleBar.raise_)
408
+
409
+
410
+ class FluentBackgroundTheme:
411
+ """ Fluent background theme """
412
+ DEFAULT = (QColor(243, 243, 243), QColor(32, 32, 32)) # light, dark
413
+ DEFAULT_BLUE = (QColor(240, 244, 249), QColor(25, 33, 42))
@@ -0,0 +1,92 @@
1
+ # coding:utf-8
2
+ from typing import Union
3
+ import sys
4
+
5
+ from PySide6.QtCore import Qt, QSize, QRectF, QEvent
6
+ from PySide6.QtGui import QPixmap, QPainter, QColor, QIcon
7
+ from PySide6.QtWidgets import QWidget, QVBoxLayout, QGraphicsDropShadowEffect
8
+
9
+ from ..common.icon import FluentIconBase, drawIcon, toQIcon
10
+ from ..common.style_sheet import isDarkTheme, FluentStyleSheet
11
+ from ..components.widgets import IconWidget
12
+ from fframelesswindow import TitleBar
13
+
14
+
15
+
16
+ class SplashScreen(QWidget):
17
+ """ Splash screen """
18
+
19
+ def __init__(self, icon: Union[str, QIcon, FluentIconBase], parent=None, enableShadow=True):
20
+ super().__init__(parent=parent)
21
+ self._icon = icon
22
+ self._iconSize = QSize(96, 96)
23
+
24
+ self.titleBar = TitleBar(self)
25
+ self.iconWidget = IconWidget(icon, self)
26
+ self.shadowEffect = QGraphicsDropShadowEffect(self)
27
+
28
+ self.iconWidget.setFixedSize(self._iconSize)
29
+ self.shadowEffect.setColor(QColor(0, 0, 0, 50))
30
+ self.shadowEffect.setBlurRadius(15)
31
+ self.shadowEffect.setOffset(0, 4)
32
+
33
+ FluentStyleSheet.FLUENT_WINDOW.apply(self.titleBar)
34
+
35
+ if enableShadow:
36
+ self.iconWidget.setGraphicsEffect(self.shadowEffect)
37
+
38
+ if parent:
39
+ parent.installEventFilter(self)
40
+
41
+ if sys.platform == "darwin":
42
+ self.titleBar.hide()
43
+
44
+ def setIcon(self, icon: Union[str, QIcon, FluentIconBase]):
45
+ self._icon = icon
46
+ self.update()
47
+
48
+ def icon(self):
49
+ return toQIcon(self._icon)
50
+
51
+ def setIconSize(self, size: QSize):
52
+ self._iconSize = size
53
+ self.iconWidget.setFixedSize(size)
54
+ self.update()
55
+
56
+ def iconSize(self):
57
+ return self._iconSize
58
+
59
+ def setTitleBar(self, titleBar: QWidget):
60
+ """ set title bar """
61
+ self.titleBar.deleteLater()
62
+ self.titleBar = titleBar
63
+ titleBar.setParent(self)
64
+ titleBar.raise_()
65
+ self.titleBar.resize(self.width(), self.titleBar.height())
66
+
67
+ def eventFilter(self, obj, e: QEvent):
68
+ if obj is self.parent():
69
+ if e.type() == QEvent.Resize:
70
+ self.resize(e.size())
71
+ elif e.type() == QEvent.ChildAdded:
72
+ self.raise_()
73
+
74
+ return super().eventFilter(obj, e)
75
+
76
+ def resizeEvent(self, e):
77
+ iw, ih = self.iconSize().width(), self.iconSize().height()
78
+ self.iconWidget.move(self.width()//2 - iw//2, self.height()//2 - ih//2)
79
+ self.titleBar.resize(self.width(), self.titleBar.height())
80
+
81
+ def finish(self):
82
+ """ close splash screen """
83
+ self.close()
84
+
85
+ def paintEvent(self, e):
86
+ painter = QPainter(self)
87
+ painter.setPen(Qt.NoPen)
88
+
89
+ # draw background
90
+ c = 32 if isDarkTheme() else 255
91
+ painter.setBrush(QColor(c, c, c))
92
+ painter.drawRect(self.rect())
@@ -0,0 +1,66 @@
1
+ # coding:utf-8
2
+ from PySide6.QtCore import Qt, Signal, QEasingCurve
3
+ from PySide6.QtWidgets import QFrame, QHBoxLayout, QAbstractScrollArea
4
+
5
+ from ..components.widgets.stacked_widget import PopUpAniStackedWidget
6
+
7
+
8
+
9
+ class StackedWidget(QFrame):
10
+ """ Stacked widget """
11
+
12
+ currentChanged = Signal(int)
13
+
14
+ def __init__(self, parent=None):
15
+ super().__init__(parent=parent)
16
+ self.hBoxLayout = QHBoxLayout(self)
17
+ self.view = PopUpAniStackedWidget(self)
18
+
19
+ self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
20
+ self.hBoxLayout.addWidget(self.view)
21
+
22
+ self.view.currentChanged.connect(self.currentChanged)
23
+ self.setAttribute(Qt.WA_StyledBackground)
24
+
25
+ def isAnimationEnabled(self) -> bool:
26
+ return self.view.isAnimationEnabled
27
+
28
+ def setAnimationEnabled(self, isEnabled: bool):
29
+ """set whether the pop animation is enabled"""
30
+ self.view.setAnimationEnabled(isEnabled)
31
+
32
+ def addWidget(self, widget):
33
+ """ add widget to view """
34
+ self.view.addWidget(widget)
35
+
36
+ def removeWidget(self, widget):
37
+ """ remove widget from view """
38
+ self.view.removeWidget(widget)
39
+
40
+ def widget(self, index: int):
41
+ return self.view.widget(index)
42
+
43
+ def setCurrentWidget(self, widget, popOut=True):
44
+ if isinstance(widget, QAbstractScrollArea):
45
+ widget.verticalScrollBar().setValue(0)
46
+
47
+ if not popOut:
48
+ self.view.setCurrentWidget(widget, duration=300)
49
+ else:
50
+ self.view.setCurrentWidget(
51
+ widget, True, False, 200, QEasingCurve.InQuad)
52
+
53
+ def setCurrentIndex(self, index, popOut=True):
54
+ self.setCurrentWidget(self.view.widget(index), popOut)
55
+
56
+ def currentIndex(self):
57
+ return self.view.currentIndex()
58
+
59
+ def currentWidget(self):
60
+ return self.view.currentWidget()
61
+
62
+ def indexOf(self, widget):
63
+ return self.view.indexOf(widget)
64
+
65
+ def count(self):
66
+ return self.view.count()
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: Python-FastUI-Widgets
3
+ Version: 1.0.0
4
+ Summary: FastUI on PySide6
5
+ Author: NumBNN
6
+ Author-email: NumBNN@outlook.com
7
+ Keywords: pyside6 fastui widgets
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: PySide6>=6.4.2
13
+ Requires-Dist: Python-FastUI-Window>=1.0.1
14
+ Requires-Dist: darkdetect
15
+ Provides-Extra: full
16
+ Requires-Dist: scipy; extra == "full"
17
+ Requires-Dist: pillow; extra == "full"
18
+ Requires-Dist: colorthief; extra == "full"
19
+ Dynamic: author
20
+ Dynamic: author-email
21
+ Dynamic: classifier
22
+ Dynamic: description
23
+ Dynamic: description-content-type
24
+ Dynamic: keywords
25
+ Dynamic: license-file
26
+ Dynamic: provides-extra
27
+ Dynamic: requires-dist
28
+ Dynamic: summary
29
+
30
+ 测试自用