Introduction¶
qstylizer is a python package designed to help with the construction of Qt stylesheets.
The typical way of setting a stylesheet in PyQt is like this:
widget = QtWidgets.QWidget()
widget.setStyleSheet("""
QTabBar {
border-radius: 3px;
background-color: green;
}
QTabBar:focus {
border: 0px transparent black;
background-color: red;
}
QTabBar::close-button {
background: transparent;
}
""")
This approach floods the python code with ugly multi-line strings everywhere.
The qstylizer way:
import qstylizer.style
css = qstylizer.style.StyleSheet()
css.QTabBar.setValues(
borderRadius="3px",
backgroundColor="green"
)
css.QTabBar.focus.setValues(
border="0px transparent black",
backgroundColor="red"
)
css.QTabBar.closeButton.background.setValue("transparent")
widget = QtWidgets.QMainWindow()
widget.setStyleSheet(css.toString())
qstylizer stores style rule objects in a dictionary hierarchy.
The above example maps to this hierarchy:
<StyleSheet dict={
"QTabBar": <ClassRule name="QTabBar" dict={
"border-radius": <PropRule name="border-radius" value="3px" />,
"background-color": <PropRule name="background-color" value="green" />,
"focus": <PseudoStateRule name="focus" dict={
"border": <PropRule name="border" value="0px transparent black" />,
"background-color": <PropRule name="background-color" value="red" />,
} />
"close-button": <SubControlRule name="close-button" dict={
"background": <PropRule name="background" value="transparent" />,
}/>
} />
} />
A StyleRule object is basically just an ordered dictionary with the keys as the style rule property names and the values as the style rule property values. Any attempt to get a dictionary value in the instance will add a key and value into the dictionary (the style rule property:values).
If qstylizer incorrectly determines that close-button is a pseudostate instead of a subcontrol, the colons can be specified in the key:
css.QTabBar["::close-button"].background.setValue("transparent")
Because of the hierarchical nature, the following are all valid:
css.QTabBar.closeButton.background.setValue("transparent")
css["QTabBar"].closeButton.background.setValue("transparent")
css["QTabBar"]["close-button"].background.setValue("transparent")
css["QTabBar"]["close-button"]["background"].setValue("transparent")
css["QTabBar"]["::close-button"]["background"].setValue("transparent")
css["QTabBar::close-button"].background.setValue("transparent")
css["QTabBar::close-button"]["background"].setValue("transparent")
How Does it Work?¶
How does qstylizer determine what is a QClass, subcontrol, or pseudostate? The package itself stores a list of known options for each type.
>>> qstylizer.style.rule_class("QTabBar")
<class 'qstylizer.style.ClassRule'>
>>> qstylizer.style.rule_class("close-button")
<class 'qstylizer.style.SubControlRule'>
>>> qstylizer.style.rule_class("hover")
<class 'qstylizer.style.PseudoStateRule'>
Advantages¶
What are the advantages? Ease of use and cleaner code. There is no need to worry about scope operators, brackets, and semi-colons.