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,223 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
from PySide6.QtCore import Qt, Signal, QTime, Property
|
3
|
+
|
4
|
+
from .picker_base import PickerBase, PickerColumnFormatter, DigitFormatter
|
5
|
+
|
6
|
+
|
7
|
+
class TimePickerBase(PickerBase):
|
8
|
+
""" Time picker base class """
|
9
|
+
|
10
|
+
timeChanged = Signal(QTime)
|
11
|
+
|
12
|
+
def __init__(self, parent=None, showSeconds=False):
|
13
|
+
super().__init__(parent=parent)
|
14
|
+
self._isSecondVisible = showSeconds
|
15
|
+
self._time = QTime()
|
16
|
+
|
17
|
+
def getTime(self):
|
18
|
+
return self._time
|
19
|
+
|
20
|
+
def setTime(self, time: QTime):
|
21
|
+
""" set current time
|
22
|
+
|
23
|
+
Parameters
|
24
|
+
----------
|
25
|
+
time: QTime
|
26
|
+
current time
|
27
|
+
"""
|
28
|
+
raise NotImplementedError
|
29
|
+
|
30
|
+
def isSecondVisible(self):
|
31
|
+
return self._isSecondVisible
|
32
|
+
|
33
|
+
def setSecondVisible(self, isVisible: bool):
|
34
|
+
""" set the visibility of seconds column """
|
35
|
+
raise NotImplementedError
|
36
|
+
|
37
|
+
|
38
|
+
class MiniuteFormatter(DigitFormatter):
|
39
|
+
""" Minute formatter """
|
40
|
+
|
41
|
+
def encode(self, minute):
|
42
|
+
return str(minute).zfill(2)
|
43
|
+
|
44
|
+
|
45
|
+
class AMHourFormatter(DigitFormatter):
|
46
|
+
""" AM/PM Hour formatter """
|
47
|
+
|
48
|
+
def encode(self, hour):
|
49
|
+
hour = int(hour)
|
50
|
+
if hour in [0, 12]:
|
51
|
+
return "12"
|
52
|
+
|
53
|
+
return str(hour % 12)
|
54
|
+
|
55
|
+
|
56
|
+
class AMPMFormatter(PickerColumnFormatter):
|
57
|
+
""" AM/PM formatter """
|
58
|
+
|
59
|
+
def __init__(self):
|
60
|
+
super().__init__()
|
61
|
+
self.AM = self.tr('AM')
|
62
|
+
self.PM = self.tr('PM')
|
63
|
+
|
64
|
+
def encode(self, hour):
|
65
|
+
if not str(hour).isdigit():
|
66
|
+
return str(hour)
|
67
|
+
|
68
|
+
hour = int(hour)
|
69
|
+
return self.AM if hour < 12 else self.PM
|
70
|
+
|
71
|
+
|
72
|
+
class TimePicker(TimePickerBase):
|
73
|
+
""" 24 hours time picker """
|
74
|
+
|
75
|
+
def __init__(self, parent=None, showSeconds=False):
|
76
|
+
super().__init__(parent, showSeconds)
|
77
|
+
# add hour column
|
78
|
+
w = 80 if showSeconds else 120
|
79
|
+
self.addColumn(self.tr('hour'), range(0, 24),
|
80
|
+
w, formatter=DigitFormatter())
|
81
|
+
|
82
|
+
# add minute column
|
83
|
+
self.addColumn(self.tr('minute'), range(0, 60),
|
84
|
+
w, formatter=MiniuteFormatter())
|
85
|
+
|
86
|
+
# add seconds column
|
87
|
+
self.addColumn(self.tr('second'), range(0, 60),
|
88
|
+
w, formatter=MiniuteFormatter())
|
89
|
+
self.setColumnVisible(2, showSeconds)
|
90
|
+
|
91
|
+
def setTime(self, time):
|
92
|
+
if not time.isValid() or time.isNull():
|
93
|
+
return
|
94
|
+
|
95
|
+
self._time = time
|
96
|
+
self.setColumnValue(0, time.hour())
|
97
|
+
self.setColumnValue(1, time.minute())
|
98
|
+
self.setColumnValue(2, time.second())
|
99
|
+
|
100
|
+
def setSecondVisible(self, isVisible: bool):
|
101
|
+
self._isSecondVisible = isVisible
|
102
|
+
self.setColumnVisible(2, isVisible)
|
103
|
+
|
104
|
+
w = 80 if isVisible else 120
|
105
|
+
for button in self.columns:
|
106
|
+
button.setFixedWidth(w)
|
107
|
+
|
108
|
+
def _onConfirmed(self, value: list):
|
109
|
+
super()._onConfirmed(value)
|
110
|
+
h = self.decodeValue(0, value[0])
|
111
|
+
m = self.decodeValue(1, value[1])
|
112
|
+
s = 0 if len(value) == 2 else self.decodeValue(2, value[2])
|
113
|
+
|
114
|
+
time = QTime(h, m, s)
|
115
|
+
ot = self.time
|
116
|
+
self.setTime(time)
|
117
|
+
|
118
|
+
if ot != time:
|
119
|
+
self.timeChanged.emit(time)
|
120
|
+
|
121
|
+
def panelInitialValue(self):
|
122
|
+
if any(self.value()):
|
123
|
+
return self.value()
|
124
|
+
|
125
|
+
time = QTime.currentTime()
|
126
|
+
h = self.encodeValue(0, time.hour())
|
127
|
+
m = self.encodeValue(1, time.minute())
|
128
|
+
s = self.encodeValue(2, time.second())
|
129
|
+
return [h, m, s] if self.isSecondVisible() else [h, m]
|
130
|
+
|
131
|
+
def getTime(self):
|
132
|
+
return self._time
|
133
|
+
|
134
|
+
def isSecondVisible(self):
|
135
|
+
return self._isSecondVisible
|
136
|
+
|
137
|
+
time = Property(QTime, getTime, setTime)
|
138
|
+
secondVisible = Property(bool, isSecondVisible, setSecondVisible)
|
139
|
+
|
140
|
+
|
141
|
+
class AMTimePicker(TimePickerBase):
|
142
|
+
""" AM/PM time picker """
|
143
|
+
|
144
|
+
def __init__(self, parent=None, showSeconds=False):
|
145
|
+
super().__init__(parent, showSeconds)
|
146
|
+
self.AM = self.tr('AM')
|
147
|
+
self.PM = self.tr('PM')
|
148
|
+
|
149
|
+
# add hour column
|
150
|
+
self.addColumn(self.tr('hour'), range(1, 13),
|
151
|
+
80, formatter=AMHourFormatter())
|
152
|
+
|
153
|
+
# add minute column
|
154
|
+
self.addColumn(self.tr('minute'), range(0, 60),
|
155
|
+
80, formatter=MiniuteFormatter())
|
156
|
+
|
157
|
+
# add second column
|
158
|
+
self.addColumn(self.tr('second'), range(0, 60),
|
159
|
+
80, formatter=MiniuteFormatter())
|
160
|
+
self.setColumnVisible(2, showSeconds)
|
161
|
+
|
162
|
+
# add AM/PM column
|
163
|
+
self.addColumn(self.AM, [self.AM, self.PM],
|
164
|
+
80, formatter=AMPMFormatter())
|
165
|
+
|
166
|
+
def setSecondVisible(self, isVisible: bool):
|
167
|
+
self._isSecondVisible = isVisible
|
168
|
+
self.setColumnVisible(2, isVisible)
|
169
|
+
|
170
|
+
def setTime(self, time):
|
171
|
+
if not time.isValid() or time.isNull():
|
172
|
+
return
|
173
|
+
|
174
|
+
self._time = time
|
175
|
+
self.setColumnValue(0, time.hour())
|
176
|
+
self.setColumnValue(1, time.minute())
|
177
|
+
self.setColumnValue(2, time.second())
|
178
|
+
self.setColumnValue(3, time.hour())
|
179
|
+
|
180
|
+
def _onConfirmed(self, value: list):
|
181
|
+
super()._onConfirmed(value)
|
182
|
+
|
183
|
+
if len(value) == 3:
|
184
|
+
h, m, p = value
|
185
|
+
s = 0
|
186
|
+
else:
|
187
|
+
h, m, s, p = value
|
188
|
+
s = self.decodeValue(2, s)
|
189
|
+
|
190
|
+
h = self.decodeValue(0, h)
|
191
|
+
m = self.decodeValue(1, m)
|
192
|
+
|
193
|
+
if p == self.AM:
|
194
|
+
h = 0 if h == 12 else h
|
195
|
+
elif p == self.PM:
|
196
|
+
h = h if h == 12 else h + 12
|
197
|
+
|
198
|
+
time = QTime(h, m, s)
|
199
|
+
ot = self.time
|
200
|
+
self.setTime(time)
|
201
|
+
|
202
|
+
if ot != time:
|
203
|
+
self.timeChanged.emit(time)
|
204
|
+
|
205
|
+
def panelInitialValue(self):
|
206
|
+
if any(self.value()):
|
207
|
+
return self.value()
|
208
|
+
|
209
|
+
time = QTime.currentTime()
|
210
|
+
h = self.encodeValue(0, time.hour())
|
211
|
+
m = self.encodeValue(1, time.minute())
|
212
|
+
s = self.encodeValue(2, time.second())
|
213
|
+
p = self.encodeValue(3, time.hour())
|
214
|
+
return [h, m, s, p] if self.isSecondVisible() else [h, m, p]
|
215
|
+
|
216
|
+
def getTime(self):
|
217
|
+
return self._time
|
218
|
+
|
219
|
+
def isSecondVisible(self):
|
220
|
+
return self._isSecondVisible
|
221
|
+
|
222
|
+
time = Property(QTime, getTime, setTime)
|
223
|
+
secondVisible = Property(bool, isSecondVisible, setSecondVisible)
|
@@ -0,0 +1,414 @@
|
|
1
|
+
# coding:utf-8
|
2
|
+
from PySide6.QtCore import Qt, Signal, QPoint, QRegularExpression, QSize
|
3
|
+
from PySide6.QtGui import (QBrush, QColor, QPixmap, QPainter,
|
4
|
+
QPen, QIntValidator, QRegularExpressionValidator, QIcon)
|
5
|
+
from PySide6.QtWidgets import QApplication, QLabel, QWidget, QPushButton, QPushButton, QFrame, QVBoxLayout
|
6
|
+
|
7
|
+
from ...common.style_sheet import FluentStyleSheet, isDarkTheme
|
8
|
+
from ..widgets import ClickableSlider, SingleDirectionScrollArea, PushButton, PrimaryPushButton
|
9
|
+
from ..widgets.line_edit import LineEdit
|
10
|
+
from .mask_dialog_base import MaskDialogBase
|
11
|
+
|
12
|
+
|
13
|
+
class HuePanel(QWidget):
|
14
|
+
""" Hue panel """
|
15
|
+
|
16
|
+
colorChanged = Signal(QColor)
|
17
|
+
|
18
|
+
def __init__(self, color=QColor(255, 0, 0), parent=None):
|
19
|
+
super().__init__(parent=parent)
|
20
|
+
self.setFixedSize(256, 256)
|
21
|
+
self.huePixmap = QPixmap(":/fastuiwidgets/images/color_dialog/HuePanel.png")
|
22
|
+
self.setColor(color)
|
23
|
+
|
24
|
+
def mousePressEvent(self, e):
|
25
|
+
self.setPickerPosition(e.pos())
|
26
|
+
|
27
|
+
def mouseMoveEvent(self, e):
|
28
|
+
self.setPickerPosition(e.pos())
|
29
|
+
|
30
|
+
def setPickerPosition(self, pos):
|
31
|
+
""" set the position of """
|
32
|
+
self.pickerPos = pos
|
33
|
+
self.color.setHsv(
|
34
|
+
int(max(0, min(1, pos.x() / self.width())) * 360),
|
35
|
+
int(max(0, min(1, (self.height() - pos.y()) / self.height())) * 255),
|
36
|
+
255
|
37
|
+
)
|
38
|
+
self.update()
|
39
|
+
self.colorChanged.emit(self.color)
|
40
|
+
|
41
|
+
def setColor(self, color):
|
42
|
+
""" set color """
|
43
|
+
self.color = QColor(color)
|
44
|
+
self.color.setHsv(self.color.hue(), self.color.saturation(), 255)
|
45
|
+
self.pickerPos = QPoint(
|
46
|
+
int(self.hue/360*self.width()),
|
47
|
+
int((255 - self.saturation)/255*self.height())
|
48
|
+
)
|
49
|
+
self.update()
|
50
|
+
|
51
|
+
@property
|
52
|
+
def hue(self):
|
53
|
+
return self.color.hue()
|
54
|
+
|
55
|
+
@property
|
56
|
+
def saturation(self):
|
57
|
+
return self.color.saturation()
|
58
|
+
|
59
|
+
def paintEvent(self, e):
|
60
|
+
painter = QPainter(self)
|
61
|
+
painter.setRenderHints(QPainter.Antialiasing |
|
62
|
+
QPainter.SmoothPixmapTransform)
|
63
|
+
|
64
|
+
# draw hue panel
|
65
|
+
painter.setBrush(QBrush(self.huePixmap))
|
66
|
+
painter.setPen(QPen(QColor(0, 0, 0, 15), 2.4))
|
67
|
+
painter.drawRoundedRect(self.rect(), 5.6, 5.6)
|
68
|
+
|
69
|
+
# draw picker
|
70
|
+
if self.saturation > 153 or 40 < self.hue < 180:
|
71
|
+
color = Qt.black
|
72
|
+
else:
|
73
|
+
color = QColor(255, 253, 254)
|
74
|
+
|
75
|
+
painter.setPen(QPen(color, 3))
|
76
|
+
painter.setBrush(Qt.NoBrush)
|
77
|
+
painter.drawEllipse(self.pickerPos.x() - 8,
|
78
|
+
self.pickerPos.y() - 8, 16, 16)
|
79
|
+
|
80
|
+
|
81
|
+
class BrightnessSlider(ClickableSlider):
|
82
|
+
""" Brightness slider """
|
83
|
+
|
84
|
+
colorChanged = Signal(QColor)
|
85
|
+
|
86
|
+
def __init__(self, color, parent=None):
|
87
|
+
super().__init__(Qt.Horizontal, parent)
|
88
|
+
self.setRange(0, 255)
|
89
|
+
self.setSingleStep(1)
|
90
|
+
self.setColor(color)
|
91
|
+
self.valueChanged.connect(self.__onValueChanged)
|
92
|
+
|
93
|
+
def setColor(self, color):
|
94
|
+
""" set color """
|
95
|
+
self.color = QColor(color)
|
96
|
+
self.setValue(self.color.value())
|
97
|
+
qss = FluentStyleSheet.COLOR_DIALOG.content()
|
98
|
+
qss = qss.replace('--slider-hue', str(self.color.hue()))
|
99
|
+
qss = qss.replace('--slider-saturation', str(self.color.saturation()))
|
100
|
+
self.setStyleSheet(qss)
|
101
|
+
|
102
|
+
def __onValueChanged(self, value):
|
103
|
+
""" slider value changed slot """
|
104
|
+
self.color.setHsv(self.color.hue(), self.color.saturation(), value, self.color.alpha())
|
105
|
+
self.setColor(self.color)
|
106
|
+
self.colorChanged.emit(self.color)
|
107
|
+
|
108
|
+
|
109
|
+
class ColorCard(QWidget):
|
110
|
+
""" Color card """
|
111
|
+
|
112
|
+
def __init__(self, color, parent=None, enableAlpha=False):
|
113
|
+
super().__init__(parent)
|
114
|
+
self.setFixedSize(44, 128)
|
115
|
+
self.setColor(color)
|
116
|
+
self.enableAlpha = enableAlpha
|
117
|
+
self.titledPixmap = self._createTitledBackground()
|
118
|
+
|
119
|
+
def _createTitledBackground(self):
|
120
|
+
pixmap = QPixmap(8, 8)
|
121
|
+
pixmap.fill(Qt.transparent)
|
122
|
+
painter = QPainter(pixmap)
|
123
|
+
|
124
|
+
c = 255 if isDarkTheme() else 0
|
125
|
+
color = QColor(c, c, c, 26)
|
126
|
+
painter.fillRect(4, 0, 4, 4, color)
|
127
|
+
painter.fillRect(0, 4, 4, 4, color)
|
128
|
+
painter.end()
|
129
|
+
return pixmap
|
130
|
+
|
131
|
+
def setColor(self, color):
|
132
|
+
""" set the color of card """
|
133
|
+
self.color = QColor(color)
|
134
|
+
self.update()
|
135
|
+
|
136
|
+
def paintEvent(self, e):
|
137
|
+
painter = QPainter(self)
|
138
|
+
painter.setRenderHints(QPainter.Antialiasing)
|
139
|
+
|
140
|
+
# draw tiled background
|
141
|
+
if self.enableAlpha:
|
142
|
+
painter.setBrush(QBrush(self.titledPixmap))
|
143
|
+
painter.setPen(QColor(0, 0, 0, 13))
|
144
|
+
painter.drawRoundedRect(self.rect(), 4, 4)
|
145
|
+
|
146
|
+
# draw color
|
147
|
+
painter.setBrush(self.color)
|
148
|
+
painter.setPen(QColor(0, 0, 0, 13))
|
149
|
+
painter.drawRoundedRect(self.rect(), 4, 4)
|
150
|
+
|
151
|
+
|
152
|
+
class ColorLineEdit(LineEdit):
|
153
|
+
""" Color line edit """
|
154
|
+
|
155
|
+
valueChanged = Signal(str)
|
156
|
+
|
157
|
+
def __init__(self, value, parent=None):
|
158
|
+
super().__init__(parent)
|
159
|
+
self.setText(str(value))
|
160
|
+
self.setFixedSize(136, 33)
|
161
|
+
self.setClearButtonEnabled(True)
|
162
|
+
self.setValidator(QIntValidator(0, 255, self))
|
163
|
+
|
164
|
+
self.textEdited.connect(self._onTextEdited)
|
165
|
+
|
166
|
+
def _onTextEdited(self, text):
|
167
|
+
""" text edited slot """
|
168
|
+
state = self.validator().validate(text, 0)[0]
|
169
|
+
if state == QIntValidator.Acceptable:
|
170
|
+
self.valueChanged.emit(text)
|
171
|
+
|
172
|
+
|
173
|
+
class HexColorLineEdit(ColorLineEdit):
|
174
|
+
""" Hex color line edit """
|
175
|
+
|
176
|
+
def __init__(self, color, parent=None, enableAlpha=False):
|
177
|
+
self.colorFormat = QColor.HexArgb if enableAlpha else QColor.HexRgb
|
178
|
+
super().__init__(QColor(color).name(self.colorFormat)[1:], parent)
|
179
|
+
|
180
|
+
if enableAlpha:
|
181
|
+
self.setValidator(QRegularExpressionValidator(QRegularExpression(r'[A-Fa-f0-9]{8}')))
|
182
|
+
else:
|
183
|
+
self.setValidator(QRegularExpressionValidator(QRegularExpression(r'[A-Fa-f0-9]{6}')))
|
184
|
+
|
185
|
+
self.setTextMargins(4, 0, 33, 0)
|
186
|
+
self.prefixLabel = QLabel('#', self)
|
187
|
+
self.prefixLabel.move(7, 2)
|
188
|
+
self.prefixLabel.setObjectName('prefixLabel')
|
189
|
+
|
190
|
+
def setColor(self, color):
|
191
|
+
""" set color """
|
192
|
+
self.setText(color.name(self.colorFormat)[1:])
|
193
|
+
|
194
|
+
|
195
|
+
class OpacityLineEdit(ColorLineEdit):
|
196
|
+
""" Opacity line edit """
|
197
|
+
|
198
|
+
def __init__(self, value, parent=None, enableAlpha=False):
|
199
|
+
super().__init__(int(value/255*100), parent)
|
200
|
+
self.setValidator(QRegularExpressionValidator(QRegularExpression(r'[0-9][0-9]{0,1}|100')))
|
201
|
+
self.setTextMargins(4, 0, 33, 0)
|
202
|
+
self.suffixLabel = QLabel('%', self)
|
203
|
+
self.suffixLabel.setObjectName('suffixLabel')
|
204
|
+
self.textChanged.connect(self._adjustSuffixPos)
|
205
|
+
|
206
|
+
def showEvent(self, e):
|
207
|
+
super().showEvent(e)
|
208
|
+
self._adjustSuffixPos()
|
209
|
+
|
210
|
+
def _adjustSuffixPos(self):
|
211
|
+
x = self.fontMetrics().boundingRect(self.text()).width() + 18
|
212
|
+
self.suffixLabel.move(x, 2)
|
213
|
+
|
214
|
+
|
215
|
+
class ColorDialog(MaskDialogBase):
|
216
|
+
""" Color dialog """
|
217
|
+
|
218
|
+
colorChanged = Signal(QColor)
|
219
|
+
|
220
|
+
def __init__(self, color, title: str, parent=None, enableAlpha=False):
|
221
|
+
"""
|
222
|
+
Parameters
|
223
|
+
----------
|
224
|
+
color: `QColor` | `GlobalColor` | str
|
225
|
+
initial color
|
226
|
+
|
227
|
+
title: str
|
228
|
+
the title of dialog
|
229
|
+
|
230
|
+
parent: QWidget
|
231
|
+
parent widget
|
232
|
+
|
233
|
+
enableAlpha: bool
|
234
|
+
whether to enable the alpha channel
|
235
|
+
"""
|
236
|
+
super().__init__(parent)
|
237
|
+
self.enableAlpha = enableAlpha
|
238
|
+
if not enableAlpha:
|
239
|
+
color = QColor(color)
|
240
|
+
color.setAlpha(255)
|
241
|
+
|
242
|
+
self.oldColor = QColor(color)
|
243
|
+
self.color = QColor(color)
|
244
|
+
|
245
|
+
self.scrollArea = SingleDirectionScrollArea(self.widget)
|
246
|
+
self.scrollWidget = QWidget(self.scrollArea)
|
247
|
+
|
248
|
+
self.buttonGroup = QFrame(self.widget)
|
249
|
+
self.yesButton = PrimaryPushButton(self.tr('OK'), self.buttonGroup)
|
250
|
+
self.cancelButton = QPushButton(self.tr('Cancel'), self.buttonGroup)
|
251
|
+
|
252
|
+
self.titleLabel = QLabel(title, self.scrollWidget)
|
253
|
+
self.huePanel = HuePanel(color, self.scrollWidget)
|
254
|
+
self.newColorCard = ColorCard(color, self.scrollWidget, enableAlpha)
|
255
|
+
self.oldColorCard = ColorCard(color, self.scrollWidget, enableAlpha)
|
256
|
+
self.brightSlider = BrightnessSlider(color, self.scrollWidget)
|
257
|
+
|
258
|
+
self.editLabel = QLabel(self.tr('Edit Color'), self.scrollWidget)
|
259
|
+
self.redLabel = QLabel(self.tr('Red'), self.scrollWidget)
|
260
|
+
self.blueLabel = QLabel(self.tr('Blue'), self.scrollWidget)
|
261
|
+
self.greenLabel = QLabel(self.tr('Green'), self.scrollWidget)
|
262
|
+
self.opacityLabel = QLabel(self.tr('Opacity'), self.scrollWidget)
|
263
|
+
self.hexLineEdit = HexColorLineEdit(color, self.scrollWidget, enableAlpha)
|
264
|
+
self.redLineEdit = ColorLineEdit(self.color.red(), self.scrollWidget)
|
265
|
+
self.greenLineEdit = ColorLineEdit(self.color.green(), self.scrollWidget)
|
266
|
+
self.blueLineEdit = ColorLineEdit(self.color.blue(), self.scrollWidget)
|
267
|
+
self.opacityLineEdit = OpacityLineEdit(self.color.alpha(), self.scrollWidget)
|
268
|
+
|
269
|
+
self.vBoxLayout = QVBoxLayout(self.widget)
|
270
|
+
|
271
|
+
self.__initWidget()
|
272
|
+
|
273
|
+
def __initWidget(self):
|
274
|
+
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
275
|
+
self.scrollArea.setViewportMargins(48, 24, 0, 24)
|
276
|
+
self.scrollArea.setWidget(self.scrollWidget)
|
277
|
+
|
278
|
+
self.widget.setMaximumSize(488, 696+40*self.enableAlpha)
|
279
|
+
self.widget.resize(488, 696+40*self.enableAlpha)
|
280
|
+
self.scrollWidget.resize(440, 560+40*self.enableAlpha)
|
281
|
+
self.buttonGroup.setFixedSize(486, 81)
|
282
|
+
self.yesButton.setFixedWidth(216)
|
283
|
+
self.cancelButton.setFixedWidth(216)
|
284
|
+
|
285
|
+
self.setShadowEffect(60, (0, 10), QColor(0, 0, 0, 80))
|
286
|
+
self.setMaskColor(QColor(0, 0, 0, 76))
|
287
|
+
|
288
|
+
self.__setQss()
|
289
|
+
self.__initLayout()
|
290
|
+
self.__connectSignalToSlot()
|
291
|
+
|
292
|
+
def __initLayout(self):
|
293
|
+
self.huePanel.move(0, 46)
|
294
|
+
self.newColorCard.move(288, 46)
|
295
|
+
self.oldColorCard.move(288, self.newColorCard.geometry().bottom()+1)
|
296
|
+
self.brightSlider.move(0, 324)
|
297
|
+
|
298
|
+
self.editLabel.move(0, 385)
|
299
|
+
self.redLineEdit.move(0, 426)
|
300
|
+
self.greenLineEdit.move(0, 470)
|
301
|
+
self.blueLineEdit.move(0, 515)
|
302
|
+
self.redLabel.move(144, 434)
|
303
|
+
self.greenLabel.move(144, 478)
|
304
|
+
self.blueLabel.move(144, 524)
|
305
|
+
self.hexLineEdit.move(196, 381)
|
306
|
+
|
307
|
+
if self.enableAlpha:
|
308
|
+
self.opacityLineEdit.move(0, 560)
|
309
|
+
self.opacityLabel.move(144, 567)
|
310
|
+
else:
|
311
|
+
self.opacityLineEdit.hide()
|
312
|
+
self.opacityLabel.hide()
|
313
|
+
|
314
|
+
self.vBoxLayout.setSpacing(0)
|
315
|
+
self.vBoxLayout.setAlignment(Qt.AlignTop)
|
316
|
+
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
|
317
|
+
self.vBoxLayout.addWidget(self.scrollArea, 1)
|
318
|
+
self.vBoxLayout.addWidget(self.buttonGroup, 0, Qt.AlignBottom)
|
319
|
+
|
320
|
+
self.yesButton.move(24, 25)
|
321
|
+
self.cancelButton.move(250, 25)
|
322
|
+
|
323
|
+
def __setQss(self):
|
324
|
+
self.editLabel.setObjectName('editLabel')
|
325
|
+
self.titleLabel.setObjectName('titleLabel')
|
326
|
+
self.yesButton.setObjectName('yesButton')
|
327
|
+
self.cancelButton.setObjectName('cancelButton')
|
328
|
+
self.buttonGroup.setObjectName('buttonGroup')
|
329
|
+
FluentStyleSheet.COLOR_DIALOG.apply(self)
|
330
|
+
self.titleLabel.adjustSize()
|
331
|
+
self.editLabel.adjustSize()
|
332
|
+
|
333
|
+
def setColor(self, color, movePicker=True):
|
334
|
+
""" set color """
|
335
|
+
self.color = QColor(color)
|
336
|
+
self.brightSlider.setColor(color)
|
337
|
+
self.newColorCard.setColor(color)
|
338
|
+
self.hexLineEdit.setColor(color)
|
339
|
+
self.redLineEdit.setText(str(color.red()))
|
340
|
+
self.blueLineEdit.setText(str(color.blue()))
|
341
|
+
self.greenLineEdit.setText(str(color.green()))
|
342
|
+
if movePicker:
|
343
|
+
self.huePanel.setColor(color)
|
344
|
+
|
345
|
+
def __onHueChanged(self, color):
|
346
|
+
""" hue changed slot """
|
347
|
+
self.color.setHsv(
|
348
|
+
color.hue(), color.saturation(), self.color.value(), self.color.alpha())
|
349
|
+
self.setColor(self.color)
|
350
|
+
|
351
|
+
def __onBrightnessChanged(self, color):
|
352
|
+
""" brightness changed slot """
|
353
|
+
self.color.setHsv(
|
354
|
+
self.color.hue(), self.color.saturation(), color.value(), color.alpha())
|
355
|
+
self.setColor(self.color, False)
|
356
|
+
|
357
|
+
def __onRedChanged(self, red):
|
358
|
+
""" red channel changed slot """
|
359
|
+
self.color.setRed(int(red))
|
360
|
+
self.setColor(self.color)
|
361
|
+
|
362
|
+
def __onBlueChanged(self, blue):
|
363
|
+
""" blue channel changed slot """
|
364
|
+
self.color.setBlue(int(blue))
|
365
|
+
self.setColor(self.color)
|
366
|
+
|
367
|
+
def __onGreenChanged(self, green):
|
368
|
+
""" green channel changed slot """
|
369
|
+
self.color.setGreen(int(green))
|
370
|
+
self.setColor(self.color)
|
371
|
+
|
372
|
+
def __onOpacityChanged(self, opacity):
|
373
|
+
""" opacity channel changed slot """
|
374
|
+
self.color.setAlpha(int(int(opacity)/100*255))
|
375
|
+
self.setColor(self.color)
|
376
|
+
|
377
|
+
def __onHexColorChanged(self, color):
|
378
|
+
""" hex color changed slot """
|
379
|
+
self.color.setNamedColor("#" + color)
|
380
|
+
self.setColor(self.color)
|
381
|
+
|
382
|
+
def __onYesButtonClicked(self):
|
383
|
+
""" yes button clicked slot """
|
384
|
+
self.accept()
|
385
|
+
if self.color != self.oldColor:
|
386
|
+
self.colorChanged.emit(self.color)
|
387
|
+
|
388
|
+
def updateStyle(self):
|
389
|
+
""" update style sheet """
|
390
|
+
self.setStyle(QApplication.style())
|
391
|
+
self.titleLabel.adjustSize()
|
392
|
+
self.editLabel.adjustSize()
|
393
|
+
self.redLabel.adjustSize()
|
394
|
+
self.greenLabel.adjustSize()
|
395
|
+
self.blueLabel.adjustSize()
|
396
|
+
self.opacityLabel.adjustSize()
|
397
|
+
|
398
|
+
def showEvent(self, e):
|
399
|
+
self.updateStyle()
|
400
|
+
super().showEvent(e)
|
401
|
+
|
402
|
+
def __connectSignalToSlot(self):
|
403
|
+
""" connect signal to slot """
|
404
|
+
self.cancelButton.clicked.connect(self.reject)
|
405
|
+
self.yesButton.clicked.connect(self.__onYesButtonClicked)
|
406
|
+
|
407
|
+
self.huePanel.colorChanged.connect(self.__onHueChanged)
|
408
|
+
self.brightSlider.colorChanged.connect(self.__onBrightnessChanged)
|
409
|
+
|
410
|
+
self.redLineEdit.valueChanged.connect(self.__onRedChanged)
|
411
|
+
self.blueLineEdit.valueChanged.connect(self.__onBlueChanged)
|
412
|
+
self.greenLineEdit.valueChanged.connect(self.__onGreenChanged)
|
413
|
+
self.hexLineEdit.valueChanged.connect(self.__onHexColorChanged)
|
414
|
+
self.opacityLineEdit.valueChanged.connect(self.__onOpacityChanged)
|