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,65 @@
1
+ # coding:utf-8
2
+ from PySide6.QtCore import Signal
3
+ from PySide6.QtWidgets import QLabel, QPushButton, QDialog
4
+
5
+ from ...common.auto_wrap import TextWrap
6
+ from ...common.style_sheet import FluentStyleSheet
7
+ from .mask_dialog_base import MaskDialogBase
8
+
9
+
10
+ class MessageDialog(MaskDialogBase):
11
+ """ Win10 style message dialog box with a mask """
12
+
13
+ yesSignal = Signal()
14
+ cancelSignal = Signal()
15
+
16
+ def __init__(self, title: str, content: str, parent):
17
+ super().__init__(parent=parent)
18
+ self.content = content
19
+ self.titleLabel = QLabel(title, self.widget)
20
+ self.contentLabel = QLabel(content, self.widget)
21
+ self.yesButton = QPushButton(self.tr('OK'), self.widget)
22
+ self.cancelButton = QPushButton(self.tr('Cancel'), self.widget)
23
+ self.__initWidget()
24
+
25
+ def __initWidget(self):
26
+ """ initialize widgets """
27
+ self.windowMask.resize(self.size())
28
+ self.widget.setMaximumWidth(540)
29
+ self.titleLabel.move(24, 24)
30
+ self.contentLabel.move(24, 56)
31
+ self.contentLabel.setText(TextWrap.wrap(self.content, 71)[0])
32
+
33
+ self.__setQss()
34
+ self.__initLayout()
35
+
36
+ # connect signal to slot
37
+ self.yesButton.clicked.connect(self.__onYesButtonClicked)
38
+ self.cancelButton.clicked.connect(self.__onCancelButtonClicked)
39
+
40
+ def __initLayout(self):
41
+ """ initialize layout """
42
+ self.contentLabel.adjustSize()
43
+ self.widget.setFixedSize(48+self.contentLabel.width(),
44
+ self.contentLabel.y() + self.contentLabel.height()+92)
45
+ self.yesButton.resize((self.widget.width() - 54) // 2, 32)
46
+ self.cancelButton.resize(self.yesButton.width(), 32)
47
+ self.yesButton.move(24, self.widget.height()-56)
48
+ self.cancelButton.move(
49
+ self.widget.width()-24-self.cancelButton.width(), self.widget.height()-56)
50
+
51
+ def __onCancelButtonClicked(self):
52
+ self.cancelSignal.emit()
53
+ self.reject()
54
+
55
+ def __onYesButtonClicked(self):
56
+ self.setEnabled(False)
57
+ self.yesSignal.emit()
58
+ self.accept()
59
+
60
+ def __setQss(self):
61
+ """ set style sheet """
62
+ self.windowMask.setObjectName('windowMask')
63
+ self.titleLabel.setObjectName('titleLabel')
64
+ self.contentLabel.setObjectName('contentLabel')
65
+ FluentStyleSheet.MESSAGE_DIALOG.apply(self)
@@ -0,0 +1,3 @@
1
+ from .expand_layout import ExpandLayout
2
+ from .flow_layout import FlowLayout
3
+ from .v_box_layout import VBoxLayout
@@ -0,0 +1,96 @@
1
+ # coding:utf-8
2
+ from PySide6.QtCore import QSize, QPoint, Qt, QEvent, QRect
3
+ from PySide6.QtGui import QResizeEvent
4
+ from PySide6.QtWidgets import QLayout, QWidget
5
+
6
+
7
+ class ExpandLayout(QLayout):
8
+ """ Expand layout """
9
+
10
+ def __init__(self, parent=None):
11
+ super().__init__(parent)
12
+ self.__items = []
13
+ self.__widgets = []
14
+
15
+ def addWidget(self, widget: QWidget):
16
+ if widget in self.__widgets:
17
+ return
18
+
19
+ self.__widgets.append(widget)
20
+ widget.installEventFilter(self)
21
+
22
+ def addItem(self, item):
23
+ self.__items.append(item)
24
+
25
+ def count(self):
26
+ return len(self.__items)
27
+
28
+ def itemAt(self, index):
29
+ if 0 <= index < len(self.__items):
30
+ return self.__items[index]
31
+
32
+ return None
33
+
34
+ def takeAt(self, index):
35
+ if 0 <= index < len(self.__items):
36
+ self.__widgets.pop(index)
37
+ return self.__items.pop(index)
38
+
39
+ return None
40
+
41
+ def expandingDirections(self):
42
+ return Qt.Vertical
43
+
44
+ def hasHeightForWidth(self):
45
+ return True
46
+
47
+ def heightForWidth(self, width):
48
+ """ get the minimal height according to width """
49
+ return self.__doLayout(QRect(0, 0, width, 0), False)
50
+
51
+ def setGeometry(self, rect):
52
+ super().setGeometry(rect)
53
+ self.__doLayout(rect, True)
54
+
55
+ def sizeHint(self):
56
+ return self.minimumSize()
57
+
58
+ def minimumSize(self):
59
+ size = QSize()
60
+
61
+ for w in self.__widgets:
62
+ size = size.expandedTo(w.minimumSize())
63
+
64
+ m = self.contentsMargins()
65
+ size += QSize(m.left()+m.right(), m.top()+m.bottom())
66
+
67
+ return size
68
+
69
+ def __doLayout(self, rect, move):
70
+ """ adjust widgets position according to the window size """
71
+ margin = self.contentsMargins()
72
+ x = rect.x() + margin.left()
73
+ y = rect.y() + margin.top()
74
+ width = rect.width() - margin.left() - margin.right()
75
+
76
+ for i, w in enumerate(self.__widgets):
77
+ if w.isHidden():
78
+ continue
79
+
80
+ y += (i>0)*self.spacing()
81
+ if move:
82
+ w.setGeometry(QRect(QPoint(x, y), QSize(width, w.height())))
83
+
84
+ y += w.height()
85
+
86
+ return y - rect.y()
87
+
88
+ def eventFilter(self, obj, e):
89
+ if obj in self.__widgets:
90
+ if e.type() == QEvent.Resize:
91
+ ds = e.size() - e.oldSize() # type:QSize
92
+ if ds.height() != 0 and ds.width() == 0:
93
+ w = self.parentWidget()
94
+ w.resize(w.width(), w.height() + ds.height())
95
+
96
+ return super().eventFilter(obj, e)
@@ -0,0 +1,236 @@
1
+ # coding:utf-8
2
+ from typing import List
3
+
4
+ from PySide6.QtCore import QSize, QPoint, Qt, QRect, QPropertyAnimation, QParallelAnimationGroup, QEasingCurve, QEvent, QTimer, QObject
5
+ from PySide6.QtWidgets import QLayout, QWidgetItem, QLayoutItem
6
+
7
+
8
+ class FlowLayout(QLayout):
9
+ """ Flow layout """
10
+
11
+ def __init__(self, parent=None, needAni=False, isTight=False):
12
+ """
13
+ Parameters
14
+ ----------
15
+ parent:
16
+ parent window or layout
17
+
18
+ needAni: bool
19
+ whether to add moving animation
20
+
21
+ isTight: bool
22
+ whether to use the tight layout when widgets are hidden
23
+ """
24
+ super().__init__(parent)
25
+ self._items = [] # type: List[QLayoutItem]
26
+ self._anis = [] # type: List[QPropertyAnimation]
27
+ self._aniGroup = QParallelAnimationGroup(self)
28
+ self._verticalSpacing = 10
29
+ self._horizontalSpacing = 10
30
+ self.duration = 300
31
+ self.ease = QEasingCurve.Linear
32
+ self.needAni = needAni
33
+ self.isTight = isTight
34
+ self._deBounceTimer = QTimer(self)
35
+ self._deBounceTimer.setSingleShot(True)
36
+ self._deBounceTimer.timeout.connect(lambda: self._doLayout(self.geometry(), True))
37
+ self._wParent = None
38
+ self._isInstalledEventFilter = False
39
+
40
+ def addItem(self, item):
41
+ self._items.append(item)
42
+
43
+ def insertItem(self, index, item):
44
+ self._items.insert(index, item)
45
+
46
+ def addWidget(self, w):
47
+ super().addWidget(w)
48
+ self._onWidgetAdded(w)
49
+
50
+ def insertWidget(self, index, w):
51
+ self.insertItem(index, QWidgetItem(w))
52
+ self.addChildWidget(w)
53
+ self._onWidgetAdded(w, index)
54
+
55
+ def _onWidgetAdded(self, w, index=-1):
56
+ if not self._isInstalledEventFilter:
57
+ if w.parent():
58
+ self._wParent = w.parent()
59
+ w.parent().installEventFilter(self)
60
+ else:
61
+ w.installEventFilter(self)
62
+
63
+ if not self.needAni:
64
+ return
65
+
66
+ ani = QPropertyAnimation(w, b'geometry')
67
+ ani.setEndValue(QRect(QPoint(0, 0), w.size()))
68
+ ani.setDuration(self.duration)
69
+ ani.setEasingCurve(self.ease)
70
+ w.setProperty('flowAni', ani)
71
+ self._aniGroup.addAnimation(ani)
72
+
73
+ if index == -1:
74
+ self._anis.append(ani)
75
+ else:
76
+ self._anis.insert(index, ani)
77
+
78
+ def setAnimation(self, duration, ease=QEasingCurve.Linear):
79
+ """ set the moving animation
80
+
81
+ Parameters
82
+ ----------
83
+ duration: int
84
+ the duration of animation in milliseconds
85
+
86
+ ease: QEasingCurve
87
+ the easing curve of animation
88
+ """
89
+ if not self.needAni:
90
+ return
91
+
92
+ self.duration = duration
93
+ self.ease = ease
94
+
95
+ for ani in self._anis:
96
+ ani.setDuration(duration)
97
+ ani.setEasingCurve(ease)
98
+
99
+ def count(self):
100
+ return len(self._items)
101
+
102
+ def itemAt(self, index: int):
103
+ if 0 <= index < len(self._items):
104
+ return self._items[index]
105
+
106
+ return None
107
+
108
+ def takeAt(self, index: int):
109
+ if 0 <= index < len(self._items):
110
+ item = self._items[index] # type: QLayoutItem
111
+ ani = item.widget().property('flowAni')
112
+ if ani:
113
+ self._anis.remove(ani)
114
+ self._aniGroup.removeAnimation(ani)
115
+ ani.deleteLater()
116
+
117
+ return self._items.pop(index).widget()
118
+
119
+ return None
120
+
121
+ def removeWidget(self, widget):
122
+ for i, item in enumerate(self._items):
123
+ if item.widget() is widget:
124
+ return self.takeAt(i)
125
+
126
+ def removeAllWidgets(self):
127
+ """ remove all widgets from layout """
128
+ while self._items:
129
+ self.takeAt(0)
130
+
131
+ def takeAllWidgets(self):
132
+ """ remove all widgets from layout and delete them """
133
+ while self._items:
134
+ w = self.takeAt(0)
135
+ if w:
136
+ w.deleteLater()
137
+
138
+ def expandingDirections(self):
139
+ return Qt.Orientation(0)
140
+
141
+ def hasHeightForWidth(self):
142
+ return True
143
+
144
+ def heightForWidth(self, width: int):
145
+ """ get the minimal height according to width """
146
+ return self._doLayout(QRect(0, 0, width, 0), False)
147
+
148
+ def setGeometry(self, rect: QRect):
149
+ super().setGeometry(rect)
150
+
151
+ if self.needAni:
152
+ self._deBounceTimer.start(80)
153
+ else:
154
+ self._doLayout(rect, True)
155
+
156
+ def sizeHint(self):
157
+ return self.minimumSize()
158
+
159
+ def minimumSize(self):
160
+ size = QSize()
161
+
162
+ for item in self._items:
163
+ size = size.expandedTo(item.minimumSize())
164
+
165
+ m = self.contentsMargins()
166
+ size += QSize(m.left()+m.right(), m.top()+m.bottom())
167
+
168
+ return size
169
+
170
+ def setVerticalSpacing(self, spacing: int):
171
+ """ set vertical spacing between widgets """
172
+ self._verticalSpacing = spacing
173
+
174
+ def verticalSpacing(self):
175
+ """ get vertical spacing between widgets """
176
+ return self._verticalSpacing
177
+
178
+ def setHorizontalSpacing(self, spacing: int):
179
+ """ set horizontal spacing between widgets """
180
+ self._horizontalSpacing = spacing
181
+
182
+ def horizontalSpacing(self):
183
+ """ get horizontal spacing between widgets """
184
+ return self._horizontalSpacing
185
+
186
+ def eventFilter(self, obj: QObject, event: QEvent) -> bool:
187
+ if obj in [w.widget() for w in self._items] and event.type() == QEvent.Type.ParentChange:
188
+ self._wParent = obj.parent()
189
+ obj.parent().installEventFilter(self)
190
+ self._isInstalledEventFilter = True
191
+
192
+ if obj == self._wParent and event.type() == QEvent.Type.Show:
193
+ self._doLayout(self.geometry(), True)
194
+ self._isInstalledEventFilter = True
195
+
196
+ return super().eventFilter(obj, event)
197
+
198
+ def _doLayout(self, rect: QRect, move: bool):
199
+ """ adjust widgets position according to the window size """
200
+ aniRestart = False
201
+ margin = self.contentsMargins()
202
+ x = rect.x() + margin.left()
203
+ y = rect.y() + margin.top()
204
+ rowHeight = 0
205
+ spaceX = self.horizontalSpacing()
206
+ spaceY = self.verticalSpacing()
207
+
208
+ for i, item in enumerate(self._items):
209
+ if item.widget() and not item.widget().isVisible() and self.isTight:
210
+ continue
211
+
212
+ nextX = x + item.sizeHint().width() + spaceX
213
+
214
+ if nextX - spaceX > rect.right() - margin.right() and rowHeight > 0:
215
+ x = rect.x() + margin.left()
216
+ y = y + rowHeight + spaceY
217
+ nextX = x + item.sizeHint().width() + spaceX
218
+ rowHeight = 0
219
+
220
+ if move:
221
+ target = QRect(QPoint(x, y), item.sizeHint())
222
+ if not self.needAni:
223
+ item.setGeometry(target)
224
+ elif target != self._anis[i].endValue():
225
+ self._anis[i].stop()
226
+ self._anis[i].setEndValue(target)
227
+ aniRestart = True
228
+
229
+ x = nextX
230
+ rowHeight = max(rowHeight, item.sizeHint().height())
231
+
232
+ if self.needAni and aniRestart:
233
+ self._aniGroup.stop()
234
+ self._aniGroup.start()
235
+
236
+ return y + rowHeight + margin.bottom() - rect.y()
@@ -0,0 +1,41 @@
1
+ # coding:utf-8
2
+ from typing import List
3
+ from PySide6.QtCore import Qt
4
+ from PySide6.QtWidgets import QVBoxLayout, QWidget
5
+
6
+
7
+ class VBoxLayout(QVBoxLayout):
8
+ """ Vertical box layout """
9
+
10
+ def __init__(self, parent):
11
+ super().__init__(parent)
12
+ self.widgets = []
13
+
14
+ def addWidgets(self, widgets: List[QWidget], stretch=0, alignment=Qt.AlignTop):
15
+ """ add widgets to layout """
16
+ for widget in widgets:
17
+ self.addWidget(widget, stretch, alignment)
18
+
19
+ def addWidget(self, widget: QWidget, stretch=0, alignment=Qt.AlignTop):
20
+ """ add widget to layout """
21
+ super().addWidget(widget, stretch, alignment)
22
+ self.widgets.append(widget)
23
+ widget.show()
24
+
25
+ def removeWidget(self, widget: QWidget):
26
+ """ remove widget from layout but not delete it """
27
+ super().removeWidget(widget)
28
+ self.widgets.remove(widget)
29
+
30
+ def deleteWidget(self, widget: QWidget):
31
+ """ remove widget from layout and delete it """
32
+ self.removeWidget(widget)
33
+ widget.hide()
34
+ widget.deleteLater()
35
+
36
+ def removeAllWidget(self):
37
+ """ remove all widgets from layout """
38
+ for widget in self.widgets:
39
+ super().removeWidget(widget)
40
+
41
+ self.widgets.clear()
@@ -0,0 +1,6 @@
1
+ from .acrylic_menu import AcrylicMenu, AcrylicLineEditMenu, AcrylicCheckableMenu, AcrylicCheckableSystemTrayMenu, AcrylicSystemTrayMenu
2
+ from .acrylic_line_edit import AcrylicLineEditBase, AcrylicLineEdit, AcrylicSearchLineEdit
3
+ from .acrylic_combo_box import AcrylicComboBox, AcrylicComboBoxSettingCard, AcrylicEditableComboBox
4
+ from .acrylic_widget import AcrylicWidget, AcrylicBrush
5
+ from .acrylic_flyout import AcrylicFlyoutView, AcrylicFlyoutViewBase, AcrylicFlyout
6
+ from .acrylic_tool_tip import AcrylicToolTip, AcrylicToolTipFilter
@@ -0,0 +1,96 @@
1
+ # coding:utf-8
2
+ from PySide6.QtCore import Qt, QPoint
3
+ from PySide6.QtGui import QAction
4
+
5
+
6
+ from .acrylic_menu import AcrylicMenuBase, AcrylicMenuActionListWidget
7
+ from .acrylic_line_edit import AcrylicLineEditBase
8
+ from ..widgets.combo_box import ComboBoxMenu, ComboBox, EditableComboBox
9
+ from ..widgets.menu import MenuAnimationType, RoundMenu, IndicatorMenuItemDelegate
10
+ from ..settings import SettingCard
11
+ from ...common.config import OptionsConfigItem, qconfig
12
+
13
+
14
+ class AcrylicComboMenuActionListWidget(AcrylicMenuActionListWidget):
15
+
16
+ def _topMargin(self):
17
+ return 2
18
+
19
+
20
+ class AcrylicComboBoxMenu(AcrylicMenuBase, RoundMenu):
21
+
22
+ def __init__(self, parent=None):
23
+ super().__init__(parent=parent)
24
+ self.setUpMenu(AcrylicComboMenuActionListWidget(self))
25
+
26
+ self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
27
+ self.view.setItemDelegate(IndicatorMenuItemDelegate())
28
+ self.view.setObjectName('comboListWidget')
29
+ self.setItemHeight(33)
30
+
31
+ def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
32
+ return super().exec(pos, ani, aniType)
33
+
34
+
35
+ class AcrylicComboBox(ComboBox):
36
+ """ Acrylic combo box """
37
+
38
+ def _createComboMenu(self):
39
+ return AcrylicComboBoxMenu(self)
40
+
41
+
42
+ class AcrylicEditableComboBox(AcrylicLineEditBase, EditableComboBox):
43
+ """ Acrylic combo box """
44
+
45
+ def _createComboMenu(self):
46
+ return AcrylicComboBoxMenu(self)
47
+
48
+
49
+ class AcrylicComboBoxSettingCard(SettingCard):
50
+ """ Setting card with a combo box """
51
+
52
+ def __init__(self, configItem: OptionsConfigItem, icon, title, content=None, texts=None, parent=None):
53
+ """
54
+ Parameters
55
+ ----------
56
+ configItem: OptionsConfigItem
57
+ configuration item operated by the card
58
+
59
+ icon: str | QIcon | FluentIconBase
60
+ the icon to be drawn
61
+
62
+ title: str
63
+ the title of card
64
+
65
+ content: str
66
+ the content of card
67
+
68
+ texts: List[str]
69
+ the text of items
70
+
71
+ parent: QWidget
72
+ parent widget
73
+ """
74
+ super().__init__(icon, title, content, parent)
75
+ self.configItem = configItem
76
+ self.comboBox = AcrylicComboBox(self)
77
+ self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
78
+ self.hBoxLayout.addSpacing(16)
79
+
80
+ self.optionToText = {o: t for o, t in zip(configItem.options, texts)}
81
+ for text, option in zip(texts, configItem.options):
82
+ self.comboBox.addItem(text, userData=option)
83
+
84
+ self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
85
+ self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
86
+ configItem.valueChanged.connect(self.setValue)
87
+
88
+ def _onCurrentIndexChanged(self, index: int):
89
+ qconfig.set(self.configItem, self.comboBox.itemData(index))
90
+
91
+ def setValue(self, value):
92
+ if value not in self.optionToText:
93
+ return
94
+
95
+ self.comboBox.setCurrentText(self.optionToText[value])
96
+ qconfig.set(self.configItem, value)
@@ -0,0 +1,105 @@
1
+ # coding:utf-8
2
+ from typing import Union
3
+ from PySide6.QtCore import QPoint, Qt, QRect, QRectF
4
+ from PySide6.QtGui import QPixmap, QPainter, QColor, QPainterPath, QIcon, QImage
5
+ from PySide6.QtWidgets import QWidget
6
+
7
+ from ...common.style_sheet import isDarkTheme
8
+ from ...common.icon import FluentIconBase
9
+ from ..widgets.flyout import FlyoutAnimationType, FlyoutViewBase, FlyoutView, Flyout, FlyoutAnimationManager
10
+ from .acrylic_widget import AcrylicWidget
11
+
12
+
13
+ class AcrylicFlyoutViewBase(AcrylicWidget, FlyoutViewBase):
14
+ """ Acrylic flyout view base """
15
+
16
+ def acrylicClipPath(self):
17
+ path = QPainterPath()
18
+ path.addRoundedRect(QRectF(self.rect().adjusted(1, 1, -1, -1)), 8, 8)
19
+ return path
20
+
21
+ def paintEvent(self, e):
22
+ painter = QPainter(self)
23
+ painter.setRenderHints(QPainter.Antialiasing)
24
+ self._drawAcrylic(painter)
25
+
26
+ # draw border
27
+ painter.setBrush(Qt.NoBrush)
28
+ painter.setPen(self.borderColor())
29
+ rect = QRectF(self.rect()).adjusted(1, 1, -1, -1)
30
+ painter.drawRoundedRect(rect, 8, 8)
31
+
32
+
33
+ class AcrylicFlyoutView(AcrylicWidget, FlyoutView):
34
+ """ Acrylic flyout view """
35
+
36
+ def acrylicClipPath(self):
37
+ path = QPainterPath()
38
+ path.addRoundedRect(QRectF(self.rect().adjusted(1, 1, -1, -1)), 8, 8)
39
+ return path
40
+
41
+ def paintEvent(self, e):
42
+ painter = QPainter(self)
43
+ painter.setRenderHints(QPainter.Antialiasing)
44
+ self._drawAcrylic(painter)
45
+
46
+ # draw border
47
+ painter.setBrush(Qt.NoBrush)
48
+ painter.setPen(self.borderColor())
49
+ rect = self.rect().adjusted(1, 1, -1, -1)
50
+ painter.drawRoundedRect(rect, 8, 8)
51
+
52
+
53
+ class AcrylicFlyout(Flyout):
54
+ """ Acrylic flyout """
55
+
56
+ @classmethod
57
+ def create(cls, title: str, content: str, icon: Union[FluentIconBase, QIcon, str] = None,
58
+ image: Union[str, QPixmap, QImage] = None, isClosable=False, target: Union[QWidget, QPoint] = None,
59
+ parent=None, aniType=FlyoutAnimationType.PULL_UP, isDeleteOnClose=True):
60
+ """ create and show a flyout using the default view
61
+
62
+ Parameters
63
+ ----------
64
+ title: str
65
+ the title of teaching tip
66
+
67
+ content: str
68
+ the content of teaching tip
69
+
70
+ icon: InfoBarIcon | FluentIconBase | QIcon | str
71
+ the icon of teaching tip
72
+
73
+ image: str | QPixmap | QImage
74
+ the image of teaching tip
75
+
76
+ isClosable: bool
77
+ whether to show the close button
78
+
79
+ target: QWidget | QPoint
80
+ the target widget or position to show flyout
81
+
82
+ parent: QWidget
83
+ parent window
84
+
85
+ aniType: FlyoutAnimationType
86
+ flyout animation type
87
+
88
+ isDeleteOnClose: bool
89
+ whether delete flyout automatically when flyout is closed
90
+ """
91
+ view = AcrylicFlyoutView(title, content, icon, image, isClosable)
92
+ w = cls.make(view, target, parent, aniType, isDeleteOnClose)
93
+ view.closed.connect(w.close)
94
+ return w
95
+
96
+ def exec(self, pos: QPoint, aniType=FlyoutAnimationType.PULL_UP):
97
+ """ show calendar view """
98
+ self.aniManager = FlyoutAnimationManager.make(aniType, self)
99
+
100
+ if isinstance(self.view, AcrylicWidget):
101
+ pos = self.aniManager._adjustPosition(pos)
102
+ self.view.acrylicBrush.grabImage(QRect(pos, self.layout().sizeHint()))
103
+
104
+ self.show()
105
+ self.aniManager.exec(pos)
@@ -0,0 +1,27 @@
1
+ # coding:utf-8
2
+ from .acrylic_menu import AcrylicCompleterMenu, AcrylicLineEditMenu
3
+ from ..widgets.line_edit import LineEdit, SearchLineEdit
4
+
5
+
6
+ class AcrylicLineEditBase:
7
+ """ Acrylic line edit base """
8
+
9
+ def __init__(self, *args, **kwargs) -> None:
10
+ super().__init__(*args, **kwargs)
11
+
12
+ def setCompleter(self, completer):
13
+ super().setCompleter(completer)
14
+ self.setCompleterMenu(AcrylicCompleterMenu(self))
15
+
16
+ def contextMenuEvent(self, e):
17
+ menu = AcrylicLineEditMenu(self)
18
+ menu.exec(e.globalPos())
19
+
20
+
21
+
22
+ class AcrylicLineEdit(AcrylicLineEditBase, LineEdit):
23
+ """ Acrylic line edit """
24
+
25
+
26
+ class AcrylicSearchLineEdit(AcrylicLineEditBase, SearchLineEdit):
27
+ """ Acrylic search line edit """