Modifying widget colour at runtime without overwriting stylesheet
pyside, python, qt, qtstylesheets
Solution
You can use dynamic properties to do this:
from PySide import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.edit = QtGui.QLineEdit(self)
self.edit.setProperty('warning', False)
self.edit.setStyleSheet("""
/* other rules go here */
QLineEdit[warning="true"] {background-color: yellow};
QLineEdit[warning="false"] {background-color: palette(base)};
""")
self.button = QtGui.QPushButton('Test', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
layout.addWidget(self.button)
def handleButton(self):
self.edit.setProperty(
'warning', not self.edit.property('warning'))
self.edit.style().unpolish(self.edit)
self.edit.style().polish(self.edit)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
Problem
My situation: I have a widget that has a stylesheet set. That stylesheet may or may not include colour settings. I want to change the colour of the widget, but I can't just do `widget.setStyleSheet("QWidget {background-color: %s}"% colour)`, because that replaces the existing stylesheet, which I don't want to do. My Question: What is the correct method for changing the (background, in my case) colour of a widget without erasing that widget's stylesheet? Is there a better method than parsing and appending to the style sheet? Example: In the code below, how can I change the colour of `box` (imagining that the box's colour must change dynamically; e.g., the box is red when it contains an even number of items, and green when the number is odd)? ``` import sys from PySide import QtGui, QtCore class Example(QtGui.QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): box = QtGui.QComboBox(self) box.resize(box.sizeHint()) box.setStyleSheet(""" QComboBox::drop-down {border-width: 0px;} QComboBox::down-arrow {image: url(noimg); border-width: 0px;} """) box.move(50, 50) #Using the palette doesn't work: pal = box.palette() pal.setColor(box.backgroundRole(), QtCore.Qt.red) box.setAutoFillBackground(True) box.setPalette(pal) self.setGeometry(300, 300, 250, 150) self.show() if __name__ == '__main__': app = QtGui.QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) ``` Using the box's pallet doesn't work, presumably as per this warning on the `autoFillBackground` method: Warning: Use this property with caution in conjunction with Qt Style Sheets. When a widget has a style sheet with a valid background or a border-image, this property is automatically disabled.