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,390 @@
1
+ # coding:utf-8
2
+ from typing import List, Union
3
+ from PySide6.QtCore import QEvent, Qt, QPropertyAnimation, Property, QEasingCurve, QRectF
4
+ from PySide6.QtGui import QColor, QPainter, QIcon, QPainterPath
5
+ from PySide6.QtWidgets import QFrame, QWidget, QAbstractButton, QApplication, QScrollArea, QVBoxLayout
6
+
7
+ from ...common.config import isDarkTheme
8
+ from ...common.icon import FluentIcon as FIF
9
+ from ...common.style_sheet import FluentStyleSheet
10
+ from .setting_card import SettingCard
11
+ from ..layout.v_box_layout import VBoxLayout
12
+
13
+
14
+ class ExpandButton(QAbstractButton):
15
+ """ Expand button """
16
+
17
+ def __init__(self, parent=None):
18
+ super().__init__(parent)
19
+ self.setFixedSize(30, 30)
20
+ self.__angle = 0
21
+ self.isHover = False
22
+ self.isPressed = False
23
+ self.rotateAni = QPropertyAnimation(self, b'angle', self)
24
+ self.clicked.connect(self.__onClicked)
25
+
26
+ def paintEvent(self, e):
27
+ painter = QPainter(self)
28
+ painter.setRenderHints(QPainter.Antialiasing |
29
+ QPainter.SmoothPixmapTransform)
30
+ painter.setPen(Qt.NoPen)
31
+
32
+ # draw background
33
+ r = 255 if isDarkTheme() else 0
34
+ color = Qt.transparent
35
+
36
+ if self.isEnabled():
37
+ if self.isPressed:
38
+ color = QColor(r, r, r, 10)
39
+ elif self.isHover:
40
+ color = QColor(r, r, r, 14)
41
+ else:
42
+ painter.setOpacity(0.36)
43
+
44
+ painter.setBrush(color)
45
+ painter.drawRoundedRect(self.rect(), 4, 4)
46
+
47
+ # draw icon
48
+ painter.translate(self.width()//2, self.height()//2)
49
+ painter.rotate(self.__angle)
50
+ FIF.ARROW_DOWN.render(painter, QRectF(-5, -5, 9.6, 9.6))
51
+
52
+ def enterEvent(self, e):
53
+ self.setHover(True)
54
+
55
+ def leaveEvent(self, e):
56
+ self.setHover(False)
57
+
58
+ def mousePressEvent(self, e):
59
+ super().mousePressEvent(e)
60
+ self.setPressed(True)
61
+
62
+ def mouseReleaseEvent(self, e):
63
+ super().mouseReleaseEvent(e)
64
+ self.setPressed(False)
65
+
66
+ def setHover(self, isHover: bool):
67
+ self.isHover = isHover
68
+ self.update()
69
+
70
+ def setPressed(self, isPressed: bool):
71
+ self.isPressed = isPressed
72
+ self.update()
73
+
74
+ def __onClicked(self):
75
+ self.setExpand(self.angle < 180)
76
+
77
+ def setExpand(self, isExpand: bool):
78
+ self.rotateAni.stop()
79
+ self.rotateAni.setEndValue(180 if isExpand else 0)
80
+ self.rotateAni.setDuration(200)
81
+ self.rotateAni.start()
82
+
83
+ def getAngle(self):
84
+ return self.__angle
85
+
86
+ def setAngle(self, angle):
87
+ self.__angle = angle
88
+ self.update()
89
+
90
+ angle = Property(float, getAngle, setAngle)
91
+
92
+
93
+ class SpaceWidget(QWidget):
94
+ """ Spacing widget """
95
+
96
+ def __init__(self, parent=None):
97
+ super().__init__(parent=parent)
98
+ self.setAttribute(Qt.WA_TranslucentBackground)
99
+ self.setFixedHeight(1)
100
+
101
+
102
+ class HeaderSettingCard(SettingCard):
103
+ """ Header setting card """
104
+
105
+ def __init__(self, icon, title, content=None, parent=None):
106
+ super().__init__(icon, title, content, parent)
107
+ self.expandButton = ExpandButton(self)
108
+
109
+ self.hBoxLayout.addWidget(self.expandButton, 0, Qt.AlignRight)
110
+ self.hBoxLayout.addSpacing(8)
111
+
112
+ self.titleLabel.setObjectName("titleLabel")
113
+ self.installEventFilter(self)
114
+
115
+ def eventFilter(self, obj, e):
116
+ if obj is self:
117
+ if e.type() == QEvent.Enter:
118
+ self.expandButton.setHover(True)
119
+ elif e.type() == QEvent.Leave:
120
+ self.expandButton.setHover(False)
121
+ elif e.type() == QEvent.MouseButtonPress and e.button() == Qt.LeftButton:
122
+ self.expandButton.setPressed(True)
123
+ elif e.type() == QEvent.MouseButtonRelease and e.button() == Qt.LeftButton:
124
+ self.expandButton.setPressed(False)
125
+ self.expandButton.click()
126
+
127
+ return super().eventFilter(obj, e)
128
+
129
+ def addWidget(self, widget: QWidget):
130
+ """ add widget to tail """
131
+ N = self.hBoxLayout.count()
132
+ self.hBoxLayout.removeItem(self.hBoxLayout.itemAt(N - 1))
133
+ self.hBoxLayout.addWidget(widget, 0, Qt.AlignRight)
134
+ self.hBoxLayout.addSpacing(19)
135
+ self.hBoxLayout.addWidget(self.expandButton, 0, Qt.AlignRight)
136
+ self.hBoxLayout.addSpacing(8)
137
+
138
+ def paintEvent(self, e):
139
+ painter = QPainter(self)
140
+ painter.setRenderHints(QPainter.Antialiasing)
141
+ painter.setPen(Qt.NoPen)
142
+
143
+ if isDarkTheme():
144
+ painter.setBrush(QColor(255, 255, 255, 13))
145
+ else:
146
+ painter.setBrush(QColor(255, 255, 255, 170))
147
+
148
+ p = self.parent() # type: ExpandSettingCard
149
+ path = QPainterPath()
150
+ path.setFillRule(Qt.WindingFill)
151
+ path.addRoundedRect(QRectF(self.rect().adjusted(1, 1, -1, -1)), 6, 6)
152
+
153
+ # set the bottom border radius to 0 if parent is expanded
154
+ if p.isExpand:
155
+ path.addRect(1, self.height() - 8, self.width() - 2, 8)
156
+
157
+ painter.drawPath(path.simplified())
158
+
159
+
160
+ class ExpandBorderWidget(QWidget):
161
+ """ Expand setting card border widget """
162
+
163
+ def __init__(self, parent=None):
164
+ super().__init__(parent=parent)
165
+ self.setAttribute(Qt.WA_TransparentForMouseEvents)
166
+ parent.installEventFilter(self)
167
+
168
+ def eventFilter(self, obj, e):
169
+ if obj is self.parent() and e.type() == QEvent.Resize:
170
+ self.resize(e.size())
171
+
172
+ return super().eventFilter(obj, e)
173
+
174
+ def paintEvent(self, e):
175
+ painter = QPainter(self)
176
+ painter.setRenderHints(QPainter.Antialiasing)
177
+ painter.setBrush(Qt.NoBrush)
178
+
179
+ if isDarkTheme():
180
+ painter.setPen(QColor(0, 0, 0, 50))
181
+ else:
182
+ painter.setPen(QColor(0, 0, 0, 19))
183
+
184
+ p = self.parent() # type: ExpandSettingCard
185
+ r, d = 6, 12
186
+ ch, h, w = p.card.height(), self.height(), self.width()
187
+
188
+ # only draw rounded rect if parent is not expanded
189
+ painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), r, r)
190
+
191
+ # draw the seperator line under card widget
192
+ if ch < h:
193
+ painter.drawLine(1, ch, w - 1, ch)
194
+
195
+
196
+
197
+
198
+ class ExpandSettingCard(QScrollArea):
199
+ """ Expandable setting card """
200
+
201
+ def __init__(self, icon: Union[str, QIcon, FIF], title: str, content: str = None, parent=None):
202
+ super().__init__(parent=parent)
203
+ self.isExpand = False
204
+
205
+ self.scrollWidget = QFrame(self)
206
+ self.view = QFrame(self.scrollWidget)
207
+ self.card = HeaderSettingCard(icon, title, content, self)
208
+
209
+ self.scrollLayout = QVBoxLayout(self.scrollWidget)
210
+ self.viewLayout = QVBoxLayout(self.view)
211
+ self.spaceWidget = SpaceWidget(self.scrollWidget)
212
+ self.borderWidget = ExpandBorderWidget(self)
213
+
214
+ # expand animation
215
+ self.expandAni = QPropertyAnimation(self.verticalScrollBar(), b'value', self)
216
+
217
+ self.__initWidget()
218
+
219
+ def __initWidget(self):
220
+ """ initialize widgets """
221
+ self.setWidget(self.scrollWidget)
222
+ self.setWidgetResizable(True)
223
+ self.setFixedHeight(self.card.height())
224
+ self.setViewportMargins(0, self.card.height(), 0, 0)
225
+ self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
226
+ self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
227
+
228
+ # initialize layout
229
+ self.scrollLayout.setContentsMargins(0, 0, 0, 0)
230
+ self.scrollLayout.setSpacing(0)
231
+ self.scrollLayout.addWidget(self.view)
232
+ self.scrollLayout.addWidget(self.spaceWidget)
233
+
234
+ # initialize expand animation
235
+ self.expandAni.setEasingCurve(QEasingCurve.OutQuad)
236
+ self.expandAni.setDuration(200)
237
+
238
+ # initialize style sheet
239
+ self.view.setObjectName('view')
240
+ self.scrollWidget.setObjectName('scrollWidget')
241
+ self.setProperty('isExpand', False)
242
+ FluentStyleSheet.EXPAND_SETTING_CARD.apply(self.card)
243
+ FluentStyleSheet.EXPAND_SETTING_CARD.apply(self)
244
+
245
+ self.card.installEventFilter(self)
246
+ self.expandAni.valueChanged.connect(self._onExpandValueChanged)
247
+ self.card.expandButton.clicked.connect(self.toggleExpand)
248
+
249
+ def addWidget(self, widget: QWidget):
250
+ """ add widget to tail """
251
+ self.card.addWidget(widget)
252
+
253
+ def wheelEvent(self, e):
254
+ e.ignore()
255
+
256
+ def setExpand(self, isExpand: bool):
257
+ """ set the expand status of card """
258
+ if self.isExpand == isExpand:
259
+ return
260
+
261
+ # update style sheet
262
+ self.isExpand = isExpand
263
+ self.setProperty('isExpand', isExpand)
264
+ self.setStyle(QApplication.style())
265
+
266
+ # start expand animation
267
+ if isExpand:
268
+ h = self.viewLayout.sizeHint().height()
269
+ self.verticalScrollBar().setValue(h)
270
+ self.expandAni.setStartValue(h)
271
+ self.expandAni.setEndValue(0)
272
+ else:
273
+ self.expandAni.setStartValue(0)
274
+ self.expandAni.setEndValue(self.verticalScrollBar().maximum())
275
+
276
+ self.expandAni.start()
277
+ self.card.expandButton.setExpand(isExpand)
278
+
279
+ def toggleExpand(self):
280
+ """ toggle expand status """
281
+ self.setExpand(not self.isExpand)
282
+
283
+ def resizeEvent(self, e):
284
+ self.card.resize(self.width(), self.card.height())
285
+ self.scrollWidget.resize(self.width(), self.scrollWidget.height())
286
+
287
+ def _onExpandValueChanged(self):
288
+ vh = self.viewLayout.sizeHint().height()
289
+ h = self.viewportMargins().top()
290
+ self.setFixedHeight(max(h + vh - self.verticalScrollBar().value(), h))
291
+
292
+ def _adjustViewSize(self):
293
+ """ adjust view size """
294
+ h = self.viewLayout.sizeHint().height()
295
+ self.spaceWidget.setFixedHeight(h)
296
+
297
+ if self.isExpand:
298
+ self.setFixedHeight(self.card.height()+h)
299
+
300
+ def setValue(self, value):
301
+ """ set the value of config item """
302
+ pass
303
+
304
+
305
+
306
+ class GroupSeparator(QWidget):
307
+ """ group separator """
308
+
309
+ def __init__(self, parent=None):
310
+ super().__init__(parent=parent)
311
+ self.setFixedHeight(3)
312
+
313
+ def paintEvent(self, e):
314
+ painter = QPainter(self)
315
+ painter.setRenderHints(QPainter.Antialiasing)
316
+
317
+ if isDarkTheme():
318
+ painter.setPen(QColor(0, 0, 0, 50))
319
+ else:
320
+ painter.setPen(QColor(0, 0, 0, 19))
321
+
322
+ painter.drawLine(0, 1, self.width(), 1)
323
+
324
+
325
+ class ExpandGroupSettingCard(ExpandSettingCard):
326
+ """ Expand group setting card """
327
+
328
+ def __init__(self, icon: Union[str, QIcon, FIF], title: str, content: str = None, parent=None):
329
+ super().__init__(icon, title, content, parent)
330
+ self.widgets = [] # type: List[QWidget]
331
+
332
+ self.viewLayout.setContentsMargins(0, 0, 0, 0)
333
+ self.viewLayout.setSpacing(0)
334
+
335
+ def addGroupWidget(self, widget: QWidget):
336
+ """ add widget to group """
337
+ # add separator
338
+ if self.viewLayout.count() >= 1:
339
+ self.viewLayout.addWidget(GroupSeparator(self.view))
340
+
341
+ widget.setParent(self.view)
342
+ self.widgets.append(widget)
343
+ self.viewLayout.addWidget(widget)
344
+ self._adjustViewSize()
345
+
346
+ def removeGroupWidget(self, widget: QWidget):
347
+ """ remove a group from card """
348
+ if widget not in self.widgets:
349
+ return
350
+
351
+ layoutIndex = self.viewLayout.indexOf(widget)
352
+ index = self.widgets.index(widget)
353
+
354
+ self.viewLayout.removeWidget(widget)
355
+ self.widgets.remove(widget)
356
+
357
+ if not self.widgets:
358
+ return self._adjustViewSize()
359
+
360
+ # remove separator
361
+ if layoutIndex >= 1:
362
+ separator = self.viewLayout.itemAt(layoutIndex - 1).widget()
363
+ separator.deleteLater()
364
+ self.viewLayout.removeWidget(separator)
365
+ elif index == 0:
366
+ separator = self.viewLayout.itemAt(0).widget()
367
+ separator.deleteLater()
368
+ self.viewLayout.removeWidget(separator)
369
+
370
+ self._adjustViewSize()
371
+
372
+ def _adjustViewSize(self):
373
+ """ adjust view size """
374
+ h = sum(w.sizeHint().height() + 3 for w in self.widgets)
375
+ self.spaceWidget.setFixedHeight(h)
376
+
377
+ if self.isExpand:
378
+ self.setFixedHeight(self.card.height()+h)
379
+
380
+
381
+ class SimpleExpandGroupSettingCard(ExpandGroupSettingCard):
382
+ """ Simple expand group setting card """
383
+
384
+ def _adjustViewSize(self):
385
+ """ adjust view size """
386
+ h = self.viewLayout.sizeHint().height()
387
+ self.spaceWidget.setFixedHeight(h)
388
+
389
+ if self.isExpand:
390
+ self.setFixedHeight(self.card.height()+h)
@@ -0,0 +1,134 @@
1
+ # coding:utf-8
2
+ from typing import List
3
+ from pathlib import Path
4
+
5
+ from PySide6.QtCore import Qt, Signal, QSize
6
+ from PySide6.QtGui import QPainter, QIcon
7
+ from PySide6.QtWidgets import (QPushButton, QFileDialog, QWidget, QLabel,
8
+ QHBoxLayout, QToolButton, QSizePolicy)
9
+
10
+ from ...components.widgets.button import ToolButton, PushButton
11
+ from ...common.config import ConfigItem, qconfig
12
+ from ...common.icon import drawIcon
13
+ from ...common.icon import FluentIcon as FIF
14
+ from ..dialog_box.dialog import Dialog
15
+ from .expand_setting_card import ExpandSettingCard
16
+
17
+
18
+
19
+ class FolderItem(QWidget):
20
+ """ Folder item """
21
+
22
+ removed = Signal(QWidget)
23
+
24
+ def __init__(self, folder: str, parent=None):
25
+ super().__init__(parent=parent)
26
+ self.folder = folder
27
+ self.hBoxLayout = QHBoxLayout(self)
28
+ self.folderLabel = QLabel(folder, self)
29
+ self.removeButton = ToolButton(FIF.CLOSE, self)
30
+
31
+ self.removeButton.setFixedSize(39, 29)
32
+ self.removeButton.setIconSize(QSize(12, 12))
33
+
34
+ self.setFixedHeight(53)
35
+ self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
36
+ self.hBoxLayout.setContentsMargins(48, 0, 60, 0)
37
+ self.hBoxLayout.addWidget(self.folderLabel, 0, Qt.AlignLeft)
38
+ self.hBoxLayout.addSpacing(16)
39
+ self.hBoxLayout.addStretch(1)
40
+ self.hBoxLayout.addWidget(self.removeButton, 0, Qt.AlignRight)
41
+ self.hBoxLayout.setAlignment(Qt.AlignVCenter)
42
+
43
+ self.removeButton.clicked.connect(
44
+ lambda: self.removed.emit(self))
45
+
46
+
47
+ class FolderListSettingCard(ExpandSettingCard):
48
+ """ Folder list setting card """
49
+
50
+ folderChanged = Signal(list)
51
+
52
+ def __init__(self, configItem: ConfigItem, title: str, content: str = None, directory="./", parent=None):
53
+ """
54
+ Parameters
55
+ ----------
56
+ configItem: RangeConfigItem
57
+ configuration item operated by the card
58
+
59
+ title: str
60
+ the title of card
61
+
62
+ content: str
63
+ the content of card
64
+
65
+ directory: str
66
+ working directory of file dialog
67
+
68
+ parent: QWidget
69
+ parent widget
70
+ """
71
+ super().__init__(FIF.FOLDER, title, content, parent)
72
+ self.configItem = configItem
73
+ self._dialogDirectory = directory
74
+ self.addFolderButton = PushButton(self.tr('Add folder'), self, FIF.FOLDER_ADD)
75
+
76
+ self.folders = qconfig.get(configItem).copy() # type:List[str]
77
+ self.__initWidget()
78
+
79
+ def __initWidget(self):
80
+ self.addWidget(self.addFolderButton)
81
+
82
+ # initialize layout
83
+ self.viewLayout.setSpacing(0)
84
+ self.viewLayout.setAlignment(Qt.AlignTop)
85
+ self.viewLayout.setContentsMargins(0, 0, 0, 0)
86
+ for folder in self.folders:
87
+ self.__addFolderItem(folder)
88
+
89
+ self.addFolderButton.clicked.connect(self.__showFolderDialog)
90
+
91
+ def __showFolderDialog(self):
92
+ """ show folder dialog """
93
+ folder = QFileDialog.getExistingDirectory(
94
+ self, self.tr("Choose folder"), self._dialogDirectory)
95
+
96
+ if not folder or folder in self.folders:
97
+ return
98
+
99
+ self.__addFolderItem(folder)
100
+ self.folders.append(folder)
101
+ qconfig.set(self.configItem, self.folders)
102
+ self.folderChanged.emit(self.folders)
103
+
104
+ def __addFolderItem(self, folder: str):
105
+ """ add folder item """
106
+ item = FolderItem(folder, self.view)
107
+ item.removed.connect(self.__showConfirmDialog)
108
+ self.viewLayout.addWidget(item)
109
+ item.show()
110
+ self._adjustViewSize()
111
+
112
+ def __showConfirmDialog(self, item: FolderItem):
113
+ """ show confirm dialog """
114
+ name = Path(item.folder).name
115
+ title = self.tr('Are you sure you want to delete the folder?')
116
+ content = self.tr("If you delete the ") + f'"{name}"' + \
117
+ self.tr(" folder and remove it from the list, the folder will no "
118
+ "longer appear in the list, but will not be deleted.")
119
+ w = Dialog(title, content, self.window())
120
+ w.yesSignal.connect(lambda: self.__removeFolder(item))
121
+ w.exec_()
122
+
123
+ def __removeFolder(self, item: FolderItem):
124
+ """ remove folder """
125
+ if item.folder not in self.folders:
126
+ return
127
+
128
+ self.folders.remove(item.folder)
129
+ self.viewLayout.removeWidget(item)
130
+ item.deleteLater()
131
+ self._adjustViewSize()
132
+
133
+ self.folderChanged.emit(self.folders)
134
+ qconfig.set(self.configItem, self.folders)
@@ -0,0 +1,86 @@
1
+ # coding:utf-8
2
+ from typing import Union
3
+ from PySide6.QtCore import Signal
4
+ from PySide6.QtGui import QIcon
5
+ from PySide6.QtWidgets import QButtonGroup, QLabel
6
+
7
+ from ...common.config import OptionsConfigItem, qconfig
8
+ from ...common.icon import FluentIconBase
9
+ from ..widgets.button import RadioButton
10
+ from .expand_setting_card import ExpandSettingCard
11
+
12
+
13
+ class OptionsSettingCard(ExpandSettingCard):
14
+ """ setting card with a group of options """
15
+
16
+ optionChanged = Signal(OptionsConfigItem)
17
+
18
+ def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, texts=None, parent=None):
19
+ """
20
+ Parameters
21
+ ----------
22
+ configItem: OptionsConfigItem
23
+ options config item
24
+
25
+ icon: str | QIcon | FluentIconBase
26
+ the icon to be drawn
27
+
28
+ title: str
29
+ the title of setting card
30
+
31
+ content: str
32
+ the content of setting card
33
+
34
+ texts: List[str]
35
+ the texts of radio buttons
36
+
37
+ parent: QWidget
38
+ parent window
39
+ """
40
+ super().__init__(icon, title, content, parent)
41
+ self.texts = texts or []
42
+ self.configItem = configItem
43
+ self.configName = configItem.name
44
+ self.choiceLabel = QLabel(self)
45
+ self.buttonGroup = QButtonGroup(self)
46
+
47
+ self.choiceLabel.setObjectName("titleLabel")
48
+ self.addWidget(self.choiceLabel)
49
+
50
+ # create buttons
51
+ self.viewLayout.setSpacing(19)
52
+ self.viewLayout.setContentsMargins(48, 18, 0, 18)
53
+ for text, option in zip(texts, configItem.options):
54
+ button = RadioButton(text, self.view)
55
+ self.buttonGroup.addButton(button)
56
+ self.viewLayout.addWidget(button)
57
+ button.setProperty(self.configName, option)
58
+
59
+ self._adjustViewSize()
60
+ self.setValue(qconfig.get(self.configItem))
61
+ configItem.valueChanged.connect(self.setValue)
62
+ self.buttonGroup.buttonClicked.connect(self.__onButtonClicked)
63
+
64
+ def __onButtonClicked(self, button: RadioButton):
65
+ """ button clicked slot """
66
+ if button.text() == self.choiceLabel.text():
67
+ return
68
+
69
+ value = button.property(self.configName)
70
+ qconfig.set(self.configItem, value)
71
+
72
+ self.choiceLabel.setText(button.text())
73
+ self.choiceLabel.adjustSize()
74
+ self.optionChanged.emit(self.configItem)
75
+
76
+ def setValue(self, value):
77
+ """ select button according to the value """
78
+ qconfig.set(self.configItem, value)
79
+
80
+ for button in self.buttonGroup.buttons():
81
+ isChecked = button.property(self.configName) == value
82
+ button.setChecked(isChecked)
83
+
84
+ if isChecked:
85
+ self.choiceLabel.setText(button.text())
86
+ self.choiceLabel.adjustSize()