提交 60605848 编写于 作者: 之一Yo's avatar 之一Yo

重构开关按钮

上级 73b9931f
......@@ -185,7 +185,8 @@ class BasicInputInterface(GalleryInterface):
# hyperlink button
self.addExampleCard(
self.tr('A hyperlink button that navigates to a URI'),
HyperlinkButton('http://github.com', self.tr('GitHub home page')),
HyperlinkButton(
'https://github.com/zhiyiYo/QMaterialWidgets', self.tr('GitHub home page'), self, FluentIcon.LINK),
'https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/button/demo.py'
)
......
......@@ -14,49 +14,7 @@ SwitchButton>QLabel {
border: none;
}
Indicator {
height: 16px;
width: 37px;
qproperty-sliderOnColor: black;
qproperty-sliderOffColor: rgb(210, 211, 210);
qproperty-sliderDisabledColor: rgb(155, 154, 153);
border-radius: 10px;
}
Indicator:!checked {
background-color: rgb(45, 45, 45);
border: 1px solid rgb(162, 163, 162);
}
Indicator:!checked:hover {
background-color: rgb(58, 60, 59);
border: 1px solid rgb(160, 161, 161);
qproperty-sliderOffColor: rgb(91, 91, 91);
}
Indicator:!checked:pressed {
background-color: rgb(64, 65, 64);
border: 1px solid rgb(164, 165, 165);
qproperty-sliderOffColor: rgb(87, 87, 87);
SwitchButton>QLabel:disabled {
color: rgba(255, 255, 255, 0.36);
}
Indicator:checked {
border: 1px solid --ThemeColorPrimary;
background-color: --ThemeColorPrimary;
}
Indicator:checked:hover {
border: 1px solid --ThemeColorDark1;
background-color: --ThemeColorDark1;
}
Indicator:checked:pressed {
border: 1px solid --ThemeColorDark2;
background-color: --ThemeColorDark2;
}
Indicator:disabled {
border: 1px solid rgb(100, 100, 100);
background-color: transparent;
}
\ No newline at end of file
......@@ -14,49 +14,7 @@ SwitchButton>QLabel {
border: none;
}
Indicator {
height: 16px;
width: 37px;
qproperty-sliderOnColor: white;
qproperty-sliderOffColor: rgb(96, 96, 96);
qproperty-sliderDisabledColor: rgb(155, 154, 153);
border-radius: 10px;
}
Indicator:!checked {
background-color: rgb(247, 247, 247);
border: 1px solid rgb(139, 139, 139);
}
Indicator:!checked:hover {
border: 1px solid rgb(136, 136, 136);
background-color: rgb(238, 238, 238);
qproperty-sliderOffColor: rgb(91, 91, 91);
}
Indicator:!checked:pressed {
border: 1px solid rgb(133, 133, 133);
background-color: rgb(229, 229, 229);
qproperty-sliderOffColor: rgb(87, 87, 87);
}
Indicator:checked {
border: 1px solid --ThemeColorPrimary;
background-color: --ThemeColorPrimary;
}
Indicator:checked:hover {
border: 1px solid --ThemeColorLight1;
background-color: --ThemeColorLight1;
}
Indicator:checked:pressed {
border: 1px solid --ThemeColorLight2;
background-color: --ThemeColorLight2;
SwitchButton>QLabel:disabled {
color: rgba(0, 0, 0, 0.36);
}
Indicator:disabled {
border: 1px solid rgb(194, 194, 191);
background-color: rgb(194, 194, 191);
}
\ No newline at end of file
此差异已折叠。
# coding: utf-8
from enum import Enum
from PyQt5.QtCore import Qt, QTimer, pyqtProperty, pyqtSignal, QEvent, QPoint
from PyQt5.QtCore import Qt, QTimer, pyqtProperty, pyqtSignal, QEvent, QPoint, QPropertyAnimation, QEasingCurve
from PyQt5.QtGui import QColor, QPainter, QHoverEvent
from PyQt5.QtWidgets import QApplication, QHBoxLayout, QLabel, QToolButton, QWidget
from ...common.style_sheet import FluentStyleSheet
from ...common.style_sheet import FluentStyleSheet, themeColor, ThemeColor, isDarkTheme
from ...common.overload import singledispatchmethod
from .button import ToolButton
class Indicator(QToolButton):
class Indicator(ToolButton):
""" Indicator of switch button """
checkedChanged = pyqtSignal(bool)
......@@ -17,109 +18,107 @@ class Indicator(QToolButton):
def __init__(self, parent):
super().__init__(parent=parent)
self.setCheckable(True)
super().setChecked(False)
self.resize(37, 16)
self.__sliderOnColor = QColor(Qt.white)
self.__sliderOffColor = QColor(Qt.black)
self.__sliderDisabledColor = QColor(QColor(155, 154, 153))
self.timer = QTimer(self)
self.padding = self.height()//4
self.sliderX = self.padding
self.sliderRadius = (self.height()-2*self.padding)//2
self.sliderEndX = self.width()-2*self.sliderRadius
self.sliderStep = self.width()/50
self.timer.timeout.connect(self.__updateSliderPos)
def __updateSliderPos(self):
""" update slider position """
if self.isChecked():
if self.sliderX+self.sliderStep < self.sliderEndX:
self.sliderX += self.sliderStep
else:
self.sliderX = self.sliderEndX
self.timer.stop()
else:
if self.sliderX-self.sliderStep > self.sliderEndX:
self.sliderX -= self.sliderStep
else:
self.sliderX = self.padding
self.timer.stop()
self.style().polish(self)
def setChecked(self, isChecked: bool):
""" set checked state """
if isChecked == self.isChecked():
return
self.setFixedSize(42, 22)
super().setChecked(isChecked)
self.sliderRadius = (self.height()-2*self.padding)//2
self.sliderEndX = self.width()-2*self.sliderRadius - \
self.padding if isChecked else self.padding
self.timer.start(5)
self._sliderX = 5
self.slideAni = QPropertyAnimation(self, b'sliderX', self)
self.slideAni.setDuration(120)
def toggle(self):
self.setChecked(not self.isChecked())
self.toggled.connect(self._toggleSlider)
def mouseReleaseEvent(self, e):
""" toggle checked state when mouse release"""
super().mouseReleaseEvent(e)
self.sliderEndX = self.width()-2*self.sliderRadius - \
self.padding if self.isChecked() else self.padding
self.timer.start(5)
self.checkedChanged.emit(self.isChecked())
def resizeEvent(self, e):
self.padding = self.height()//4
self.sliderRadius = (self.height()-2*self.padding)//2
self.sliderStep = self.width()/50
self.sliderEndX = self.width()-2*self.sliderRadius - \
self.padding if self.isChecked() else self.padding
def _toggleSlider(self):
self.slideAni.setEndValue(26 if self.isChecked() else 5)
self.slideAni.start()
def toggle(self):
self.setChecked(not self.isChecked())
def setDown(self, isDown: bool):
self.isPressed = isDown
super().setDown(isDown)
def setHover(self, isHover: bool):
self.isHover = isHover
self.update()
def paintEvent(self, e):
""" paint indicator """
# the background and border are specified by qss
super().paintEvent(e)
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
self._drawBackground(painter)
self._drawCircle(painter)
def _drawBackground(self, painter: QPainter):
r = self.height() / 2
painter.setPen(self._borderColor())
painter.setBrush(self._backgroundColor())
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), r, r)
def _drawCircle(self, painter: QPainter):
painter.setPen(Qt.NoPen)
painter.setBrush(self._sliderColor())
painter.drawEllipse(int(self.sliderX), 5, 12, 12)
if self.isEnabled():
color = self.sliderOnColor if self.isChecked() else self.sliderOffColor
def _backgroundColor(self):
isDark = isDarkTheme()
if self.isChecked():
if not self.isEnabled():
return QColor(255, 255, 255, 41) if isDark else QColor(0, 0, 0, 56)
if self.isPressed:
return ThemeColor.LIGHT_2.color()
elif self.isHover:
return ThemeColor.LIGHT_1.color()
return themeColor()
else:
color = self.sliderDisabledColor
if not self.isEnabled():
return QColor(0, 0, 0, 0)
if self.isPressed:
return QColor(255, 255, 255, 18) if isDark else QColor(0, 0, 0, 23)
elif self.isHover:
return QColor(255, 255, 255, 10) if isDark else QColor(0, 0, 0, 15)
painter.setBrush(color)
painter.drawEllipse(int(self.sliderX), int(self.padding),
self.sliderRadius*2, self.sliderRadius*2)
return QColor(0, 0, 0, 0)
def getSliderOnColor(self):
return self.__sliderOnColor
def _borderColor(self):
isDark = isDarkTheme()
def setSliderOnColor(self, color: QColor):
self.__sliderOnColor = color
self.update()
if self.isChecked():
return self._backgroundColor() if self.isEnabled() else QColor(0, 0, 0, 0)
else:
if self.isEnabled():
return QColor(255, 255, 255, 153) if isDark else QColor(0, 0, 0, 133)
def getSliderOffColor(self):
return self.__sliderOffColor
return QColor(255, 255, 255, 41) if isDark else QColor(0, 0, 0, 56)
def setSliderOffColor(self, color: QColor):
self.__sliderOffColor = color
self.update()
def _sliderColor(self):
isDark = isDarkTheme()
if self.isChecked():
if self.isEnabled():
return QColor(Qt.black if isDark else Qt.white)
def getSliderDisabledColor(self):
return self.__sliderDisabledColor
return QColor(255, 255, 255, 77) if isDark else QColor(255, 255, 255)
else:
if self.isEnabled():
return QColor(255, 255, 255, 201) if isDark else QColor(0, 0, 0, 156)
def setSliderDisabledColor(self, color: QColor):
self.__sliderDisabledColor = color
self.update()
return QColor(255, 255, 255, 96) if isDark else QColor(0, 0, 0, 91)
sliderOnColor = pyqtProperty(QColor, getSliderOnColor, setSliderOnColor)
sliderOffColor = pyqtProperty(QColor, getSliderOffColor, setSliderOffColor)
sliderDisabledColor = pyqtProperty(
QColor, getSliderDisabledColor, setSliderDisabledColor)
@pyqtProperty(float)
def sliderX(self):
return self._sliderX
@sliderX.setter
def sliderX(self, x):
self._sliderX = x
self.update()
class IndicatorPosition(Enum):
......@@ -149,10 +148,12 @@ class SwitchButton(QWidget):
self._offText = self.tr('Off')
self._onText = self.tr('On')
self.__spacing = 12
self.indicatorPos = indicatorPos
self.hBox = QHBoxLayout(self)
self.indicator = Indicator(self)
self.label = QLabel(self._text, self)
self.__initWidget()
@__init__.register
......@@ -176,7 +177,6 @@ class SwitchButton(QWidget):
def __initWidget(self):
""" initialize widgets """
self.setAttribute(Qt.WA_StyledBackground)
self.setFixedHeight(37)
self.installEventFilter(self)
# set layout
......@@ -207,13 +207,9 @@ class SwitchButton(QWidget):
self.indicator.setDown(False)
self.indicator.toggle()
elif e.type() == QEvent.Enter:
self.indicator.setAttribute(Qt.WA_UnderMouse, True)
e = QHoverEvent(QEvent.HoverEnter, QPoint(), QPoint(1, 1))
QApplication.sendEvent(self.indicator, e)
self.indicator.setHover(True)
elif e.type() == QEvent.Leave:
self.indicator.setAttribute(Qt.WA_UnderMouse, False)
e = QHoverEvent(QEvent.HoverLeave, QPoint(1, 1), QPoint())
QApplication.sendEvent(self.indicator, e)
self.indicator.setHover(False)
return super().eventFilter(obj, e)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册