As a simple example, suppose I have a QPushButton
that has some basic styling applied to it using button.setStyleSheet()
. Additionally, I want some parts of the style (background color) to change in response to events triggered by the user.
I could simply make calls to button.setStyleSheet()
throughout my code, but these will erase pre-existing style attributes. So I would not be able to edit just one styling attribute in response to some signal, rather I would have to specify all style attributes every time the style changes (even if only one or a few style attributes are actually being modified).
I understand this can be done more neatly with the QSS property selector which can apparently be used with "any Qt property that supports QVariant::toString()
". This is also described for C here: dynamic properties & stylesheets.
So suppose I have a custom widget class, and I want some of its styling to depend (responsively) on a property of my custom class, e.g. a state
property. It sounds like I should be able to do something like
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtCore import pyqtProperty
class StatefulWidget(QPushButton):
""" QPushButton colored to reflect its state. """
def __init__(self, state=0):
super().__init__()
self.state = state
self.setStyleSheet('''
StatefulWidget[state=0] {
background-color: red;
}
StatefulWidget[state=1] {
background-color: green;
}
''')
@pyqtProperty(int)
def state(self):
return self._state
@state.setter
def state(self, state):
# Register change of state
self._state = state
# Update displayed style
self.style().polish(self)
but this does not work for me.
Can anyone suggest the proper way to make this work? The intended behavior is that the style should be updated whenever the property changes, but the underlying CSS/QSS should be fixed.
Related:
CodePudding user response:
The documentation about the QSS property selector says:
You may use this selector to test for any Qt property that supports QVariant::toString()
The QSS parser code is quite complex and somehow cryptic, and I've never been able to completely follow its logic, but I believe that it always tries to convert string values to numbers whenever they contain digits, so the 0
value for the QSS property selector will not match the "0"
resulting from toString()
.
As a general rule, always use quotes around values:
self.setStyleSheet('''
StatefulWidget[state="0"] {
background-color: red;
}
StatefulWidget[state="1"] {
background-color: green;
}
''')