Hi @martin i’m using pyside2 5.13.2.
Hi don’t understand why changing :
xPos = contRect.x() + handleRadius + trailLength * self._handle_position
to
xPos = contRect.x() + handleRadius + trailLength * self.handle_position
would override Qt property, i’m just accessing it.
Here is the minimum changes I had to do to make it work :
class Toggle(QCheckBox):
_transparent_pen = QPen(Qt.transparent)
_light_grey_pen = QPen(Qt.lightGray)
def __init__(self,
parent=None,
bar_color=Qt.gray,
checked_color="#00B0FF",
handle_color=Qt.white,
):
super().__init__(parent)
self._handle_position = 0
self._pulse_radius = 0
# Save our properties on the object via self, so we can access them later
# in the paintEvent.
self._bar_brush = QBrush(bar_color)
self._bar_checked_brush = QBrush(QColor(checked_color).lighter())
self._handle_brush = QBrush(handle_color)
self._handle_checked_brush = QBrush(QColor(checked_color))
# Setup the rest of the widget.
self.setContentsMargins(8, 0, 8, 0)
self.stateChanged.connect(self.handle_state_change)
@Property(int)
def handle_position(self):
return int(self._handle_position)
@handle_position.setter
def handle_position(self, pos):
"""change the property
we need to trigger QWidget.update() method, either by:
1- calling it here [ what we're doing ].
2- connecting the QPropertyAnimation.valueChanged() signal to it.
"""
self._handle_position = pos
self.update()
@Property(float)
def pulse_radius(self):
return self._pulse_radius
@pulse_radius.setter
def pulse_radius(self, pos):
self._pulse_radius = pos
self.update()
def sizeHint(self):
return QSize(48, 45)
def hitButton(self, pos: QPoint):
return self.contentsRect().contains(pos)
def paintEvent(self, e: QPaintEvent):
contRect = self.contentsRect()
handleRadius = round(0.24 * contRect.height())
p = QPainter(self)
p.setRenderHint(QPainter.Antialiasing)
p.setPen(self._transparent_pen)
barRect = QRectF(0, 0, contRect.width() - handleRadius, 0.40 * contRect.height())
barRect.moveCenter(contRect.center())
rounding = barRect.height() / 2
# the handle will move along this line
trailLength = contRect.width() - 2 * handleRadius
xPos = contRect.x() + handleRadius + trailLength * self.handle_position
if self.isChecked():
p.setBrush(self._bar_checked_brush)
p.drawRoundedRect(barRect, rounding, rounding)
p.setBrush(self._handle_checked_brush)
else:
p.setBrush(self._bar_brush)
p.drawRoundedRect(barRect, rounding, rounding)
p.setPen(self._light_grey_pen)
p.setBrush(self._handle_brush)
p.drawEllipse(
QPointF(xPos, barRect.center().y()),
handleRadius, handleRadius)
p.end()
@Slot(int)
def handle_state_change(self, value):
self.handle_position = 1 if value else 0