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,556 @@
1
+ # coding:utf-8
2
+ import sys
3
+ from typing import Union, List, Iterable
4
+
5
+ from PySide6.QtCore import Qt, Signal, QRectF, QPoint, QObject, QEvent
6
+ from PySide6.QtGui import QPainter, QAction, QCursor, QIcon
7
+ from PySide6.QtWidgets import QPushButton, QApplication
8
+
9
+ from .menu import RoundMenu, MenuAnimationType, IndicatorMenuItemDelegate
10
+ from .line_edit import LineEdit, LineEditButton
11
+ from ...common.animation import TranslateYAnimation
12
+ from ...common.icon import FluentIconBase, isDarkTheme
13
+ from ...common.icon import FluentIcon as FIF
14
+ from ...common.font import setFont
15
+ from ...common.style_sheet import FluentStyleSheet
16
+
17
+
18
+ class ComboItem:
19
+ """ Combo box item """
20
+
21
+ def __init__(self, text: str, icon: Union[str, QIcon, FluentIconBase] = None, userData=None, isEnabled=True):
22
+ """ add item
23
+
24
+ Parameters
25
+ ----------
26
+ text: str
27
+ the text of item
28
+
29
+ icon: str | QIcon | FluentIconBase
30
+ the icon of item
31
+
32
+ userData: Any
33
+ user data
34
+
35
+ isEnabled: bool
36
+ whether to enable the item
37
+ """
38
+ self.text = text
39
+ self.userData = userData
40
+ self.icon = icon
41
+ self.isEnabled = isEnabled
42
+
43
+ @property
44
+ def icon(self):
45
+ if isinstance(self._icon, QIcon):
46
+ return self._icon
47
+
48
+ return self._icon.icon()
49
+
50
+ @icon.setter
51
+ def icon(self, ico: Union[str, QIcon, FluentIconBase]):
52
+ if ico:
53
+ self._icon = QIcon(ico) if isinstance(ico, str) else ico
54
+ else:
55
+ self._icon = QIcon()
56
+
57
+
58
+ class ComboBoxBase:
59
+ """ Combo box base """
60
+ activated = Signal(int)
61
+ textActivated = Signal(str)
62
+
63
+ def __init__(self, parent=None, **kwargs):
64
+ pass
65
+
66
+ def _setUpUi(self):
67
+ self.isHover = False
68
+ self.isPressed = False
69
+ self.items = [] # type: List[ComboItem]
70
+ self._currentIndex = -1
71
+ self._maxVisibleItems = -1
72
+ self.dropMenu = None
73
+ self._placeholderText = ""
74
+
75
+ FluentStyleSheet.COMBO_BOX.apply(self)
76
+ self.installEventFilter(self)
77
+
78
+ def addItem(self, text, icon: Union[str, QIcon, FluentIconBase] = None, userData=None):
79
+ """ add item
80
+
81
+ Parameters
82
+ ----------
83
+ text: str
84
+ the text of item
85
+
86
+ icon: str | QIcon | FluentIconBase
87
+ """
88
+ item = ComboItem(text, icon, userData)
89
+ self.items.append(item)
90
+ if len(self.items) == 1:
91
+ self.setCurrentIndex(0)
92
+
93
+ def addItems(self, texts: Iterable[str]):
94
+ """ add items
95
+
96
+ Parameters
97
+ ----------
98
+ text: Iterable[str]
99
+ the text of item
100
+ """
101
+ for text in texts:
102
+ self.addItem(text)
103
+
104
+ def removeItem(self, index: int):
105
+ """ Removes the item at the given index from the combobox.
106
+ This will update the current index if the index is removed.
107
+ """
108
+ if not 0 <= index < len(self.items):
109
+ return
110
+
111
+ self.items.pop(index)
112
+
113
+ if index < self.currentIndex():
114
+ self.setCurrentIndex(self._currentIndex - 1)
115
+ elif index == self.currentIndex():
116
+ if index > 0:
117
+ self.setCurrentIndex(self._currentIndex - 1)
118
+ else:
119
+ self.setText(self.itemText(0))
120
+ self.currentTextChanged.emit(self.currentText())
121
+ self.currentIndexChanged.emit(0)
122
+
123
+ if self.count() == 0:
124
+ self.clear()
125
+
126
+ def currentIndex(self):
127
+ return self._currentIndex
128
+
129
+ def setCurrentIndex(self, index: int):
130
+ """ set current index
131
+
132
+ Parameters
133
+ ----------
134
+ index: int
135
+ current index
136
+ """
137
+ if not 0 <= index < len(self.items) or index == self.currentIndex():
138
+ return
139
+
140
+ oldText = self.currentText()
141
+
142
+ self._currentIndex = index
143
+ self.setText(self.items[index].text)
144
+
145
+ if oldText != self.currentText():
146
+ self.currentTextChanged.emit(self.currentText())
147
+
148
+ self.currentIndexChanged.emit(index)
149
+
150
+ def setText(self, text: str):
151
+ super().setText(text)
152
+ self.adjustSize()
153
+
154
+ def currentText(self):
155
+ if not 0 <= self.currentIndex() < len(self.items):
156
+ return ''
157
+
158
+ return self.items[self.currentIndex()].text
159
+
160
+ def currentData(self):
161
+ if not 0 <= self.currentIndex() < len(self.items):
162
+ return None
163
+
164
+ return self.items[self.currentIndex()].userData
165
+
166
+ def setCurrentText(self, text):
167
+ """ set the current text displayed in combo box,
168
+ text should be in the item list
169
+
170
+ Parameters
171
+ ----------
172
+ text: str
173
+ text displayed in combo box
174
+ """
175
+ if text == self.currentText():
176
+ return
177
+
178
+ index = self.findText(text)
179
+ if index >= 0:
180
+ self.setCurrentIndex(index)
181
+
182
+ def setItemText(self, index: int, text: str):
183
+ """ set the text of item
184
+
185
+ Parameters
186
+ ----------
187
+ index: int
188
+ the index of item
189
+
190
+ text: str
191
+ new text of item
192
+ """
193
+ if not 0 <= index < len(self.items):
194
+ return
195
+
196
+ self.items[index].text = text
197
+ if self.currentIndex() == index:
198
+ self.setText(text)
199
+
200
+ def itemData(self, index: int):
201
+ """ Returns the data in the given index """
202
+ if not 0 <= index < len(self.items):
203
+ return None
204
+
205
+ return self.items[index].userData
206
+
207
+ def itemText(self, index: int):
208
+ """ Returns the text in the given index """
209
+ if not 0 <= index < len(self.items):
210
+ return ''
211
+
212
+ return self.items[index].text
213
+
214
+ def itemIcon(self, index: int):
215
+ """ Returns the icon in the given index """
216
+ if not 0 <= index < len(self.items):
217
+ return QIcon()
218
+
219
+ return self.items[index].icon
220
+
221
+ def setItemData(self, index: int, value):
222
+ """ Sets the data role for the item on the given index """
223
+ if 0 <= index < len(self.items):
224
+ self.items[index].userData = value
225
+
226
+ def setItemIcon(self, index: int, icon: Union[str, QIcon, FluentIconBase]):
227
+ """ Sets the data role for the item on the given index """
228
+ if 0 <= index < len(self.items):
229
+ self.items[index].icon = icon
230
+
231
+ def setItemEnabled(self, index: int, isEnabled: bool):
232
+ """ Sets the enabled status of the item on the given index """
233
+ if 0 <= index < len(self.items):
234
+ self.items[index].isEnabled = isEnabled
235
+
236
+ def findData(self, data):
237
+ """ Returns the index of the item containing the given data, otherwise returns -1 """
238
+ for i, item in enumerate(self.items):
239
+ if item.userData == data:
240
+ return i
241
+
242
+ return -1
243
+
244
+ def findText(self, text: str):
245
+ """ Returns the index of the item containing the given text; otherwise returns -1. """
246
+ for i, item in enumerate(self.items):
247
+ if item.text == text:
248
+ return i
249
+
250
+ return -1
251
+
252
+ def clear(self):
253
+ """ Clears the combobox, removing all items. """
254
+ if self.currentIndex() >= 0:
255
+ self.setText('')
256
+
257
+ self.items.clear()
258
+ self._currentIndex = -1
259
+
260
+ def count(self):
261
+ """ Returns the number of items in the combobox """
262
+ return len(self.items)
263
+
264
+ def insertItem(self, index: int, text: str, icon: Union[str, QIcon, FluentIconBase] = None, userData=None):
265
+ """ Inserts item into the combobox at the given index. """
266
+ item = ComboItem(text, icon, userData)
267
+ self.items.insert(index, item)
268
+
269
+ if index <= self.currentIndex():
270
+ self.setCurrentIndex(self.currentIndex() + 1)
271
+
272
+ def insertItems(self, index: int, texts: Iterable[str]):
273
+ """ Inserts items into the combobox, starting at the index specified. """
274
+ pos = index
275
+ for text in texts:
276
+ item = ComboItem(text)
277
+ self.items.insert(pos, item)
278
+ pos += 1
279
+
280
+ if index <= self.currentIndex():
281
+ self.setCurrentIndex(self.currentIndex() + pos - index)
282
+
283
+ def setMaxVisibleItems(self, num: int):
284
+ self._maxVisibleItems = num
285
+
286
+ def maxVisibleItems(self):
287
+ return self._maxVisibleItems
288
+
289
+ def _closeComboMenu(self):
290
+ if not self.dropMenu:
291
+ return
292
+
293
+ # drop menu could be deleted before this method
294
+ try:
295
+ self.dropMenu.close()
296
+ except:
297
+ pass
298
+
299
+ self.dropMenu = None
300
+
301
+ def _onDropMenuClosed(self):
302
+ if sys.platform != "win32":
303
+ self.dropMenu = None
304
+ else:
305
+ pos = self.mapFromGlobal(QCursor.pos())
306
+ if not self.rect().contains(pos):
307
+ self.dropMenu = None
308
+
309
+ def _createComboMenu(self):
310
+ return ComboBoxMenu(self)
311
+
312
+ def _showComboMenu(self):
313
+ if not self.items:
314
+ return
315
+
316
+ menu = self._createComboMenu()
317
+ for item in self.items:
318
+ action = QAction(item.icon, item.text)
319
+ action.setEnabled(item.isEnabled)
320
+ menu.addAction(action)
321
+
322
+ # fixes issue #468
323
+ menu.view.itemClicked.connect(lambda i: self._onItemClicked(self.findText(i.text().lstrip())))
324
+
325
+ if menu.view.width() < self.width():
326
+ menu.view.setMinimumWidth(self.width())
327
+ menu.adjustSize()
328
+
329
+ menu.setMaxVisibleItems(self.maxVisibleItems())
330
+ menu.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
331
+ menu.closedSignal.connect(self._onDropMenuClosed)
332
+ self.dropMenu = menu
333
+
334
+ # set the selected item
335
+ if self.currentIndex() >= 0 and self.items:
336
+ menu.setDefaultAction(menu.actions()[self.currentIndex()])
337
+
338
+ # determine the animation type by choosing the maximum height of view
339
+ x = -menu.width()//2 + menu.layout().contentsMargins().left() + self.width()//2
340
+ pd = self.mapToGlobal(QPoint(x, self.height()))
341
+ hd = menu.view.heightForAnimation(pd, MenuAnimationType.DROP_DOWN)
342
+
343
+ pu = self.mapToGlobal(QPoint(x, 0))
344
+ hu = menu.view.heightForAnimation(pu, MenuAnimationType.PULL_UP)
345
+
346
+ if hd >= hu:
347
+ menu.view.adjustSize(pd, MenuAnimationType.DROP_DOWN)
348
+ menu.exec(pd, aniType=MenuAnimationType.DROP_DOWN)
349
+ else:
350
+ menu.view.adjustSize(pu, MenuAnimationType.PULL_UP)
351
+ menu.exec(pu, aniType=MenuAnimationType.PULL_UP)
352
+
353
+ def _toggleComboMenu(self):
354
+ if self.dropMenu:
355
+ self._closeComboMenu()
356
+ else:
357
+ self._showComboMenu()
358
+
359
+ def _onItemClicked(self, index):
360
+ if not self.items[index].isEnabled:
361
+ return
362
+
363
+ if index != self.currentIndex():
364
+ self.setCurrentIndex(index)
365
+
366
+ self.activated.emit(index)
367
+ self.textActivated.emit(self.currentText())
368
+
369
+
370
+ class ComboBox(QPushButton, ComboBoxBase):
371
+ """ Combo box """
372
+
373
+ currentIndexChanged = Signal(int)
374
+ currentTextChanged = Signal(str)
375
+ activated = Signal(int)
376
+ textActivated = Signal(str)
377
+
378
+ def __init__(self, parent=None):
379
+ super().__init__(parent=parent)
380
+ self.arrowAni = TranslateYAnimation(self)
381
+ self._setUpUi()
382
+ setFont(self)
383
+
384
+ def eventFilter(self, obj, e: QEvent):
385
+ if obj is self:
386
+ if e.type() == QEvent.MouseButtonPress:
387
+ self.isPressed = True
388
+ elif e.type() == QEvent.MouseButtonRelease:
389
+ self.isPressed = False
390
+ elif e.type() == QEvent.Enter:
391
+ self.isHover = True
392
+ elif e.type() == QEvent.Leave:
393
+ self.isHover = False
394
+
395
+ return super().eventFilter(obj, e)
396
+
397
+ def setPlaceholderText(self, text: str):
398
+ self._placeholderText = text
399
+
400
+ if self.currentIndex() <= 0:
401
+ self._updateTextState(True)
402
+ self.setText(text)
403
+
404
+ def setCurrentIndex(self, index: int):
405
+ if index < 0:
406
+ self._currentIndex = -1
407
+ self.setPlaceholderText(self._placeholderText)
408
+ elif 0 <= index < len(self.items):
409
+ self._updateTextState(False)
410
+ super().setCurrentIndex(index)
411
+
412
+ def _updateTextState(self, isPlaceholder):
413
+ if self.property("isPlaceholderText") == isPlaceholder:
414
+ return
415
+
416
+ self.setProperty("isPlaceholderText", isPlaceholder)
417
+ self.setStyle(QApplication.style())
418
+
419
+ def mouseReleaseEvent(self, e):
420
+ super().mouseReleaseEvent(e)
421
+ self._toggleComboMenu()
422
+
423
+ def paintEvent(self, e):
424
+ QPushButton.paintEvent(self, e)
425
+ painter = QPainter(self)
426
+ painter.setRenderHints(QPainter.Antialiasing)
427
+ if self.isHover:
428
+ painter.setOpacity(0.8)
429
+ elif self.isPressed:
430
+ painter.setOpacity(0.7)
431
+
432
+ rect = QRectF(self.width()-22, self.height()/2-5+self.arrowAni.y, 10, 10)
433
+ if isDarkTheme():
434
+ FIF.ARROW_DOWN.render(painter, rect)
435
+ else:
436
+ FIF.ARROW_DOWN.render(painter, rect, fill="#646464")
437
+
438
+
439
+ class EditableComboBox(LineEdit, ComboBoxBase):
440
+ """ Editable combo box """
441
+
442
+ currentIndexChanged = Signal(int)
443
+ currentTextChanged = Signal(str)
444
+ activated = Signal(int)
445
+ textActivated = Signal(str)
446
+
447
+ def __init__(self, parent=None):
448
+ super().__init__(parent=parent)
449
+ self._setUpUi()
450
+
451
+ self.dropButton = LineEditButton(FIF.ARROW_DOWN, self)
452
+
453
+ self.setTextMargins(0, 0, 29, 0)
454
+ self.dropButton.setFixedSize(30, 25)
455
+ self.hBoxLayout.addWidget(self.dropButton, 0, Qt.AlignRight)
456
+
457
+ self.dropButton.clicked.connect(self._toggleComboMenu)
458
+ self.textChanged.connect(self._onComboTextChanged)
459
+ self.returnPressed.connect(self._onReturnPressed)
460
+
461
+ FluentStyleSheet.LINE_EDIT.apply(self)
462
+
463
+ self.clearButton.clicked.disconnect()
464
+ self.clearButton.clicked.connect(self._onClearButtonClicked)
465
+
466
+ def setCompleterMenu(self, menu):
467
+ super().setCompleterMenu(menu)
468
+ menu.activated.connect(self.__onActivated)
469
+
470
+ def __onActivated(self, text):
471
+ index = self.findText(text)
472
+ if index >= 0:
473
+ self.setCurrentIndex(index)
474
+
475
+ def currentText(self):
476
+ return self.text()
477
+
478
+ def setCurrentIndex(self, index: int):
479
+ if index >= self.count() or index == self.currentIndex():
480
+ return
481
+
482
+ if index < 0:
483
+ self._currentIndex = -1
484
+ self.setText("")
485
+ self.setPlaceholderText(self._placeholderText)
486
+ else:
487
+ self._currentIndex = index
488
+ self.setText(self.items[index].text)
489
+
490
+ def clear(self):
491
+ ComboBoxBase.clear(self)
492
+
493
+ def setPlaceholderText(self, text: str):
494
+ self._placeholderText = text
495
+ super().setPlaceholderText(text)
496
+
497
+ def _onReturnPressed(self):
498
+ if not self.text():
499
+ return
500
+
501
+ index = self.findText(self.text())
502
+ if index >= 0 and index != self.currentIndex():
503
+ self._currentIndex = index
504
+ self.currentIndexChanged.emit(index)
505
+ elif index == -1:
506
+ self.addItem(self.text())
507
+ self.setCurrentIndex(self.count() - 1)
508
+
509
+ def eventFilter(self, obj, e: QEvent):
510
+ if obj is self:
511
+ if e.type() == QEvent.MouseButtonPress:
512
+ self.isPressed = True
513
+ elif e.type() == QEvent.MouseButtonRelease:
514
+ self.isPressed = False
515
+ elif e.type() == QEvent.Enter:
516
+ self.isHover = True
517
+ elif e.type() == QEvent.Leave:
518
+ self.isHover = False
519
+
520
+ return super().eventFilter(obj, e)
521
+
522
+ def _onComboTextChanged(self, text: str):
523
+ self._currentIndex = -1
524
+ self.currentTextChanged.emit(text)
525
+
526
+ for i, item in enumerate(self.items):
527
+ if item.text == text:
528
+ self._currentIndex = i
529
+ self.currentIndexChanged.emit(i)
530
+ return
531
+
532
+ def _onDropMenuClosed(self):
533
+ self.dropMenu = None
534
+
535
+ def _onClearButtonClicked(self):
536
+ LineEdit.clear(self)
537
+ self._currentIndex = -1
538
+
539
+
540
+ class ComboBoxMenu(RoundMenu):
541
+ """ Combo box menu """
542
+
543
+ def __init__(self, parent=None):
544
+ super().__init__(title="", parent=parent)
545
+
546
+ self.view.setViewportMargins(0, 2, 0, 6)
547
+ self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
548
+ self.view.setItemDelegate(IndicatorMenuItemDelegate())
549
+ self.view.setObjectName('comboListWidget')
550
+
551
+ self.setItemHeight(33)
552
+
553
+ def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
554
+ self.view.adjustSize(pos, aniType)
555
+ self.adjustSize()
556
+ return super().exec(pos, ani, aniType)