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.
- fastuiwidgets/__init__.py +12 -0
- fastuiwidgets/_rc/__init__.py +0 -0
- fastuiwidgets/_rc/resource.py +98835 -0
- fastuiwidgets/common/__init__.py +12 -0
- fastuiwidgets/common/animation.py +530 -0
- fastuiwidgets/common/auto_wrap.py +164 -0
- fastuiwidgets/common/color.py +95 -0
- fastuiwidgets/common/config.py +423 -0
- fastuiwidgets/common/exception_handler.py +31 -0
- fastuiwidgets/common/font.py +38 -0
- fastuiwidgets/common/icon.py +703 -0
- fastuiwidgets/common/image_utils.py +198 -0
- fastuiwidgets/common/overload.py +47 -0
- fastuiwidgets/common/router.py +133 -0
- fastuiwidgets/common/screen.py +25 -0
- fastuiwidgets/common/smooth_scroll.py +141 -0
- fastuiwidgets/common/style_sheet.py +512 -0
- fastuiwidgets/common/theme_listener.py +27 -0
- fastuiwidgets/common/translator.py +14 -0
- fastuiwidgets/components/__init__.py +6 -0
- fastuiwidgets/components/date_time/__init__.py +4 -0
- fastuiwidgets/components/date_time/calendar_picker.py +121 -0
- fastuiwidgets/components/date_time/calendar_view.py +671 -0
- fastuiwidgets/components/date_time/date_picker.py +245 -0
- fastuiwidgets/components/date_time/fast_calendar_view.py +487 -0
- fastuiwidgets/components/date_time/picker_base.py +632 -0
- fastuiwidgets/components/date_time/time_picker.py +223 -0
- fastuiwidgets/components/dialog_box/__init__.py +6 -0
- fastuiwidgets/components/dialog_box/color_dialog.py +414 -0
- fastuiwidgets/components/dialog_box/dialog.py +167 -0
- fastuiwidgets/components/dialog_box/folder_list_dialog.py +307 -0
- fastuiwidgets/components/dialog_box/mask_dialog_base.py +120 -0
- fastuiwidgets/components/dialog_box/message_box_base.py +92 -0
- fastuiwidgets/components/dialog_box/message_dialog.py +65 -0
- fastuiwidgets/components/layout/__init__.py +3 -0
- fastuiwidgets/components/layout/expand_layout.py +96 -0
- fastuiwidgets/components/layout/flow_layout.py +236 -0
- fastuiwidgets/components/layout/v_box_layout.py +41 -0
- fastuiwidgets/components/material/__init__.py +6 -0
- fastuiwidgets/components/material/acrylic_combo_box.py +96 -0
- fastuiwidgets/components/material/acrylic_flyout.py +105 -0
- fastuiwidgets/components/material/acrylic_line_edit.py +27 -0
- fastuiwidgets/components/material/acrylic_menu.py +204 -0
- fastuiwidgets/components/material/acrylic_tool_tip.py +39 -0
- fastuiwidgets/components/material/acrylic_widget.py +42 -0
- fastuiwidgets/components/navigation/__init__.py +9 -0
- fastuiwidgets/components/navigation/breadcrumb.py +350 -0
- fastuiwidgets/components/navigation/navigation_bar.py +416 -0
- fastuiwidgets/components/navigation/navigation_interface.py +268 -0
- fastuiwidgets/components/navigation/navigation_panel.py +657 -0
- fastuiwidgets/components/navigation/navigation_widget.py +686 -0
- fastuiwidgets/components/navigation/pivot.py +272 -0
- fastuiwidgets/components/navigation/segmented_widget.py +174 -0
- fastuiwidgets/components/settings/__init__.py +8 -0
- fastuiwidgets/components/settings/custom_color_setting_card.py +139 -0
- fastuiwidgets/components/settings/expand_setting_card.py +390 -0
- fastuiwidgets/components/settings/folder_list_setting_card.py +134 -0
- fastuiwidgets/components/settings/options_setting_card.py +86 -0
- fastuiwidgets/components/settings/setting_card.py +449 -0
- fastuiwidgets/components/settings/setting_card_group.py +48 -0
- fastuiwidgets/components/widgets/__init__.py +41 -0
- fastuiwidgets/components/widgets/acrylic_label.py +261 -0
- fastuiwidgets/components/widgets/button.py +1059 -0
- fastuiwidgets/components/widgets/card_widget.py +369 -0
- fastuiwidgets/components/widgets/check_box.py +203 -0
- fastuiwidgets/components/widgets/combo_box.py +556 -0
- fastuiwidgets/components/widgets/command_bar.py +636 -0
- fastuiwidgets/components/widgets/cycle_list_widget.py +251 -0
- fastuiwidgets/components/widgets/flip_view.py +430 -0
- fastuiwidgets/components/widgets/flyout.py +521 -0
- fastuiwidgets/components/widgets/frameless_window.py +49 -0
- fastuiwidgets/components/widgets/icon_widget.py +53 -0
- fastuiwidgets/components/widgets/info_badge.py +483 -0
- fastuiwidgets/components/widgets/info_bar.py +596 -0
- fastuiwidgets/components/widgets/label.py +553 -0
- fastuiwidgets/components/widgets/line_edit.py +551 -0
- fastuiwidgets/components/widgets/list_view.py +158 -0
- fastuiwidgets/components/widgets/menu.py +1318 -0
- fastuiwidgets/components/widgets/pips_pager.py +331 -0
- fastuiwidgets/components/widgets/progress_bar.py +311 -0
- fastuiwidgets/components/widgets/progress_ring.py +212 -0
- fastuiwidgets/components/widgets/scroll_area.py +125 -0
- fastuiwidgets/components/widgets/scroll_bar.py +673 -0
- fastuiwidgets/components/widgets/separator.py +43 -0
- fastuiwidgets/components/widgets/slider.py +307 -0
- fastuiwidgets/components/widgets/spin_box.py +306 -0
- fastuiwidgets/components/widgets/stacked_widget.py +211 -0
- fastuiwidgets/components/widgets/state_tool_tip.py +188 -0
- fastuiwidgets/components/widgets/switch_button.py +312 -0
- fastuiwidgets/components/widgets/tab_view.py +804 -0
- fastuiwidgets/components/widgets/table_view.py +360 -0
- fastuiwidgets/components/widgets/teaching_tip.py +657 -0
- fastuiwidgets/components/widgets/tool_tip.py +460 -0
- fastuiwidgets/components/widgets/tree_view.py +216 -0
- fastuiwidgets/multimedia/__init__.py +3 -0
- fastuiwidgets/multimedia/media_play_bar.py +319 -0
- fastuiwidgets/multimedia/media_player.py +124 -0
- fastuiwidgets/multimedia/video_widget.py +93 -0
- fastuiwidgets/window/__init__.py +2 -0
- fastuiwidgets/window/fluent_window.py +413 -0
- fastuiwidgets/window/splash_screen.py +92 -0
- fastuiwidgets/window/stacked_widget.py +66 -0
- python_fastui_widgets-1.0.0.dist-info/METADATA +30 -0
- python_fastui_widgets-1.0.0.dist-info/RECORD +107 -0
- python_fastui_widgets-1.0.0.dist-info/WHEEL +5 -0
- python_fastui_widgets-1.0.0.dist-info/licenses/LICENSE +674 -0
- python_fastui_widgets-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,416 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
from typing import Dict, Union
|
3
|
+
|
4
|
+
from PySide6.QtCore import Qt, QRect, QPropertyAnimation, QEasingCurve, Property, QRectF
|
5
|
+
from PySide6.QtGui import QFont, QPainter, QColor, QIcon
|
6
|
+
from PySide6.QtWidgets import QWidget, QVBoxLayout
|
7
|
+
|
8
|
+
from ...common.config import isDarkTheme
|
9
|
+
from ...common.font import setFont
|
10
|
+
from ...common.style_sheet import themeColor
|
11
|
+
from ...common.color import autoFallbackThemeColor
|
12
|
+
from ...common.icon import drawIcon, FluentIconBase, toQIcon
|
13
|
+
from ...common.icon import FluentIcon as FIF
|
14
|
+
from ...common.router import qrouter
|
15
|
+
from ...common.style_sheet import FluentStyleSheet
|
16
|
+
from ..widgets.scroll_area import ScrollArea
|
17
|
+
from .navigation_widget import NavigationPushButton, NavigationWidget
|
18
|
+
from .navigation_panel import RouteKeyError, NavigationItemPosition
|
19
|
+
|
20
|
+
|
21
|
+
class IconSlideAnimation(QPropertyAnimation):
|
22
|
+
""" Icon sliding animation """
|
23
|
+
|
24
|
+
def __init__(self, parent=None):
|
25
|
+
super().__init__(parent)
|
26
|
+
self._offset = 0
|
27
|
+
self.maxOffset = 6
|
28
|
+
self.setTargetObject(self)
|
29
|
+
self.setPropertyName(b"offset")
|
30
|
+
|
31
|
+
def getOffset(self):
|
32
|
+
return self._offset
|
33
|
+
|
34
|
+
def setOffset(self, value: float):
|
35
|
+
self._offset = value
|
36
|
+
self.parent().update()
|
37
|
+
|
38
|
+
def slideDown(self):
|
39
|
+
""" slide down """
|
40
|
+
self.setEndValue(self.maxOffset)
|
41
|
+
self.setDuration(100)
|
42
|
+
self.start()
|
43
|
+
|
44
|
+
def slideUp(self):
|
45
|
+
""" slide up """
|
46
|
+
self.setEndValue(0)
|
47
|
+
self.setDuration(100)
|
48
|
+
self.start()
|
49
|
+
|
50
|
+
offset = Property(float, getOffset, setOffset)
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
class NavigationBarPushButton(NavigationPushButton):
|
55
|
+
""" Navigation bar push button """
|
56
|
+
|
57
|
+
def __init__(self, icon: Union[str, QIcon, FIF], text: str, isSelectable: bool, selectedIcon=None, parent=None):
|
58
|
+
super().__init__(icon, text, isSelectable, parent)
|
59
|
+
self.iconAni = IconSlideAnimation(self)
|
60
|
+
self._selectedIcon = selectedIcon
|
61
|
+
self._isSelectedTextVisible = True
|
62
|
+
self.lightSelectedColor = QColor()
|
63
|
+
self.darkSelectedColor = QColor()
|
64
|
+
|
65
|
+
self.setFixedSize(64, 58)
|
66
|
+
setFont(self, 11)
|
67
|
+
|
68
|
+
def setSelectedColor(self, light, dark):
|
69
|
+
self.lightSelectedColor = QColor(light)
|
70
|
+
self.darkSelectedColor = QColor(dark)
|
71
|
+
self.update()
|
72
|
+
|
73
|
+
def selectedIcon(self):
|
74
|
+
if self._selectedIcon:
|
75
|
+
return toQIcon(self._selectedIcon)
|
76
|
+
|
77
|
+
return QIcon()
|
78
|
+
|
79
|
+
def setSelectedIcon(self, icon: Union[str, QIcon, FIF]):
|
80
|
+
self._selectedIcon = icon
|
81
|
+
self.update()
|
82
|
+
|
83
|
+
def setSelectedTextVisible(self, isVisible):
|
84
|
+
self._isSelectedTextVisible = isVisible
|
85
|
+
self.update()
|
86
|
+
|
87
|
+
def paintEvent(self, e):
|
88
|
+
painter = QPainter(self)
|
89
|
+
painter.setRenderHints(QPainter.Antialiasing |
|
90
|
+
QPainter.TextAntialiasing | QPainter.SmoothPixmapTransform)
|
91
|
+
painter.setPen(Qt.NoPen)
|
92
|
+
|
93
|
+
self._drawBackground(painter)
|
94
|
+
self._drawIcon(painter)
|
95
|
+
self._drawText(painter)
|
96
|
+
|
97
|
+
def _drawBackground(self, painter: QPainter):
|
98
|
+
if self.isSelected:
|
99
|
+
painter.setBrush(QColor(255, 255, 255, 42) if isDarkTheme() else Qt.white)
|
100
|
+
painter.drawRoundedRect(self.rect(), 5, 5)
|
101
|
+
|
102
|
+
# draw indicator
|
103
|
+
painter.setBrush(autoFallbackThemeColor(self.lightSelectedColor, self.darkSelectedColor))
|
104
|
+
if not self.isPressed:
|
105
|
+
painter.drawRoundedRect(0, 16, 4, 24, 2, 2)
|
106
|
+
else:
|
107
|
+
painter.drawRoundedRect(0, 19, 4, 18, 2, 2)
|
108
|
+
elif self.isPressed or self.isEnter:
|
109
|
+
c = 255 if isDarkTheme() else 0
|
110
|
+
alpha = 9 if self.isEnter else 6
|
111
|
+
painter.setBrush(QColor(c, c, c, alpha))
|
112
|
+
painter.drawRoundedRect(self.rect(), 5, 5)
|
113
|
+
|
114
|
+
def _drawIcon(self, painter: QPainter):
|
115
|
+
if (self.isPressed or not self.isEnter) and not self.isSelected:
|
116
|
+
painter.setOpacity(0.6)
|
117
|
+
if not self.isEnabled():
|
118
|
+
painter.setOpacity(0.4)
|
119
|
+
|
120
|
+
if self._isSelectedTextVisible:
|
121
|
+
rect = QRectF(22, 13, 20, 20)
|
122
|
+
else:
|
123
|
+
rect = QRectF(22, 13 + self.iconAni.offset, 20, 20)
|
124
|
+
|
125
|
+
selectedIcon = self._selectedIcon or self._icon
|
126
|
+
|
127
|
+
if isinstance(selectedIcon, FluentIconBase) and self.isSelected:
|
128
|
+
color = autoFallbackThemeColor(self.lightSelectedColor, self.darkSelectedColor)
|
129
|
+
selectedIcon.render(painter, rect, fill=color.name())
|
130
|
+
elif self.isSelected:
|
131
|
+
drawIcon(selectedIcon, painter, rect)
|
132
|
+
else:
|
133
|
+
drawIcon(self._icon, painter, rect)
|
134
|
+
|
135
|
+
def _drawText(self, painter: QPainter):
|
136
|
+
if self.isSelected and not self._isSelectedTextVisible:
|
137
|
+
return
|
138
|
+
|
139
|
+
if self.isSelected:
|
140
|
+
painter.setPen(autoFallbackThemeColor(self.lightSelectedColor, self.darkSelectedColor))
|
141
|
+
else:
|
142
|
+
painter.setPen(Qt.white if isDarkTheme() else Qt.black)
|
143
|
+
|
144
|
+
painter.setFont(self.font())
|
145
|
+
rect = QRect(0, 32, self.width(), 26)
|
146
|
+
painter.drawText(rect, Qt.AlignCenter, self.text())
|
147
|
+
|
148
|
+
def setSelected(self, isSelected: bool):
|
149
|
+
if isSelected == self.isSelected:
|
150
|
+
return
|
151
|
+
|
152
|
+
self.isSelected = isSelected
|
153
|
+
|
154
|
+
if isSelected:
|
155
|
+
self.iconAni.slideDown()
|
156
|
+
else:
|
157
|
+
self.iconAni.slideUp()
|
158
|
+
|
159
|
+
|
160
|
+
class NavigationBar(QWidget):
|
161
|
+
|
162
|
+
def __init__(self, parent=None):
|
163
|
+
super().__init__(parent=parent)
|
164
|
+
|
165
|
+
self.lightSelectedColor = QColor()
|
166
|
+
self.darkSelectedColor = QColor()
|
167
|
+
|
168
|
+
self.scrollArea = ScrollArea(self)
|
169
|
+
self.scrollWidget = QWidget()
|
170
|
+
|
171
|
+
self.vBoxLayout = QVBoxLayout(self)
|
172
|
+
self.topLayout = QVBoxLayout()
|
173
|
+
self.bottomLayout = QVBoxLayout()
|
174
|
+
self.scrollLayout = QVBoxLayout(self.scrollWidget)
|
175
|
+
|
176
|
+
self.items = {} # type: Dict[str, NavigationWidget]
|
177
|
+
self.history = qrouter
|
178
|
+
|
179
|
+
self.__initWidget()
|
180
|
+
|
181
|
+
def __initWidget(self):
|
182
|
+
self.resize(48, self.height())
|
183
|
+
self.setAttribute(Qt.WA_StyledBackground)
|
184
|
+
self.window().installEventFilter(self)
|
185
|
+
|
186
|
+
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
187
|
+
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
188
|
+
self.scrollArea.horizontalScrollBar().setEnabled(False)
|
189
|
+
self.scrollArea.setWidget(self.scrollWidget)
|
190
|
+
self.scrollArea.setWidgetResizable(True)
|
191
|
+
|
192
|
+
self.scrollWidget.setObjectName('scrollWidget')
|
193
|
+
FluentStyleSheet.NAVIGATION_INTERFACE.apply(self)
|
194
|
+
FluentStyleSheet.NAVIGATION_INTERFACE.apply(self.scrollWidget)
|
195
|
+
self.__initLayout()
|
196
|
+
|
197
|
+
def __initLayout(self):
|
198
|
+
self.vBoxLayout.setContentsMargins(0, 5, 0, 5)
|
199
|
+
self.topLayout.setContentsMargins(4, 0, 4, 0)
|
200
|
+
self.bottomLayout.setContentsMargins(4, 0, 4, 0)
|
201
|
+
self.scrollLayout.setContentsMargins(4, 0, 4, 0)
|
202
|
+
self.vBoxLayout.setSpacing(4)
|
203
|
+
self.topLayout.setSpacing(4)
|
204
|
+
self.bottomLayout.setSpacing(4)
|
205
|
+
self.scrollLayout.setSpacing(4)
|
206
|
+
|
207
|
+
self.vBoxLayout.addLayout(self.topLayout, 0)
|
208
|
+
self.vBoxLayout.addWidget(self.scrollArea)
|
209
|
+
self.vBoxLayout.addLayout(self.bottomLayout, 0)
|
210
|
+
|
211
|
+
self.vBoxLayout.setAlignment(Qt.AlignTop)
|
212
|
+
self.topLayout.setAlignment(Qt.AlignTop)
|
213
|
+
self.scrollLayout.setAlignment(Qt.AlignTop)
|
214
|
+
self.bottomLayout.setAlignment(Qt.AlignBottom)
|
215
|
+
|
216
|
+
def widget(self, routeKey: str):
|
217
|
+
if routeKey not in self.items:
|
218
|
+
raise RouteKeyError(f"`{routeKey}` is illegal.")
|
219
|
+
|
220
|
+
return self.items[routeKey]
|
221
|
+
|
222
|
+
def addItem(self, routeKey: str, icon: Union[str, QIcon, FluentIconBase], text: str, onClick=None,
|
223
|
+
selectable=True, selectedIcon=None, position=NavigationItemPosition.TOP):
|
224
|
+
""" add navigation item
|
225
|
+
|
226
|
+
Parameters
|
227
|
+
----------
|
228
|
+
routeKey: str
|
229
|
+
the unique name of item
|
230
|
+
|
231
|
+
icon: str | QIcon | FluentIconBase
|
232
|
+
the icon of navigation item
|
233
|
+
|
234
|
+
text: str
|
235
|
+
the text of navigation item
|
236
|
+
|
237
|
+
onClick: callable
|
238
|
+
the slot connected to item clicked signal
|
239
|
+
|
240
|
+
selectable: bool
|
241
|
+
whether the item is selectable
|
242
|
+
|
243
|
+
selectedIcon: str | QIcon | FluentIconBase
|
244
|
+
the icon of navigation item in selected state
|
245
|
+
|
246
|
+
position: NavigationItemPosition
|
247
|
+
where the button is added
|
248
|
+
"""
|
249
|
+
return self.insertItem(-1, routeKey, icon, text, onClick, selectable, selectedIcon, position)
|
250
|
+
|
251
|
+
def addWidget(self, routeKey: str, widget: NavigationWidget, onClick=None, position=NavigationItemPosition.TOP):
|
252
|
+
""" add custom widget
|
253
|
+
|
254
|
+
Parameters
|
255
|
+
----------
|
256
|
+
routeKey: str
|
257
|
+
the unique name of item
|
258
|
+
|
259
|
+
widget: NavigationWidget
|
260
|
+
the custom widget to be added
|
261
|
+
|
262
|
+
onClick: callable
|
263
|
+
the slot connected to item clicked signal
|
264
|
+
|
265
|
+
position: NavigationItemPosition
|
266
|
+
where the button is added
|
267
|
+
"""
|
268
|
+
self.insertWidget(-1, routeKey, widget, onClick, position)
|
269
|
+
|
270
|
+
def insertItem(self, index: int, routeKey: str, icon: Union[str, QIcon, FluentIconBase], text: str, onClick=None,
|
271
|
+
selectable=True, selectedIcon=None, position=NavigationItemPosition.TOP):
|
272
|
+
""" insert navigation tree item
|
273
|
+
|
274
|
+
Parameters
|
275
|
+
----------
|
276
|
+
index: int
|
277
|
+
the insert position of parent widget
|
278
|
+
|
279
|
+
routeKey: str
|
280
|
+
the unique name of item
|
281
|
+
|
282
|
+
icon: str | QIcon | FluentIconBase
|
283
|
+
the icon of navigation item
|
284
|
+
|
285
|
+
text: str
|
286
|
+
the text of navigation item
|
287
|
+
|
288
|
+
onClick: callable
|
289
|
+
the slot connected to item clicked signal
|
290
|
+
|
291
|
+
selectable: bool
|
292
|
+
whether the item is selectable
|
293
|
+
|
294
|
+
selectedIcon: str | QIcon | FluentIconBase
|
295
|
+
the icon of navigation item in selected state
|
296
|
+
|
297
|
+
position: NavigationItemPosition
|
298
|
+
where the button is added
|
299
|
+
"""
|
300
|
+
if routeKey in self.items:
|
301
|
+
return
|
302
|
+
|
303
|
+
w = NavigationBarPushButton(icon, text, selectable, selectedIcon, self)
|
304
|
+
w.setSelectedColor(self.lightSelectedColor, self.darkSelectedColor)
|
305
|
+
self.insertWidget(index, routeKey, w, onClick, position)
|
306
|
+
return w
|
307
|
+
|
308
|
+
def insertWidget(self, index: int, routeKey: str, widget: NavigationWidget, onClick=None,
|
309
|
+
position=NavigationItemPosition.TOP):
|
310
|
+
""" insert custom widget
|
311
|
+
|
312
|
+
Parameters
|
313
|
+
----------
|
314
|
+
index: int
|
315
|
+
insert position
|
316
|
+
|
317
|
+
routeKey: str
|
318
|
+
the unique name of item
|
319
|
+
|
320
|
+
widget: NavigationWidget
|
321
|
+
the custom widget to be added
|
322
|
+
|
323
|
+
onClick: callable
|
324
|
+
the slot connected to item clicked signal
|
325
|
+
|
326
|
+
position: NavigationItemPosition
|
327
|
+
where the button is added
|
328
|
+
"""
|
329
|
+
if routeKey in self.items:
|
330
|
+
return
|
331
|
+
|
332
|
+
self._registerWidget(routeKey, widget, onClick)
|
333
|
+
self._insertWidgetToLayout(index, widget, position)
|
334
|
+
|
335
|
+
def _registerWidget(self, routeKey: str, widget: NavigationWidget, onClick):
|
336
|
+
""" register widget """
|
337
|
+
widget.clicked.connect(self._onWidgetClicked)
|
338
|
+
|
339
|
+
if onClick is not None:
|
340
|
+
widget.clicked.connect(onClick)
|
341
|
+
|
342
|
+
widget.setProperty('routeKey', routeKey)
|
343
|
+
self.items[routeKey] = widget
|
344
|
+
|
345
|
+
def _insertWidgetToLayout(self, index: int, widget: NavigationWidget, position: NavigationItemPosition):
|
346
|
+
""" insert widget to layout """
|
347
|
+
if position == NavigationItemPosition.TOP:
|
348
|
+
widget.setParent(self)
|
349
|
+
self.topLayout.insertWidget(
|
350
|
+
index, widget, 0, Qt.AlignTop | Qt.AlignHCenter)
|
351
|
+
elif position == NavigationItemPosition.SCROLL:
|
352
|
+
widget.setParent(self.scrollWidget)
|
353
|
+
self.scrollLayout.insertWidget(
|
354
|
+
index, widget, 0, Qt.AlignTop | Qt.AlignHCenter)
|
355
|
+
else:
|
356
|
+
widget.setParent(self)
|
357
|
+
self.bottomLayout.insertWidget(
|
358
|
+
index, widget, 0, Qt.AlignBottom | Qt.AlignHCenter)
|
359
|
+
|
360
|
+
widget.show()
|
361
|
+
|
362
|
+
def removeWidget(self, routeKey: str):
|
363
|
+
""" remove widget
|
364
|
+
|
365
|
+
Parameters
|
366
|
+
----------
|
367
|
+
routeKey: str
|
368
|
+
the unique name of item
|
369
|
+
"""
|
370
|
+
if routeKey not in self.items:
|
371
|
+
return
|
372
|
+
|
373
|
+
widget = self.items.pop(routeKey)
|
374
|
+
widget.deleteLater()
|
375
|
+
self.history.remove(routeKey)
|
376
|
+
|
377
|
+
def setCurrentItem(self, routeKey: str):
|
378
|
+
""" set current selected item
|
379
|
+
|
380
|
+
Parameters
|
381
|
+
----------
|
382
|
+
routeKey: str
|
383
|
+
the unique name of item
|
384
|
+
"""
|
385
|
+
if routeKey not in self.items:
|
386
|
+
return
|
387
|
+
|
388
|
+
for k, widget in self.items.items():
|
389
|
+
widget.setSelected(k == routeKey)
|
390
|
+
|
391
|
+
def setFont(self, font: QFont):
|
392
|
+
""" set the font of navigation item """
|
393
|
+
super().setFont(font)
|
394
|
+
|
395
|
+
for widget in self.buttons():
|
396
|
+
widget.setFont(font)
|
397
|
+
|
398
|
+
def setSelectedTextVisible(self, isVisible: bool):
|
399
|
+
""" set whether the text is visible when button is selected """
|
400
|
+
for widget in self.buttons():
|
401
|
+
widget.setSelectedTextVisible(isVisible)
|
402
|
+
|
403
|
+
def setSelectedColor(self, light, dark):
|
404
|
+
""" set the selected color of all items """
|
405
|
+
self.lightSelectedColor = QColor(light)
|
406
|
+
self.darkSelectedColor = QColor(dark)
|
407
|
+
for button in self.buttons():
|
408
|
+
button.setSelectedColor(self.lightSelectedColor, self.darkSelectedColor)
|
409
|
+
|
410
|
+
def buttons(self):
|
411
|
+
return [i for i in self.items.values() if isinstance(i, NavigationPushButton)]
|
412
|
+
|
413
|
+
def _onWidgetClicked(self):
|
414
|
+
widget = self.sender() # type: NavigationWidget
|
415
|
+
if widget.isSelectable:
|
416
|
+
self.setCurrentItem(widget.property('routeKey'))
|
@@ -0,0 +1,268 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
from typing import Union
|
3
|
+
|
4
|
+
from PySide6.QtCore import Qt, QEvent, Signal
|
5
|
+
from PySide6.QtGui import QResizeEvent, QIcon
|
6
|
+
from PySide6.QtWidgets import QWidget
|
7
|
+
|
8
|
+
from .navigation_panel import NavigationPanel, NavigationItemPosition, NavigationWidget, NavigationDisplayMode
|
9
|
+
from .navigation_widget import NavigationTreeWidget
|
10
|
+
from ...common.style_sheet import FluentStyleSheet
|
11
|
+
from ...common.icon import FluentIconBase
|
12
|
+
|
13
|
+
|
14
|
+
class NavigationInterface(QWidget):
|
15
|
+
""" Navigation interface """
|
16
|
+
|
17
|
+
displayModeChanged = Signal(NavigationDisplayMode)
|
18
|
+
|
19
|
+
def __init__(self, parent=None, showMenuButton=True, showReturnButton=False, collapsible=True):
|
20
|
+
"""
|
21
|
+
Parameters
|
22
|
+
----------
|
23
|
+
parent: widget
|
24
|
+
parent widget
|
25
|
+
|
26
|
+
showMenuButton: bool
|
27
|
+
whether to show menu button
|
28
|
+
|
29
|
+
showReturnButton: bool
|
30
|
+
whether to show return button
|
31
|
+
|
32
|
+
collapsible: bool
|
33
|
+
Is the navigation interface collapsible
|
34
|
+
"""
|
35
|
+
super().__init__(parent=parent)
|
36
|
+
self.panel = NavigationPanel(self)
|
37
|
+
self.panel.setMenuButtonVisible(showMenuButton and collapsible)
|
38
|
+
self.panel.setReturnButtonVisible(showReturnButton)
|
39
|
+
self.panel.setCollapsible(collapsible)
|
40
|
+
self.panel.installEventFilter(self)
|
41
|
+
self.panel.displayModeChanged.connect(self.displayModeChanged)
|
42
|
+
|
43
|
+
self.resize(48, self.height())
|
44
|
+
self.setMinimumWidth(48)
|
45
|
+
self.setAttribute(Qt.WA_TranslucentBackground)
|
46
|
+
|
47
|
+
def addItem(self, routeKey: str, icon: Union[str, QIcon, FluentIconBase], text: str, onClick=None,
|
48
|
+
selectable=True, position=NavigationItemPosition.TOP, tooltip: str = None,
|
49
|
+
parentRouteKey: str = None) -> NavigationTreeWidget:
|
50
|
+
""" add navigation item
|
51
|
+
|
52
|
+
Parameters
|
53
|
+
----------
|
54
|
+
routKey: str
|
55
|
+
the unique name of item
|
56
|
+
|
57
|
+
icon: str | QIcon | FluentIconBase
|
58
|
+
the icon of navigation item
|
59
|
+
|
60
|
+
text: str
|
61
|
+
the text of navigation item
|
62
|
+
|
63
|
+
onClick: callable
|
64
|
+
the slot connected to item clicked signal
|
65
|
+
|
66
|
+
selectable: bool
|
67
|
+
whether the item is selectable
|
68
|
+
|
69
|
+
position: NavigationItemPosition
|
70
|
+
where the button is added
|
71
|
+
|
72
|
+
tooltip: str
|
73
|
+
the tooltip of item
|
74
|
+
|
75
|
+
parentRouteKey: str
|
76
|
+
the route key of parent item, the parent item should be `NavigationTreeWidgetBase`
|
77
|
+
"""
|
78
|
+
return self.insertItem(-1, routeKey, icon, text, onClick, selectable, position, tooltip, parentRouteKey)
|
79
|
+
|
80
|
+
def addWidget(self, routeKey: str, widget: NavigationWidget, onClick=None, position=NavigationItemPosition.TOP,
|
81
|
+
tooltip: str = None, parentRouteKey: str = None):
|
82
|
+
""" add custom widget
|
83
|
+
|
84
|
+
Parameters
|
85
|
+
----------
|
86
|
+
routKey: str
|
87
|
+
the unique name of item
|
88
|
+
|
89
|
+
widget: NavigationWidget
|
90
|
+
the custom widget to be added
|
91
|
+
|
92
|
+
onClick: callable
|
93
|
+
the slot connected to item clicked signal
|
94
|
+
|
95
|
+
position: NavigationItemPosition
|
96
|
+
where the widget is added
|
97
|
+
|
98
|
+
tooltip: str
|
99
|
+
the tooltip of widget
|
100
|
+
|
101
|
+
parentRouteKey: str
|
102
|
+
the route key of parent item, the parent item should be `NavigationTreeWidgetBase`
|
103
|
+
"""
|
104
|
+
self.insertWidget(-1, routeKey, widget, onClick, position, tooltip, parentRouteKey)
|
105
|
+
|
106
|
+
def insertItem(self, index: int, routeKey: str, icon: Union[str, QIcon, FluentIconBase], text: str,
|
107
|
+
onClick=None, selectable=True, position=NavigationItemPosition.TOP, tooltip: str = None,
|
108
|
+
parentRouteKey: str = None) -> NavigationTreeWidget:
|
109
|
+
""" insert navigation item
|
110
|
+
|
111
|
+
Parameters
|
112
|
+
----------
|
113
|
+
index: int
|
114
|
+
insert position
|
115
|
+
|
116
|
+
routKey: str
|
117
|
+
the unique name of item
|
118
|
+
|
119
|
+
icon: str | QIcon | FluentIconBase
|
120
|
+
the icon of navigation item
|
121
|
+
|
122
|
+
text: str
|
123
|
+
the text of navigation item
|
124
|
+
|
125
|
+
onClick: callable
|
126
|
+
the slot connected to item clicked signal
|
127
|
+
|
128
|
+
selectable: bool
|
129
|
+
whether the item is selectable
|
130
|
+
|
131
|
+
position: NavigationItemPosition
|
132
|
+
where the item is added
|
133
|
+
|
134
|
+
tooltip: str
|
135
|
+
the tooltip of item
|
136
|
+
|
137
|
+
parentRouteKey: str
|
138
|
+
the route key of parent item, the parent item should be `NavigationTreeWidgetBase`
|
139
|
+
"""
|
140
|
+
w = self.panel.insertItem(index, routeKey, icon, text, onClick, selectable, position, tooltip, parentRouteKey)
|
141
|
+
self.setMinimumHeight(self.panel.layoutMinHeight())
|
142
|
+
return w
|
143
|
+
|
144
|
+
def insertWidget(self, index: int, routeKey: str, widget: NavigationWidget, onClick=None,
|
145
|
+
position=NavigationItemPosition.TOP, tooltip: str = None, parentRouteKey: str = None):
|
146
|
+
""" insert custom widget
|
147
|
+
|
148
|
+
Parameters
|
149
|
+
----------
|
150
|
+
index: int
|
151
|
+
insert position
|
152
|
+
|
153
|
+
routKey: str
|
154
|
+
the unique name of item
|
155
|
+
|
156
|
+
widget: NavigationWidget
|
157
|
+
the custom widget to be added
|
158
|
+
|
159
|
+
onClick: callable
|
160
|
+
the slot connected to item clicked signal
|
161
|
+
|
162
|
+
position: NavigationItemPosition
|
163
|
+
where the widget is added
|
164
|
+
|
165
|
+
tooltip: str
|
166
|
+
the tooltip of widget
|
167
|
+
|
168
|
+
parentRouteKey: str
|
169
|
+
the route key of parent item, the parent item should be `NavigationTreeWidgetBase`
|
170
|
+
"""
|
171
|
+
self.panel.insertWidget(index, routeKey, widget, onClick, position, tooltip, parentRouteKey)
|
172
|
+
self.setMinimumHeight(self.panel.layoutMinHeight())
|
173
|
+
|
174
|
+
def addSeparator(self, position=NavigationItemPosition.TOP):
|
175
|
+
""" add separator
|
176
|
+
|
177
|
+
Parameters
|
178
|
+
----------
|
179
|
+
position: NavigationPostion
|
180
|
+
where to add the separator
|
181
|
+
"""
|
182
|
+
self.insertSeparator(-1, position)
|
183
|
+
|
184
|
+
def insertSeparator(self, index: int, position=NavigationItemPosition.TOP):
|
185
|
+
""" add separator
|
186
|
+
|
187
|
+
Parameters
|
188
|
+
----------
|
189
|
+
index: int
|
190
|
+
insert position
|
191
|
+
|
192
|
+
position: NavigationPostion
|
193
|
+
where to add the separator
|
194
|
+
"""
|
195
|
+
self.panel.insertSeparator(index, position)
|
196
|
+
self.setMinimumHeight(self.panel.layoutMinHeight())
|
197
|
+
|
198
|
+
def removeWidget(self, routeKey: str):
|
199
|
+
""" remove widget
|
200
|
+
|
201
|
+
Parameters
|
202
|
+
----------
|
203
|
+
routKey: str
|
204
|
+
the unique name of item
|
205
|
+
"""
|
206
|
+
self.panel.removeWidget(routeKey)
|
207
|
+
|
208
|
+
def setCurrentItem(self, name: str):
|
209
|
+
""" set current selected item
|
210
|
+
|
211
|
+
Parameters
|
212
|
+
----------
|
213
|
+
name: str
|
214
|
+
the unique name of item
|
215
|
+
"""
|
216
|
+
self.panel.setCurrentItem(name)
|
217
|
+
|
218
|
+
def expand(self, useAni=True):
|
219
|
+
""" expand navigation panel """
|
220
|
+
self.panel.expand(useAni)
|
221
|
+
|
222
|
+
def toggle(self):
|
223
|
+
""" toggle navigation panel """
|
224
|
+
self.panel.toggle()
|
225
|
+
|
226
|
+
def setExpandWidth(self, width: int):
|
227
|
+
""" set the maximum width """
|
228
|
+
self.panel.setExpandWidth(width)
|
229
|
+
|
230
|
+
def setMinimumExpandWidth(self, width: int):
|
231
|
+
""" Set the minimum window width that allows panel to be expanded """
|
232
|
+
self.panel.setMinimumExpandWidth(width)
|
233
|
+
|
234
|
+
def setMenuButtonVisible(self, isVisible: bool):
|
235
|
+
""" set whether the menu button is visible """
|
236
|
+
self.panel.setMenuButtonVisible(isVisible)
|
237
|
+
|
238
|
+
def setReturnButtonVisible(self, isVisible: bool):
|
239
|
+
""" set whether the return button is visible """
|
240
|
+
self.panel.setReturnButtonVisible(isVisible)
|
241
|
+
|
242
|
+
def setCollapsible(self, collapsible: bool):
|
243
|
+
self.panel.setCollapsible(collapsible)
|
244
|
+
|
245
|
+
def isAcrylicEnabled(self):
|
246
|
+
return self.panel.isAcrylicEnabled()
|
247
|
+
|
248
|
+
def setAcrylicEnabled(self, isEnabled: bool):
|
249
|
+
""" set whether the acrylic background effect is enabled """
|
250
|
+
self.panel.setAcrylicEnabled(isEnabled)
|
251
|
+
|
252
|
+
def widget(self, routeKey: str):
|
253
|
+
return self.panel.widget(routeKey)
|
254
|
+
|
255
|
+
def eventFilter(self, obj, e: QEvent):
|
256
|
+
if obj is not self.panel or e.type() != QEvent.Resize:
|
257
|
+
return super().eventFilter(obj, e)
|
258
|
+
|
259
|
+
if self.panel.displayMode != NavigationDisplayMode.MENU:
|
260
|
+
event = QResizeEvent(e)
|
261
|
+
if event.oldSize().width() != event.size().width():
|
262
|
+
self.setFixedWidth(event.size().width())
|
263
|
+
|
264
|
+
return super().eventFilter(obj, e)
|
265
|
+
|
266
|
+
def resizeEvent(self, e: QResizeEvent):
|
267
|
+
if e.oldSize().height() != self.height():
|
268
|
+
self.panel.setFixedHeight(self.height())
|