Set properties of custom widget from qss stylesheet

I was following along with the Animating custom widgets with QPropertyAnimation tutorial and I really like the custom toggle this tutorial demonstrates. I would love to use the AnimatedToggle widget in the GUIs that I create. However, my current project is using a QSS stylesheet to set the color scheme of the app; users can select the style they want (i.e. light or dark) in the preferences menu.

Where I am stuck is figuring out how to set the colors of the custom widget using the stylesheet that is applied globally to the app.

The beginning of the class in the tutorial is

class AnimatedToggle(QCheckBox):

    _transparent_pen = QPen(Qt.GlobalColor.transparent)
    _light_grey_pen = QPen(Qt.GlobalColor.lightGray)

    def __init__(self,
        parent=None,
        bar_color=Qt.GlobalColor.gray,
        checked_color="#00B0FF",
        handle_color=Qt.GlobalColor.white,
        pulse_unchecked_color="#44999999",
        pulse_checked_color="#4400B0EE"
        ):
        super().__init__(parent)

        # 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))

        self._pulse_unchecked_animation = QBrush(QColor(pulse_unchecked_color))
        self._pulse_checked_animation = QBrush(QColor(pulse_checked_color))

and the portion of the code the colors are used is

def paintEvent(self, e: QPaintEvent):

        contRect = self.contentsRect()
        handleRadius = round(0.24 * contRect.height())

        p = QPainter(self)
        p.setRenderHint(QPainter.RenderHint.Antialiasing)

        p.setPen(self._transparent_pen)
        barRect = QRectF(
            0, 0,
            contRect.width() - handleRadius, 0.40 * contRect.height()
        )
        barRect.moveCenter(QPointF(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.pulse_anim.state() == QPropertyAnimation.State.Running:
            p.setBrush(
                self._pulse_checked_animation if
                self.isChecked() else self._pulse_unchecked_animation)
            p.drawEllipse(QPointF(xPos, barRect.center().y()),
                          self._pulse_radius, self._pulse_radius)

        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()

What I want to do is use a QSS file with something like:

AnimatedToggle {
    bar-color: #888888;
    checked-color: #00B0FF;
    handle-color: #FFFFFF;
    pulse-unchecked-color: #44999999;
    pulse-checked-color: #4400B0FF;
    transparent-pen-color: #00FFFFFF;
    grey-pen-color: #888888 ;
}

Can you please point me in the right direction of how to modify the AnimatedToggle class to be able to accept the assignments from the QSS file?

I’ll take a stab at this…

I’ve found (from my past with CSS stylesheets) that when you attempt globally some or most of the settings get in the way.

It’s a bit more work (more code) but applying directly to widgets custom or native provides more flexibility in the long run. Apps I’ve worked on create widgets on the fly so global styling wouldn’t work for me.

Hope this helps you out !