Updated the switch class to match code standard

This commit is contained in:
Veronica K. B. Olsen
2020-05-03 12:45:58 +02:00
parent e088b03c04
commit 1fe9ff0af7
2 changed files with 136 additions and 116 deletions
+132 -116
View File
@@ -35,72 +35,74 @@
import logging
import nw
from PyQt5.QtCore import QPropertyAnimation, QRectF, QSize, Qt, pyqtProperty
from PyQt5.QtCore import Qt, QSize, QRectF, QPropertyAnimation, pyqtProperty
from PyQt5.QtWidgets import QAbstractButton, QSizePolicy
from PyQt5.QtGui import QPainter
from PyQt5.QtWidgets import (
QAbstractButton,
QApplication,
QHBoxLayout,
QSizePolicy,
QWidget,
)
from nw.constants import nwUnicode
logger = logging.getLogger(__name__)
class Switch(QAbstractButton):
def __init__(self, parent=None, track_radius=10, thumb_radius=8):
class QSwitch(QAbstractButton):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setCheckable(True)
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self._track_radius = track_radius
self._thumb_radius = thumb_radius
self._trackRadius = 10
self._thumbRadius = 8
self._margin = max(0, self._thumb_radius - self._track_radius)
self._base_offset = max(self._thumb_radius, self._track_radius)
self._end_offset = {
True: lambda: self.width() - self._base_offset,
False: lambda: self._base_offset,
self._margin = max(0, self._thumbRadius - self._trackRadius)
self._baseOffset = max(self._thumbRadius, self._trackRadius)
self._endOffset = {
True: lambda: self.width() - self._baseOffset,
False: lambda: self._baseOffset,
}
self._offset = self._base_offset
self._offset = self._baseOffset
palette = self.palette()
if self._thumb_radius > self._track_radius:
self._track_color = {
if self._thumbRadius > self._trackRadius:
self._trackColor = {
True: palette.highlight(),
False: palette.dark(),
}
self._thumb_color = {
self._thumbColor = {
True: palette.highlight(),
False: palette.light(),
}
self._text_color = {
self._textColor = {
True: palette.highlightedText().color(),
False: palette.dark().color(),
}
self._thumb_text = {
self._thumbText = {
True: '',
False: '',
}
self._track_opacity = 0.5
self._trackOpacity = 0.5
else:
self._thumb_color = {
self._thumbColor = {
True: palette.highlightedText(),
False: palette.light(),
}
self._track_color = {
self._trackColor = {
True: palette.highlight(),
False: palette.dark(),
}
self._text_color = {
self._textColor = {
True: palette.highlight().color(),
False: palette.dark().color(),
}
self._thumb_text = {
True: '',
False: '',
self._thumbText = {
True: nwUnicode.U_CHECK,
False: nwUnicode.U_MULT,
}
self._track_opacity = 1
self._trackOpacity = 1
##
# Properties
##
@pyqtProperty(int)
def offset(self):
@@ -110,114 +112,128 @@ class Switch(QAbstractButton):
def offset(self, value):
self._offset = value
self.update()
return
def sizeHint(self): # pylint: disable=invalid-name
return QSize(
4 * self._track_radius + 2 * self._margin,
2 * self._track_radius + 2 * self._margin,
)
##
# Getters and Setters
##
def trackRadius(self):
return self._trackRadius
def setTrackRadius(self, theValue):
if isinstance(theValue, int):
if theValue > 0:
self._trackRadius = theValue
return
raise ValueError("trackRadius must be an integer > 0")
self.update()
return
def thumbRadius(self):
return self._thumbRadius
def setThumbRadius(self, theValue):
if isinstance(theValue, int):
if theValue > 0:
self._thumbRadius = theValue
return
raise ValueError("thumbRadius must be an integer > 0")
self.update()
return
def setChecked(self, checked):
super().setChecked(checked)
self.offset = self._end_offset[checked]()
self.offset = self._endOffset[checked]()
def sizeHint(self):
return QSize(
4 * self._trackRadius + 2 * self._margin,
2 * self._trackRadius + 2 * self._margin,
)
##
# Events
##
def resizeEvent(self, event):
"""Overload resize to ensure correct offset.
"""
super().resizeEvent(event)
self.offset = self._end_offset[self.isChecked()]()
self.offset = self._endOffset[self.isChecked()]()
return
def paintEvent(self, event): # pylint: disable=invalid-name, unused-argument
p = QPainter(self)
p.setRenderHint(QPainter.Antialiasing, True)
p.setPen(Qt.NoPen)
track_opacity = self._track_opacity
thumb_opacity = 1.0
text_opacity = 1.0
def paintEvent(self, event):
"""Drawing the switch itself.
"""
qPaint = QPainter(self)
qPaint.setRenderHint(QPainter.Antialiasing, True)
qPaint.setPen(Qt.NoPen)
trackOpacity = self._trackOpacity
thumbOpacity = 1.0
textOpacity = 1.0
if self.isEnabled():
track_brush = self._track_color[self.isChecked()]
thumb_brush = self._thumb_color[self.isChecked()]
text_color = self._text_color[self.isChecked()]
trackBrush = self._trackColor[self.isChecked()]
thumbBrush = self._thumbColor[self.isChecked()]
textColor = self._textColor[self.isChecked()]
else:
track_opacity *= 0.8
track_brush = self.palette().shadow()
thumb_brush = self.palette().mid()
text_color = self.palette().shadow().color()
trackOpacity *= 0.8
trackBrush = self.palette().shadow()
thumbBrush = self.palette().mid()
textColor = self.palette().shadow().color()
p.setBrush(track_brush)
p.setOpacity(track_opacity)
p.drawRoundedRect(
qPaint.setBrush(trackBrush)
qPaint.setOpacity(trackOpacity)
qPaint.drawRoundedRect(
self._margin,
self._margin,
self.width() - 2 * self._margin,
self.height() - 2 * self._margin,
self._track_radius,
self._track_radius,
self.width() - 2*self._margin,
self.height() - 2*self._margin,
self._trackRadius,
self._trackRadius,
)
p.setBrush(thumb_brush)
p.setOpacity(thumb_opacity)
p.drawEllipse(
self.offset - self._thumb_radius,
self._base_offset - self._thumb_radius,
2 * self._thumb_radius,
2 * self._thumb_radius,
qPaint.setBrush(thumbBrush)
qPaint.setOpacity(thumbOpacity)
qPaint.drawEllipse(
self.offset - self._thumbRadius,
self._baseOffset - self._thumbRadius,
2*self._thumbRadius,
2*self._thumbRadius,
)
p.setPen(text_color)
p.setOpacity(text_opacity)
font = p.font()
font.setPixelSize(1.5 * self._thumb_radius)
p.setFont(font)
p.drawText(
qPaint.setPen(textColor)
qPaint.setOpacity(textOpacity)
theFont = qPaint.font()
theFont.setPixelSize(1.5*self._thumbRadius)
qPaint.setFont(theFont)
qPaint.drawText(
QRectF(
self.offset - self._thumb_radius,
self._base_offset - self._thumb_radius,
2 * self._thumb_radius,
2 * self._thumb_radius,
self.offset - self._thumbRadius,
self._baseOffset - self._thumbRadius,
2*self._thumbRadius,
2*self._thumbRadius,
),
Qt.AlignCenter,
self._thumb_text[self.isChecked()],
self._thumbText[self.isChecked()],
)
return
def mouseReleaseEvent(self, event): # pylint: disable=invalid-name
def mouseReleaseEvent(self, event):
"""Animate the switch.
"""
super().mouseReleaseEvent(event)
if event.button() == Qt.LeftButton:
anim = QPropertyAnimation(self, b'offset', self)
anim.setDuration(120)
anim.setStartValue(self.offset)
anim.setEndValue(self._end_offset[self.isChecked()]())
anim.start()
doAnim = QPropertyAnimation(self, b'offset', self)
doAnim.setDuration(120)
doAnim.setStartValue(self.offset)
doAnim.setEndValue(self._endOffset[self.isChecked()]())
doAnim.start()
return
def enterEvent(self, event): # pylint: disable=invalid-name
def enterEvent(self, event):
"""Change the cursor when hovering the button.
"""
self.setCursor(Qt.PointingHandCursor)
super().enterEvent(event)
return
# def main():
# app = QApplication([])
# # Thumb size < track size (Gitlab style)
# s1 = Switch()
# s1.toggled.connect(lambda c: print('toggled', c))
# s1.clicked.connect(lambda c: print('clicked', c))
# s1.pressed.connect(lambda: print('pressed'))
# s1.released.connect(lambda: print('released'))
# s2 = Switch()
# s2.setEnabled(False)
# # Thumb size > track size (Android style)
# s3 = Switch(thumb_radius=11, track_radius=8)
# s4 = Switch(thumb_radius=11, track_radius=8)
# s4.setEnabled(False)
# l = QHBoxLayout()
# l.addWidget(s1)
# l.addWidget(s2)
# l.addWidget(s3)
# l.addWidget(s4)
# w = QWidget()
# w.setLayout(l)
# w.show()
# app.exec()
# if __name__ == '__main__':
# main()
# END Class QSwitch
+4
View File
@@ -233,6 +233,8 @@ class nwUnicode:
## Other
U_NBSP = "\u00a0" # Non-breaking space
U_PARA = "\u2029" # Paragraph separator
U_CHECK = "\u2714" # Heavy check mark
U_MULT = "\u2715" # Multiplication x
## Arrows
U_UTRI = "\u2bc5" # Up-pointing triangle
@@ -270,6 +272,8 @@ class nwUnicode:
## Other
H_NBSP = "&nbsp;"
H_CHECK = "&#10004;"
H_MULT = "&#10005;"
## Arrows
H_UTRI = "&#11205;"