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 logging
import nw 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.QtGui import QPainter
from PyQt5.QtWidgets import (
QAbstractButton, from nw.constants import nwUnicode
QApplication,
QHBoxLayout,
QSizePolicy,
QWidget,
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class Switch(QAbstractButton): class QSwitch(QAbstractButton):
def __init__(self, parent=None, track_radius=10, thumb_radius=8):
def __init__(self, parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
self.setCheckable(True) self.setCheckable(True)
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self._track_radius = track_radius self._trackRadius = 10
self._thumb_radius = thumb_radius self._thumbRadius = 8
self._margin = max(0, self._thumb_radius - self._track_radius) self._margin = max(0, self._thumbRadius - self._trackRadius)
self._base_offset = max(self._thumb_radius, self._track_radius) self._baseOffset = max(self._thumbRadius, self._trackRadius)
self._end_offset = { self._endOffset = {
True: lambda: self.width() - self._base_offset, True: lambda: self.width() - self._baseOffset,
False: lambda: self._base_offset, False: lambda: self._baseOffset,
} }
self._offset = self._base_offset self._offset = self._baseOffset
palette = self.palette() palette = self.palette()
if self._thumb_radius > self._track_radius: if self._thumbRadius > self._trackRadius:
self._track_color = { self._trackColor = {
True: palette.highlight(), True: palette.highlight(),
False: palette.dark(), False: palette.dark(),
} }
self._thumb_color = { self._thumbColor = {
True: palette.highlight(), True: palette.highlight(),
False: palette.light(), False: palette.light(),
} }
self._text_color = { self._textColor = {
True: palette.highlightedText().color(), True: palette.highlightedText().color(),
False: palette.dark().color(), False: palette.dark().color(),
} }
self._thumb_text = { self._thumbText = {
True: '', True: '',
False: '', False: '',
} }
self._track_opacity = 0.5 self._trackOpacity = 0.5
else: else:
self._thumb_color = { self._thumbColor = {
True: palette.highlightedText(), True: palette.highlightedText(),
False: palette.light(), False: palette.light(),
} }
self._track_color = { self._trackColor = {
True: palette.highlight(), True: palette.highlight(),
False: palette.dark(), False: palette.dark(),
} }
self._text_color = { self._textColor = {
True: palette.highlight().color(), True: palette.highlight().color(),
False: palette.dark().color(), False: palette.dark().color(),
} }
self._thumb_text = { self._thumbText = {
True: '', True: nwUnicode.U_CHECK,
False: '', False: nwUnicode.U_MULT,
} }
self._track_opacity = 1 self._trackOpacity = 1
##
# Properties
##
@pyqtProperty(int) @pyqtProperty(int)
def offset(self): def offset(self):
@@ -110,114 +112,128 @@ class Switch(QAbstractButton):
def offset(self, value): def offset(self, value):
self._offset = value self._offset = value
self.update() self.update()
return
def sizeHint(self): # pylint: disable=invalid-name ##
return QSize( # Getters and Setters
4 * self._track_radius + 2 * self._margin, ##
2 * self._track_radius + 2 * self._margin,
) 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): def setChecked(self, checked):
super().setChecked(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): def resizeEvent(self, event):
"""Overload resize to ensure correct offset.
"""
super().resizeEvent(event) 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 def paintEvent(self, event):
p = QPainter(self) """Drawing the switch itself.
p.setRenderHint(QPainter.Antialiasing, True) """
p.setPen(Qt.NoPen) qPaint = QPainter(self)
track_opacity = self._track_opacity qPaint.setRenderHint(QPainter.Antialiasing, True)
thumb_opacity = 1.0 qPaint.setPen(Qt.NoPen)
text_opacity = 1.0 trackOpacity = self._trackOpacity
thumbOpacity = 1.0
textOpacity = 1.0
if self.isEnabled(): if self.isEnabled():
track_brush = self._track_color[self.isChecked()] trackBrush = self._trackColor[self.isChecked()]
thumb_brush = self._thumb_color[self.isChecked()] thumbBrush = self._thumbColor[self.isChecked()]
text_color = self._text_color[self.isChecked()] textColor = self._textColor[self.isChecked()]
else: else:
track_opacity *= 0.8 trackOpacity *= 0.8
track_brush = self.palette().shadow() trackBrush = self.palette().shadow()
thumb_brush = self.palette().mid() thumbBrush = self.palette().mid()
text_color = self.palette().shadow().color() textColor = self.palette().shadow().color()
p.setBrush(track_brush) qPaint.setBrush(trackBrush)
p.setOpacity(track_opacity) qPaint.setOpacity(trackOpacity)
p.drawRoundedRect( qPaint.drawRoundedRect(
self._margin, self._margin,
self._margin, self._margin,
self.width() - 2 * self._margin, self.width() - 2*self._margin,
self.height() - 2 * self._margin, self.height() - 2*self._margin,
self._track_radius, self._trackRadius,
self._track_radius, self._trackRadius,
) )
p.setBrush(thumb_brush) qPaint.setBrush(thumbBrush)
p.setOpacity(thumb_opacity) qPaint.setOpacity(thumbOpacity)
p.drawEllipse( qPaint.drawEllipse(
self.offset - self._thumb_radius, self.offset - self._thumbRadius,
self._base_offset - self._thumb_radius, self._baseOffset - self._thumbRadius,
2 * self._thumb_radius, 2*self._thumbRadius,
2 * self._thumb_radius, 2*self._thumbRadius,
) )
p.setPen(text_color) qPaint.setPen(textColor)
p.setOpacity(text_opacity) qPaint.setOpacity(textOpacity)
font = p.font() theFont = qPaint.font()
font.setPixelSize(1.5 * self._thumb_radius) theFont.setPixelSize(1.5*self._thumbRadius)
p.setFont(font) qPaint.setFont(theFont)
p.drawText( qPaint.drawText(
QRectF( QRectF(
self.offset - self._thumb_radius, self.offset - self._thumbRadius,
self._base_offset - self._thumb_radius, self._baseOffset - self._thumbRadius,
2 * self._thumb_radius, 2*self._thumbRadius,
2 * self._thumb_radius, 2*self._thumbRadius,
), ),
Qt.AlignCenter, 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) super().mouseReleaseEvent(event)
if event.button() == Qt.LeftButton: if event.button() == Qt.LeftButton:
anim = QPropertyAnimation(self, b'offset', self) doAnim = QPropertyAnimation(self, b'offset', self)
anim.setDuration(120) doAnim.setDuration(120)
anim.setStartValue(self.offset) doAnim.setStartValue(self.offset)
anim.setEndValue(self._end_offset[self.isChecked()]()) doAnim.setEndValue(self._endOffset[self.isChecked()]())
anim.start() 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) self.setCursor(Qt.PointingHandCursor)
super().enterEvent(event) super().enterEvent(event)
return
# END Class QSwitch
# 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()
+4
View File
@@ -233,6 +233,8 @@ class nwUnicode:
## Other ## Other
U_NBSP = "\u00a0" # Non-breaking space U_NBSP = "\u00a0" # Non-breaking space
U_PARA = "\u2029" # Paragraph separator U_PARA = "\u2029" # Paragraph separator
U_CHECK = "\u2714" # Heavy check mark
U_MULT = "\u2715" # Multiplication x
## Arrows ## Arrows
U_UTRI = "\u2bc5" # Up-pointing triangle U_UTRI = "\u2bc5" # Up-pointing triangle
@@ -270,6 +272,8 @@ class nwUnicode:
## Other ## Other
H_NBSP = "&nbsp;" H_NBSP = "&nbsp;"
H_CHECK = "&#10004;"
H_MULT = "&#10005;"
## Arrows ## Arrows
H_UTRI = "&#11205;" H_UTRI = "&#11205;"