1059 lines
33 KiB
Python
1059 lines
33 KiB
Python
|
|
# coding:utf-8
|
||
|
|
from typing import Union
|
||
|
|
|
||
|
|
from PySide6.QtCore import Signal, QUrl, Qt, QRectF, QSize, QPoint, Property, QRect
|
||
|
|
from PySide6.QtGui import QDesktopServices, QIcon, QPainter, QColor, QPainterPath
|
||
|
|
from PySide6.QtWidgets import QHBoxLayout, QPushButton, QRadioButton, QToolButton, QApplication, QWidget, QSizePolicy
|
||
|
|
|
||
|
|
from ...common.animation import TranslateYAnimation
|
||
|
|
from ...common.icon import FluentIconBase, drawIcon, isDarkTheme, Theme, toQIcon, Icon
|
||
|
|
from ...common.icon import FluentIcon as FIF
|
||
|
|
from ...common.font import setFont, getFont
|
||
|
|
from ...common.style_sheet import FluentStyleSheet, themeColor, ThemeColor
|
||
|
|
from ...common.color import autoFallbackThemeColor
|
||
|
|
from ...common.overload import singledispatchmethod
|
||
|
|
from .menu import RoundMenu, MenuAnimationType
|
||
|
|
|
||
|
|
|
||
|
|
class PushButton(QPushButton):
|
||
|
|
""" Push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PushButton(`parent`: QWidget = None)
|
||
|
|
* PushButton(`text`: str, `parent`: QWidget = None, `icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* PushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
@singledispatchmethod
|
||
|
|
def __init__(self, parent: QWidget = None):
|
||
|
|
super().__init__(parent)
|
||
|
|
FluentStyleSheet.BUTTON.apply(self)
|
||
|
|
self.isPressed = False
|
||
|
|
self.isHover = False
|
||
|
|
self.setIconSize(QSize(16, 16))
|
||
|
|
self.setIcon(None)
|
||
|
|
setFont(self)
|
||
|
|
self._postInit()
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, text: str, parent: QWidget = None, icon: Union[QIcon, str, FluentIconBase] = None):
|
||
|
|
self.__init__(parent=parent)
|
||
|
|
self.setText(text)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: QIcon, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(text, parent, icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: FluentIconBase, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(text, parent, icon)
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def setIcon(self, icon: Union[QIcon, str, FluentIconBase]):
|
||
|
|
self.setProperty('hasIcon', icon is not None)
|
||
|
|
self.setStyle(QApplication.style())
|
||
|
|
self._icon = icon or QIcon()
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def icon(self):
|
||
|
|
return toQIcon(self._icon)
|
||
|
|
|
||
|
|
def setProperty(self, name: str, value) -> bool:
|
||
|
|
if name != 'icon':
|
||
|
|
return super().setProperty(name, value)
|
||
|
|
|
||
|
|
self.setIcon(value)
|
||
|
|
return True
|
||
|
|
|
||
|
|
def mousePressEvent(self, e):
|
||
|
|
self.isPressed = True
|
||
|
|
super().mousePressEvent(e)
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, e):
|
||
|
|
self.isPressed = False
|
||
|
|
super().mouseReleaseEvent(e)
|
||
|
|
|
||
|
|
def enterEvent(self, e):
|
||
|
|
self.isHover = True
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def leaveEvent(self, e):
|
||
|
|
self.isHover = False
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect, state=QIcon.Off):
|
||
|
|
""" draw icon """
|
||
|
|
drawIcon(icon, painter, rect, state)
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
super().paintEvent(e)
|
||
|
|
if self.icon().isNull():
|
||
|
|
return
|
||
|
|
|
||
|
|
painter = QPainter(self)
|
||
|
|
painter.setRenderHints(QPainter.Antialiasing |
|
||
|
|
QPainter.SmoothPixmapTransform)
|
||
|
|
|
||
|
|
if not self.isEnabled():
|
||
|
|
painter.setOpacity(0.3628)
|
||
|
|
elif self.isPressed:
|
||
|
|
painter.setOpacity(0.786)
|
||
|
|
|
||
|
|
w, h = self.iconSize().width(), self.iconSize().height()
|
||
|
|
y = (self.height() - h) / 2
|
||
|
|
mw = self.minimumSizeHint().width()
|
||
|
|
if mw > 0:
|
||
|
|
x = 12 + (self.width() - mw) // 2
|
||
|
|
else:
|
||
|
|
x = 12
|
||
|
|
|
||
|
|
if self.isRightToLeft():
|
||
|
|
x = self.width() - w - x
|
||
|
|
|
||
|
|
self._drawIcon(self._icon, painter, QRectF(x, y, w, h))
|
||
|
|
|
||
|
|
|
||
|
|
class PrimaryPushButton(PushButton):
|
||
|
|
""" Primary color push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PrimaryPushButton(`parent`: QWidget = None)
|
||
|
|
* PrimaryPushButton(`text`: str, `parent`: QWidget = None, `icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* PrimaryPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect, state=QIcon.Off):
|
||
|
|
if isinstance(icon, FluentIconBase) and self.isEnabled():
|
||
|
|
# reverse icon color
|
||
|
|
theme = Theme.DARK if not isDarkTheme() else Theme.LIGHT
|
||
|
|
icon = icon.icon(theme)
|
||
|
|
elif not self.isEnabled():
|
||
|
|
painter.setOpacity(0.786 if isDarkTheme() else 0.9)
|
||
|
|
if isinstance(icon, FluentIconBase):
|
||
|
|
icon = icon.icon(Theme.DARK)
|
||
|
|
|
||
|
|
PushButton._drawIcon(self, icon, painter, rect, state)
|
||
|
|
|
||
|
|
|
||
|
|
class TransparentPushButton(PushButton):
|
||
|
|
""" Transparent push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* TransparentPushButton(`parent`: QWidget = None)
|
||
|
|
* TransparentPushButton(`text`: str, `parent`: QWidget = None, `icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* TransparentPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
class ToggleButton(PushButton):
|
||
|
|
""" Toggle push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* ToggleButton(`parent`: QWidget = None)
|
||
|
|
* ToggleButton(`text`: str, `parent`: QWidget = None, `icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* ToggleButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
self.setCheckable(True)
|
||
|
|
self.setChecked(False)
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect):
|
||
|
|
if not self.isChecked():
|
||
|
|
return PushButton._drawIcon(self, icon, painter, rect)
|
||
|
|
|
||
|
|
PrimaryPushButton._drawIcon(self, icon, painter, rect, QIcon.On)
|
||
|
|
|
||
|
|
|
||
|
|
TogglePushButton = ToggleButton
|
||
|
|
|
||
|
|
|
||
|
|
class TransparentTogglePushButton(TogglePushButton):
|
||
|
|
""" Transparent toggle push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* TransparentTogglePushButton(`parent`: QWidget = None)
|
||
|
|
* TransparentTogglePushButton(`text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* TransparentTogglePushButton(`icon`: QIcon | FluentIconBase, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
class HyperlinkButton(PushButton):
|
||
|
|
""" Hyperlink button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* HyperlinkButton(`parent`: QWidget = None)
|
||
|
|
* HyperlinkButton(`url`: str, `text`: str, `parent`: QWidget = None, `icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* HyperlinkButton(`icon`: QIcon | FluentIconBase, `url`: str, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
@singledispatchmethod
|
||
|
|
def __init__(self, parent: QWidget = None):
|
||
|
|
super().__init__(parent)
|
||
|
|
self._url = QUrl()
|
||
|
|
FluentStyleSheet.BUTTON.apply(self)
|
||
|
|
self.setCursor(Qt.PointingHandCursor)
|
||
|
|
setFont(self)
|
||
|
|
self.clicked.connect(self._onClicked)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, url: str, text: str, parent: QWidget = None, icon: Union[QIcon, FluentIconBase, str] = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setText(text)
|
||
|
|
self.url.setUrl(url)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: QIcon, url: str, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(url, text, parent, icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: FluentIconBase, url: str, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(url, text, parent, icon)
|
||
|
|
|
||
|
|
def getUrl(self):
|
||
|
|
return self._url
|
||
|
|
|
||
|
|
def setUrl(self, url: Union[str, QUrl]):
|
||
|
|
self._url = QUrl(url)
|
||
|
|
|
||
|
|
def _onClicked(self):
|
||
|
|
if self.getUrl().isValid():
|
||
|
|
QDesktopServices.openUrl(self.getUrl())
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect, state=QIcon.Off):
|
||
|
|
if isinstance(icon, FluentIconBase) and self.isEnabled():
|
||
|
|
icon = icon.icon(color=themeColor())
|
||
|
|
elif not self.isEnabled():
|
||
|
|
painter.setOpacity(0.3628 if isDarkTheme() else 0.36)
|
||
|
|
|
||
|
|
drawIcon(icon, painter, rect, state)
|
||
|
|
|
||
|
|
url = Property(QUrl, getUrl, setUrl)
|
||
|
|
|
||
|
|
|
||
|
|
class RadioButton(QRadioButton):
|
||
|
|
""" Radio button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* RadioButton(`parent`: QWidget = None)
|
||
|
|
* RadioButton(`url`: text, `text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
@singledispatchmethod
|
||
|
|
def __init__(self, parent: QWidget = None):
|
||
|
|
super().__init__(parent)
|
||
|
|
self._lightTextColor = QColor(0, 0, 0)
|
||
|
|
self._darkTextColor = QColor(255, 255, 255)
|
||
|
|
self.lightIndicatorColor = QColor()
|
||
|
|
self.darkIndicatorColor = QColor()
|
||
|
|
self.indicatorPos = QPoint(11, 12)
|
||
|
|
self.isHover = False
|
||
|
|
|
||
|
|
FluentStyleSheet.BUTTON.apply(self)
|
||
|
|
self.setAttribute(Qt.WA_MacShowFocusRect, False)
|
||
|
|
self._postInit()
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setText(text)
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def enterEvent(self, e):
|
||
|
|
self.isHover = True
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def leaveEvent(self, e):
|
||
|
|
self.isHover = False
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
painter = QPainter(self)
|
||
|
|
painter.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
|
||
|
|
self._drawIndicator(painter)
|
||
|
|
self._drawText(painter)
|
||
|
|
|
||
|
|
def _drawText(self, painter: QPainter):
|
||
|
|
if not self.isEnabled():
|
||
|
|
painter.setOpacity(0.36)
|
||
|
|
|
||
|
|
painter.setFont(self.font())
|
||
|
|
painter.setPen(self.textColor())
|
||
|
|
painter.drawText(QRect(29, 0, self.width(), self.height()), Qt.AlignVCenter, self.text())
|
||
|
|
|
||
|
|
def _drawIndicator(self, painter: QPainter):
|
||
|
|
if self.isChecked():
|
||
|
|
if self.isEnabled():
|
||
|
|
borderColor = autoFallbackThemeColor(self.lightIndicatorColor, self.darkIndicatorColor)
|
||
|
|
else:
|
||
|
|
borderColor = QColor(255, 255, 255, 40) if isDarkTheme() else QColor(0, 0, 0, 55)
|
||
|
|
|
||
|
|
filledColor = Qt.black if isDarkTheme() else Qt.white
|
||
|
|
|
||
|
|
if self.isHover and not self.isDown():
|
||
|
|
self._drawCircle(painter, self.indicatorPos, 10, 4, borderColor, filledColor)
|
||
|
|
else:
|
||
|
|
self._drawCircle(painter, self.indicatorPos, 10, 5, borderColor, filledColor)
|
||
|
|
|
||
|
|
else:
|
||
|
|
if self.isEnabled():
|
||
|
|
if not self.isDown():
|
||
|
|
borderColor = QColor(255, 255, 255, 153) if isDarkTheme() else QColor(0, 0, 0, 153)
|
||
|
|
else:
|
||
|
|
borderColor = QColor(255, 255, 255, 40) if isDarkTheme() else QColor(0, 0, 0, 55)
|
||
|
|
|
||
|
|
if self.isDown():
|
||
|
|
filledColor = Qt.black if isDarkTheme() else Qt.white
|
||
|
|
elif self.isHover:
|
||
|
|
filledColor = QColor(255, 255, 255, 11) if isDarkTheme() else QColor(0, 0, 0, 15)
|
||
|
|
else:
|
||
|
|
filledColor = QColor(0, 0, 0, 26) if isDarkTheme() else QColor(0, 0, 0, 6)
|
||
|
|
else:
|
||
|
|
filledColor = Qt.transparent
|
||
|
|
borderColor = QColor(255, 255, 255, 40) if isDarkTheme() else QColor(0, 0, 0, 55)
|
||
|
|
|
||
|
|
self._drawCircle(painter, self.indicatorPos, 10, 1, borderColor, filledColor)
|
||
|
|
|
||
|
|
if self.isEnabled() and self.isDown():
|
||
|
|
borderColor = QColor(255, 255, 255, 40) if isDarkTheme() else QColor(0, 0, 0, 24)
|
||
|
|
self._drawCircle(painter, self.indicatorPos, 9, 4, borderColor, Qt.transparent)
|
||
|
|
|
||
|
|
def _drawCircle(self, painter: QPainter, center: QPoint, radius, thickness, borderColor, filledColor):
|
||
|
|
path = QPainterPath()
|
||
|
|
path.setFillRule(Qt.FillRule.WindingFill)
|
||
|
|
|
||
|
|
# outer circle (border)
|
||
|
|
outerRect = QRectF(center.x() - radius, center.y() - radius, 2 * radius, 2 * radius)
|
||
|
|
path.addEllipse(outerRect)
|
||
|
|
|
||
|
|
# inner center (filled)
|
||
|
|
ir = radius - thickness
|
||
|
|
innerRect = QRectF(center.x() - ir, center.y() - ir, 2 * ir, 2 * ir)
|
||
|
|
innerPath = QPainterPath()
|
||
|
|
innerPath.addEllipse(innerRect)
|
||
|
|
|
||
|
|
path = path.subtracted(innerPath)
|
||
|
|
|
||
|
|
# draw outer ring
|
||
|
|
painter.setPen(Qt.NoPen)
|
||
|
|
painter.fillPath(path, borderColor)
|
||
|
|
|
||
|
|
# fill inner circle
|
||
|
|
painter.fillPath(innerPath, filledColor)
|
||
|
|
|
||
|
|
def textColor(self):
|
||
|
|
return self.darkTextColor if isDarkTheme() else self.lightTextColor
|
||
|
|
|
||
|
|
def getLightTextColor(self) -> QColor:
|
||
|
|
return self._lightTextColor
|
||
|
|
|
||
|
|
def getDarkTextColor(self) -> QColor:
|
||
|
|
return self._darkTextColor
|
||
|
|
|
||
|
|
def setLightTextColor(self, color: QColor):
|
||
|
|
self._lightTextColor = QColor(color)
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def setDarkTextColor(self, color: QColor):
|
||
|
|
self._darkTextColor = QColor(color)
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def setIndicatorColor(self, light, dark):
|
||
|
|
self.lightIndicatorColor = QColor(light)
|
||
|
|
self.darkIndicatorColor = QColor(dark)
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def setTextColor(self, light, dark):
|
||
|
|
self.setLightTextColor(light)
|
||
|
|
self.setDarkTextColor(dark)
|
||
|
|
|
||
|
|
lightTextColor = Property(QColor, getLightTextColor, setLightTextColor)
|
||
|
|
darkTextColor = Property(QColor, getDarkTextColor, setDarkTextColor)
|
||
|
|
|
||
|
|
|
||
|
|
class ToolButton(QToolButton):
|
||
|
|
""" Tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* ToolButton(`parent`: QWidget = None)
|
||
|
|
* ToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
@singledispatchmethod
|
||
|
|
def __init__(self, parent: QWidget = None):
|
||
|
|
super().__init__(parent)
|
||
|
|
FluentStyleSheet.BUTTON.apply(self)
|
||
|
|
self.isPressed = False
|
||
|
|
self.isHover = False
|
||
|
|
self.setIconSize(QSize(16, 16))
|
||
|
|
self.setIcon(QIcon())
|
||
|
|
setFont(self)
|
||
|
|
self._postInit()
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: FluentIconBase, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: QIcon, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: str, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def setIcon(self, icon: Union[QIcon, str, FluentIconBase]):
|
||
|
|
self._icon = icon
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def icon(self):
|
||
|
|
return toQIcon(self._icon)
|
||
|
|
|
||
|
|
def setProperty(self, name: str, value) -> bool:
|
||
|
|
if name != 'icon':
|
||
|
|
return super().setProperty(name, value)
|
||
|
|
|
||
|
|
self.setIcon(value)
|
||
|
|
return True
|
||
|
|
|
||
|
|
def mousePressEvent(self, e):
|
||
|
|
self.isPressed = True
|
||
|
|
super().mousePressEvent(e)
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, e):
|
||
|
|
self.isPressed = False
|
||
|
|
super().mouseReleaseEvent(e)
|
||
|
|
|
||
|
|
def enterEvent(self, e):
|
||
|
|
self.isHover = True
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def leaveEvent(self, e):
|
||
|
|
self.isHover = False
|
||
|
|
self.update()
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter: QPainter, rect: QRectF, state=QIcon.Off):
|
||
|
|
""" draw icon """
|
||
|
|
drawIcon(icon, painter, rect, state)
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
super().paintEvent(e)
|
||
|
|
if self._icon is None:
|
||
|
|
return
|
||
|
|
|
||
|
|
painter = QPainter(self)
|
||
|
|
painter.setRenderHints(QPainter.Antialiasing |
|
||
|
|
QPainter.SmoothPixmapTransform)
|
||
|
|
|
||
|
|
if not self.isEnabled():
|
||
|
|
painter.setOpacity(0.43)
|
||
|
|
elif self.isPressed:
|
||
|
|
painter.setOpacity(0.63)
|
||
|
|
|
||
|
|
w, h = self.iconSize().width(), self.iconSize().height()
|
||
|
|
y = (self.height() - h) / 2
|
||
|
|
x = (self.width() - w) / 2
|
||
|
|
self._drawIcon(self._icon, painter, QRectF(x, y, w, h))
|
||
|
|
|
||
|
|
|
||
|
|
class TransparentToolButton(ToolButton):
|
||
|
|
""" Transparent background tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* TransparentToolButton(`parent`: QWidget = None)
|
||
|
|
* TransparentToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
class PrimaryToolButton(ToolButton):
|
||
|
|
""" Primary color tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PrimaryToolButton(`parent`: QWidget = None)
|
||
|
|
* PrimaryToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter: QPainter, rect: QRectF, state=QIcon.Off):
|
||
|
|
if isinstance(icon, FluentIconBase) and self.isEnabled():
|
||
|
|
# reverse icon color
|
||
|
|
theme = Theme.DARK if not isDarkTheme() else Theme.LIGHT
|
||
|
|
icon = icon.icon(theme)
|
||
|
|
elif isinstance(icon, Icon) and self.isEnabled():
|
||
|
|
theme = Theme.DARK if not isDarkTheme() else Theme.LIGHT
|
||
|
|
icon = icon.fluentIcon.icon(theme)
|
||
|
|
elif not self.isEnabled():
|
||
|
|
painter.setOpacity(0.786 if isDarkTheme() else 0.9)
|
||
|
|
if isinstance(icon, FluentIconBase):
|
||
|
|
icon = icon.icon(Theme.DARK)
|
||
|
|
|
||
|
|
return drawIcon(icon, painter, rect, state)
|
||
|
|
|
||
|
|
|
||
|
|
class ToggleToolButton(ToolButton):
|
||
|
|
""" Toggle tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* ToggleToolButton(`parent`: QWidget = None)
|
||
|
|
* ToggleToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
self.setCheckable(True)
|
||
|
|
self.setChecked(False)
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect):
|
||
|
|
if not self.isChecked():
|
||
|
|
return ToolButton._drawIcon(self, icon, painter, rect)
|
||
|
|
|
||
|
|
PrimaryToolButton._drawIcon(self, icon, painter, rect, QIcon.On)
|
||
|
|
|
||
|
|
|
||
|
|
class TransparentToggleToolButton(ToggleToolButton):
|
||
|
|
""" Transparent toggle tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* TransparentToggleToolButton(`parent`: QWidget = None)
|
||
|
|
* TransparentToggleToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
class DropDownButtonBase:
|
||
|
|
""" Drop down button base class """
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super().__init__(*args, **kwargs)
|
||
|
|
self._menu = None
|
||
|
|
self.arrowAni = TranslateYAnimation(self)
|
||
|
|
|
||
|
|
def setMenu(self, menu: RoundMenu):
|
||
|
|
self._menu = menu
|
||
|
|
|
||
|
|
def menu(self) -> RoundMenu:
|
||
|
|
return self._menu
|
||
|
|
|
||
|
|
def _showMenu(self):
|
||
|
|
if not self.menu():
|
||
|
|
return
|
||
|
|
|
||
|
|
menu = self.menu()
|
||
|
|
menu.view.setMinimumWidth(self.width())
|
||
|
|
menu.view.adjustSize()
|
||
|
|
menu.adjustSize()
|
||
|
|
|
||
|
|
# determine the animation type by choosing the maximum height of view
|
||
|
|
x = -menu.width()//2 + menu.layout().contentsMargins().left() + self.width()//2
|
||
|
|
pd = self.mapToGlobal(QPoint(x, self.height()))
|
||
|
|
hd = menu.view.heightForAnimation(pd, MenuAnimationType.DROP_DOWN)
|
||
|
|
|
||
|
|
pu = self.mapToGlobal(QPoint(x, 0))
|
||
|
|
hu = menu.view.heightForAnimation(pu, MenuAnimationType.PULL_UP)
|
||
|
|
|
||
|
|
if hd >= hu:
|
||
|
|
menu.view.adjustSize(pd, MenuAnimationType.DROP_DOWN)
|
||
|
|
menu.exec(pd, aniType=MenuAnimationType.DROP_DOWN)
|
||
|
|
else:
|
||
|
|
menu.view.adjustSize(pu, MenuAnimationType.PULL_UP)
|
||
|
|
menu.exec(pu, aniType=MenuAnimationType.PULL_UP)
|
||
|
|
|
||
|
|
def _hideMenu(self):
|
||
|
|
if self.menu():
|
||
|
|
self.menu().hide()
|
||
|
|
|
||
|
|
def _drawDropDownIcon(self, painter, rect):
|
||
|
|
if isDarkTheme():
|
||
|
|
FIF.ARROW_DOWN.render(painter, rect)
|
||
|
|
else:
|
||
|
|
FIF.ARROW_DOWN.render(painter, rect, fill="#646464")
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
painter = QPainter(self)
|
||
|
|
painter.setRenderHints(QPainter.Antialiasing)
|
||
|
|
if self.isHover:
|
||
|
|
painter.setOpacity(0.8)
|
||
|
|
elif self.isPressed:
|
||
|
|
painter.setOpacity(0.7)
|
||
|
|
|
||
|
|
rect = QRectF(self.width()-22, self.height() /
|
||
|
|
2-5+self.arrowAni.y, 10, 10)
|
||
|
|
self._drawDropDownIcon(painter, rect)
|
||
|
|
|
||
|
|
|
||
|
|
class DropDownPushButton(DropDownButtonBase, PushButton):
|
||
|
|
""" Drop down push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* DropDownPushButton(`parent`: QWidget = None)
|
||
|
|
* DropDownPushButton(`text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* DropDownPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, e):
|
||
|
|
PushButton.mouseReleaseEvent(self, e)
|
||
|
|
self._showMenu()
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
PushButton.paintEvent(self, e)
|
||
|
|
DropDownButtonBase.paintEvent(self, e)
|
||
|
|
|
||
|
|
|
||
|
|
class TransparentDropDownPushButton(DropDownPushButton):
|
||
|
|
""" Transparent drop down push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* TransparentDropDownPushButton(`parent`: QWidget = None)
|
||
|
|
* TransparentDropDownPushButton(`text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* TransparentDropDownPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
class DropDownToolButton(DropDownButtonBase, ToolButton):
|
||
|
|
""" Drop down tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* DropDownToolButton(`parent`: QWidget = None)
|
||
|
|
* DropDownToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, e):
|
||
|
|
ToolButton.mouseReleaseEvent(self, e)
|
||
|
|
self._showMenu()
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect: QRectF):
|
||
|
|
rect.moveLeft(12)
|
||
|
|
return super()._drawIcon(icon, painter, rect)
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
ToolButton.paintEvent(self, e)
|
||
|
|
DropDownButtonBase.paintEvent(self, e)
|
||
|
|
|
||
|
|
|
||
|
|
class TransparentDropDownToolButton(DropDownToolButton):
|
||
|
|
""" Transparent drop down tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* TransparentDropDownToolButton(`parent`: QWidget = None)
|
||
|
|
* TransparentDropDownToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
|
||
|
|
class PrimaryDropDownButtonBase(DropDownButtonBase):
|
||
|
|
""" Primary color drop down button base class """
|
||
|
|
|
||
|
|
def _drawDropDownIcon(self, painter, rect):
|
||
|
|
theme = Theme.DARK if not isDarkTheme() else Theme.LIGHT
|
||
|
|
FIF.ARROW_DOWN.render(painter, rect, theme)
|
||
|
|
|
||
|
|
|
||
|
|
class PrimaryDropDownPushButton(PrimaryDropDownButtonBase, PrimaryPushButton):
|
||
|
|
""" Primary color drop down push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PrimaryDropDownPushButton(`parent`: QWidget = None)
|
||
|
|
* PrimaryDropDownPushButton(`text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* PrimaryDropDownPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, e):
|
||
|
|
PrimaryPushButton.mouseReleaseEvent(self, e)
|
||
|
|
self._showMenu()
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
PrimaryPushButton.paintEvent(self, e)
|
||
|
|
PrimaryDropDownButtonBase.paintEvent(self, e)
|
||
|
|
|
||
|
|
|
||
|
|
class PrimaryDropDownToolButton(PrimaryDropDownButtonBase, PrimaryToolButton):
|
||
|
|
""" Primary drop down tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PrimaryDropDownToolButton(`parent`: QWidget = None)
|
||
|
|
* PrimaryDropDownToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def mouseReleaseEvent(self, e):
|
||
|
|
PrimaryToolButton.mouseReleaseEvent(self, e)
|
||
|
|
self._showMenu()
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect: QRectF):
|
||
|
|
rect.moveLeft(12)
|
||
|
|
return super()._drawIcon(icon, painter, rect)
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
PrimaryToolButton.paintEvent(self, e)
|
||
|
|
PrimaryDropDownButtonBase.paintEvent(self, e)
|
||
|
|
|
||
|
|
|
||
|
|
class SplitDropButton(ToolButton):
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
self.arrowAni = TranslateYAnimation(self)
|
||
|
|
self.setIcon(FIF.ARROW_DOWN)
|
||
|
|
self.setIconSize(QSize(10, 10))
|
||
|
|
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect):
|
||
|
|
rect.translate(0, self.arrowAni.y)
|
||
|
|
|
||
|
|
if self.isPressed:
|
||
|
|
painter.setOpacity(0.5)
|
||
|
|
elif self.isHover:
|
||
|
|
painter.setOpacity(1)
|
||
|
|
else:
|
||
|
|
painter.setOpacity(0.63)
|
||
|
|
|
||
|
|
super()._drawIcon(icon, painter, rect)
|
||
|
|
|
||
|
|
|
||
|
|
class PrimarySplitDropButton(PrimaryToolButton):
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
self.arrowAni = TranslateYAnimation(self)
|
||
|
|
self.setIcon(FIF.ARROW_DOWN)
|
||
|
|
self.setIconSize(QSize(10, 10))
|
||
|
|
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||
|
|
|
||
|
|
def _drawIcon(self, icon, painter, rect):
|
||
|
|
rect.translate(0, self.arrowAni.y)
|
||
|
|
|
||
|
|
if self.isPressed:
|
||
|
|
painter.setOpacity(0.7)
|
||
|
|
elif self.isHover:
|
||
|
|
painter.setOpacity(0.9)
|
||
|
|
else:
|
||
|
|
painter.setOpacity(1)
|
||
|
|
|
||
|
|
if isinstance(icon, FluentIconBase):
|
||
|
|
icon = icon.icon(Theme.DARK if not isDarkTheme() else Theme.LIGHT)
|
||
|
|
|
||
|
|
super()._drawIcon(icon, painter, rect)
|
||
|
|
|
||
|
|
|
||
|
|
class SplitWidgetBase(QWidget):
|
||
|
|
""" Split widget base class """
|
||
|
|
|
||
|
|
dropDownClicked = Signal()
|
||
|
|
|
||
|
|
def __init__(self, parent=None):
|
||
|
|
super().__init__(parent=parent)
|
||
|
|
self.flyout = None # type: QWidget
|
||
|
|
self.dropButton = SplitDropButton(self)
|
||
|
|
|
||
|
|
self.hBoxLayout = QHBoxLayout(self)
|
||
|
|
self.hBoxLayout.setSpacing(0)
|
||
|
|
self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
|
||
|
|
self.hBoxLayout.addWidget(self.dropButton)
|
||
|
|
|
||
|
|
self.dropButton.clicked.connect(self.dropDownClicked)
|
||
|
|
self.dropButton.clicked.connect(self.showFlyout)
|
||
|
|
|
||
|
|
self.setAttribute(Qt.WA_TranslucentBackground)
|
||
|
|
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||
|
|
|
||
|
|
def setWidget(self, widget: QWidget):
|
||
|
|
""" set the widget on left side """
|
||
|
|
self.hBoxLayout.insertWidget(0, widget, 1, Qt.AlignLeft)
|
||
|
|
|
||
|
|
def setDropButton(self, button):
|
||
|
|
""" set drop dow button """
|
||
|
|
self.hBoxLayout.removeWidget(self.dropButton)
|
||
|
|
self.dropButton.deleteLater()
|
||
|
|
|
||
|
|
self.dropButton = button
|
||
|
|
self.dropButton.clicked.connect(self.dropDownClicked)
|
||
|
|
self.dropButton.clicked.connect(self.showFlyout)
|
||
|
|
self.hBoxLayout.addWidget(button)
|
||
|
|
|
||
|
|
def setDropIcon(self, icon: Union[str, QIcon, FluentIconBase]):
|
||
|
|
""" set the icon of drop down button """
|
||
|
|
self.dropButton.setIcon(icon)
|
||
|
|
self.dropButton.removeEventFilter(self.dropButton.arrowAni)
|
||
|
|
|
||
|
|
def setDropIconSize(self, size: QSize):
|
||
|
|
""" set the icon size of drop down button """
|
||
|
|
self.dropButton.setIconSize(size)
|
||
|
|
|
||
|
|
def setFlyout(self, flyout):
|
||
|
|
""" set the widget pops up when drop down button is clicked
|
||
|
|
|
||
|
|
Parameters
|
||
|
|
----------
|
||
|
|
flyout: QWidget
|
||
|
|
the widget pops up when drop down button is clicked.
|
||
|
|
It should contain `exec(pos: QPoint)` method
|
||
|
|
"""
|
||
|
|
self.flyout = flyout
|
||
|
|
|
||
|
|
def showFlyout(self):
|
||
|
|
""" show flyout """
|
||
|
|
if not self.flyout:
|
||
|
|
return
|
||
|
|
|
||
|
|
w = self.flyout
|
||
|
|
|
||
|
|
if isinstance(w, RoundMenu):
|
||
|
|
w.view.setMinimumWidth(self.width())
|
||
|
|
w.view.adjustSize()
|
||
|
|
w.adjustSize()
|
||
|
|
|
||
|
|
dx = w.layout().contentsMargins().left() if isinstance(w, RoundMenu) else 0
|
||
|
|
x = -w.width()//2 + dx + self.width()//2
|
||
|
|
y = self.height()
|
||
|
|
w.exec(self.mapToGlobal(QPoint(x, y)))
|
||
|
|
|
||
|
|
|
||
|
|
class SplitPushButton(SplitWidgetBase):
|
||
|
|
""" Split push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* SplitPushButton(`parent`: QWidget = None)
|
||
|
|
* SplitPushButton(`text`: str, `parent`: QWidget = None, `icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
clicked = Signal()
|
||
|
|
|
||
|
|
@singledispatchmethod
|
||
|
|
def __init__(self, parent: QWidget = None):
|
||
|
|
super().__init__(parent=parent)
|
||
|
|
self.button = PushButton(self)
|
||
|
|
self.button.setObjectName('splitPushButton')
|
||
|
|
self.button.clicked.connect(self.clicked)
|
||
|
|
self.setWidget(self.button)
|
||
|
|
self._postInit()
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, text: str, parent: QWidget = None, icon: Union[QIcon, str, FluentIconBase] = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setText(text)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: QIcon, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(text, parent, icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: FluentIconBase, text: str, parent: QWidget = None):
|
||
|
|
self.__init__(text, parent, icon)
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def text(self):
|
||
|
|
return self.button.text()
|
||
|
|
|
||
|
|
def setText(self, text: str):
|
||
|
|
self.button.setText(text)
|
||
|
|
self.adjustSize()
|
||
|
|
|
||
|
|
def icon(self):
|
||
|
|
return self.button.icon()
|
||
|
|
|
||
|
|
def setIcon(self, icon: Union[QIcon, FluentIconBase, str]):
|
||
|
|
self.button.setIcon(icon)
|
||
|
|
|
||
|
|
def setIconSize(self, size: QSize):
|
||
|
|
self.button.setIconSize(size)
|
||
|
|
|
||
|
|
text_ = Property(str, text, setText)
|
||
|
|
icon_ = Property(QIcon, icon, setIcon)
|
||
|
|
|
||
|
|
|
||
|
|
class PrimarySplitPushButton(SplitPushButton):
|
||
|
|
""" Primary split push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PrimarySplitPushButton(`parent`: QWidget = None)
|
||
|
|
* PrimarySplitPushButton(`text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* PrimarySplitPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
self.setDropButton(PrimarySplitDropButton(self))
|
||
|
|
|
||
|
|
self.hBoxLayout.removeWidget(self.button)
|
||
|
|
self.button.deleteLater()
|
||
|
|
|
||
|
|
self.button = PrimaryPushButton(self)
|
||
|
|
self.button.setObjectName('primarySplitPushButton')
|
||
|
|
self.button.clicked.connect(self.clicked)
|
||
|
|
self.setWidget(self.button)
|
||
|
|
|
||
|
|
|
||
|
|
class SplitToolButton(SplitWidgetBase):
|
||
|
|
""" Split tool button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* SplitToolButton(`parent`: QWidget = None)
|
||
|
|
* SplitToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
clicked = Signal()
|
||
|
|
|
||
|
|
@singledispatchmethod
|
||
|
|
def __init__(self, parent: QWidget = None):
|
||
|
|
super().__init__(parent=parent)
|
||
|
|
self.button = ToolButton(self)
|
||
|
|
self.button.setObjectName('splitToolButton')
|
||
|
|
self.button.clicked.connect(self.clicked)
|
||
|
|
self.setWidget(self.button)
|
||
|
|
self._postInit()
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: FluentIconBase, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: QIcon, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
@__init__.register
|
||
|
|
def _(self, icon: str, parent: QWidget = None):
|
||
|
|
self.__init__(parent)
|
||
|
|
self.setIcon(icon)
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def icon(self):
|
||
|
|
return self.button.icon()
|
||
|
|
|
||
|
|
def setIcon(self, icon: Union[QIcon, FluentIconBase, str]):
|
||
|
|
self.button.setIcon(icon)
|
||
|
|
|
||
|
|
def setIconSize(self, size: QSize):
|
||
|
|
self.button.setIconSize(size)
|
||
|
|
|
||
|
|
icon_ = Property(QIcon, icon, setIcon)
|
||
|
|
|
||
|
|
|
||
|
|
class PrimarySplitToolButton(SplitToolButton):
|
||
|
|
""" Primary split push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PrimarySplitToolButton(`parent`: QWidget = None)
|
||
|
|
* PrimarySplitToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def _postInit(self):
|
||
|
|
self.setDropButton(PrimarySplitDropButton(self))
|
||
|
|
|
||
|
|
self.hBoxLayout.removeWidget(self.button)
|
||
|
|
self.button.deleteLater()
|
||
|
|
|
||
|
|
self.button = PrimaryToolButton(self)
|
||
|
|
self.button.setObjectName('primarySplitToolButton')
|
||
|
|
self.button.clicked.connect(self.clicked)
|
||
|
|
self.setWidget(self.button)
|
||
|
|
|
||
|
|
|
||
|
|
class PillButtonBase:
|
||
|
|
""" Pill button base class """
|
||
|
|
|
||
|
|
def __init__(self, *args, **kwargs):
|
||
|
|
super().__init__(*args, **kwargs)
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
painter = QPainter(self)
|
||
|
|
painter.setRenderHints(QPainter.Antialiasing)
|
||
|
|
isDark = isDarkTheme()
|
||
|
|
|
||
|
|
if not self.isChecked():
|
||
|
|
rect = self.rect().adjusted(1, 1, -1, -1)
|
||
|
|
borderColor = QColor(255, 255, 255, 18) if isDark else QColor(0, 0, 0, 15)
|
||
|
|
|
||
|
|
if not self.isEnabled():
|
||
|
|
bgColor = QColor(255, 255, 255, 11) if isDark else QColor(249, 249, 249, 75)
|
||
|
|
elif self.isPressed or self.isHover:
|
||
|
|
bgColor = QColor(255, 255, 255, 21) if isDark else QColor(249, 249, 249, 128)
|
||
|
|
else:
|
||
|
|
bgColor = QColor(255, 255, 255, 15) if isDark else QColor(243, 243, 243, 194)
|
||
|
|
|
||
|
|
else:
|
||
|
|
if not self.isEnabled():
|
||
|
|
bgColor = QColor(255, 255, 255, 40) if isDark else QColor(0, 0, 0, 55)
|
||
|
|
elif self.isPressed:
|
||
|
|
bgColor = ThemeColor.DARK_2.color() if isDark else ThemeColor.LIGHT_3.color()
|
||
|
|
elif self.isHover:
|
||
|
|
bgColor = ThemeColor.DARK_1.color() if isDark else ThemeColor.LIGHT_1.color()
|
||
|
|
else:
|
||
|
|
bgColor = themeColor()
|
||
|
|
|
||
|
|
borderColor = Qt.transparent
|
||
|
|
rect = self.rect()
|
||
|
|
|
||
|
|
painter.setPen(borderColor)
|
||
|
|
painter.setBrush(bgColor)
|
||
|
|
|
||
|
|
r = rect.height() / 2
|
||
|
|
painter.drawRoundedRect(rect, r, r)
|
||
|
|
|
||
|
|
|
||
|
|
class PillPushButton(TogglePushButton, PillButtonBase):
|
||
|
|
""" Pill push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PillPushButton(`parent`: QWidget = None)
|
||
|
|
* PillPushButton(`text`: str, `parent`: QWidget = None,
|
||
|
|
`icon`: QIcon | str | FluentIconBase = None)
|
||
|
|
* PillPushButton(`icon`: QIcon | FluentIcon, `text`: str, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
PillButtonBase.paintEvent(self, e)
|
||
|
|
TogglePushButton.paintEvent(self, e)
|
||
|
|
|
||
|
|
|
||
|
|
class PillToolButton(ToggleToolButton, PillButtonBase):
|
||
|
|
""" Pill push button
|
||
|
|
|
||
|
|
Constructors
|
||
|
|
------------
|
||
|
|
* PillToolButton(`parent`: QWidget = None)
|
||
|
|
* PillToolButton(`icon`: QIcon | str | FluentIconBase, `parent`: QWidget = None)
|
||
|
|
"""
|
||
|
|
|
||
|
|
def paintEvent(self, e):
|
||
|
|
PillButtonBase.paintEvent(self, e)
|
||
|
|
ToggleToolButton.paintEvent(self, e)
|