Die Stylesheet-Syntax
Die Terminologie und die syntaktischen Regeln von Qt Style Sheets sind fast identisch mit denen von HTML CSS. Wenn Sie CSS bereits kennen, können Sie diesen Abschnitt wahrscheinlich schnell überfliegen.
Style-Regeln
Style Sheets bestehen aus einer Folge von Style-Regeln. Eine Stilregel setzt sich aus einem Selektor und einer Deklaration zusammen. Der Selektor gibt an, welche Widgets von der Regel betroffen sind; die Deklaration gibt an, welche Eigenschaften für das Widget festgelegt werden sollen. Zum Beispiel:
QPushButton { color: red }
In der obigen Stilregel ist QPushButton
der Selektor und { color: red }
ist die Deklaration. Die Regel gibt an, dass QPushButton und seine Unterklassen (z. B. MyPushButton
) Rot als Vordergrundfarbe verwenden sollen.
Qt Style Sheet unterscheidet im Allgemeinen nicht zwischen Groß- und Kleinschreibung (d.h. color
, Color
, COLOR
und cOloR
beziehen sich auf die gleiche Eigenschaft). Die einzigen Ausnahmen sind Klassennamen, object names und Qt-Eigenschaftsnamen, bei denen Groß- und Kleinschreibung unterschieden wird.
Mehrere Selektoren können für dieselbe Deklaration angegeben werden, wobei die Selektoren durch Kommas (,
) getrennt werden. Zum Beispiel kann die Regel
QPushButton, QLineEdit, QComboBox { color: red }
ist äquivalent zu dieser Folge von drei Regeln:
QPushButton { color: red } QLineEdit { color: red } QComboBox { color: red }
Der Deklarationsteil einer Stilregel ist eine Liste von property: value
Paaren, die in geschweifte Klammern ({}
) eingeschlossen und durch Semikolons getrennt sind. Zum Beispiel:
QPushButton { color: red; background-color: white }
Die Liste der von Qt Widgets bereitgestellten Eigenschaften finden Sie im Abschnitt Liste der Eigenschaften weiter unten.
Selektor-Typen
In allen bisherigen Beispielen wurde der einfachste Selektortyp, der Type Selector, verwendet. Qt Style Sheets unterstützen alle in CSS2 definierten Selektoren. Die folgende Tabelle fasst die nützlichsten Typen von Selektoren zusammen.
Selektor | Beispiel | Erläuterung |
---|---|---|
Universeller Selektor | * | Passt zu allen Widgets. |
Typ-Selektor | QPushButton | Passt auf Instanzen von QPushButton und seiner Unterklassen. |
Eigenschaften-Selektor | QPushButton[flat="false"] | Passt auf Instanzen von QPushButton, die nicht flat sind. Sie können diesen Selektor verwenden, um auf jede Qt-Eigenschaft zu testen, die QVariant::toString() unterstützt (siehe die Dokumentation der Funktion toString() für weitere Details). Darüber hinaus wird die spezielle Eigenschaft class für den Namen der Klasse unterstützt.Dieser Selektor kann auch verwendet werden, um dynamische Eigenschaften zu testen. Weitere Informationen zur Anpassung mit dynamischen Eigenschaften finden Sie unter Anpassen mit dynamischen Eigenschaften. Anstelle von Achtung! Wenn sich der Wert der Qt-Eigenschaft ändert, nachdem die Stilvorlage festgelegt wurde, kann es notwendig sein, eine Neuberechnung der Stilvorlage zu erzwingen. Eine Möglichkeit, dies zu erreichen, besteht darin, die Stilvorlage zu deaktivieren und erneut zu aktivieren. |
Klassen-Selektor | .QPushButton | Passt auf Instanzen von QPushButton, aber nicht auf deren Unterklassen. Dies ist äquivalent zu |
ID Selektor | QPushButton#okButton | Findet alle QPushButton Instanzen, deren object name okButton ist. |
Descendant Selektor | QDialog QPushButton | Findet alle Instanzen von QPushButton, die Nachkommen (Kinder, Enkel, etc.) eines QDialog sind. |
Kind Selektor | QDialog > QPushButton | Findet alle Instanzen von QPushButton, die direkte Kinder von QDialog sind. |
Untergeordnete Steuerelemente
Für das Styling komplexer Widgets ist es notwendig, auf Untersteuerungen des Widgets zuzugreifen, wie z. B. die Dropdown-Schaltfläche eines QComboBox oder die Auf- und Abwärtspfeile eines QSpinBox. Selektoren können Untersteuerungen enthalten, die es ermöglichen, die Anwendung einer Regel auf bestimmte Widget-Untersteuerungen zu beschränken. Zum Beispiel:
QComboBox::drop-down { image: url(dropdown.png) }
Die obige Regel formatiert die Dropdown-Schaltfläche aller QComboBoxes. Obwohl die Syntax des Doppelpunkts (::
) an CSS3 Pseudo-Elemente erinnert, unterscheiden sich Qt Sub-Controls konzeptionell von diesen und haben eine andere Kaskadierungssemantik.
Sub-Controls werden immer in Bezug auf ein anderes Element positioniert - ein Referenzelement. Dieses Referenzelement kann das Widget oder ein anderes Sub-Control sein. Zum Beispiel wird das ::drop-down eines QComboBox standardmäßig in der oberen rechten Ecke des Padding-Rechtecks des QComboBox platziert. Das ::drop-down wird standardmäßig in der Mitte des Contents-Rechtecks des ::drop-down-Untersteuerelements platziert. In der Liste der stilisierbaren Widgets unten finden Sie die Untersteuerelemente, mit denen Sie ein Widget stilisieren können, sowie deren Standardpositionen.
Das zu verwendende Ursprungsrechteck kann mit der Eigenschaft subcontrol-origin geändert werden. Wenn wir zum Beispiel das Dropdown im Rand-Rechteck von QComboBox anstelle des Standard-Padding-Rechtecks platzieren möchten, können wir dies angeben:
Die Ausrichtung des Dropdowns innerhalb des Randrechtecks wird mit der Eigenschaft subcontrol-position geändert.
Die Eigenschaften width und height können verwendet werden, um die Größe des Sub-Controls zu steuern. Beachten Sie, dass die Einstellung eines Bildes implizit die Größe eines Untersteuerelements festlegt.
Das relative Positionierungsschema(position: relative) ermöglicht es, die Position des Untersteuerelements von seiner Ausgangsposition zu verschieben. Wenn z. B. die Dropdown-Schaltfläche von QComboBox gedrückt wird, soll der Pfeil darin versetzt werden, um einen "gedrückten" Effekt zu erzeugen. Um dies zu erreichen, können wir angeben:
QComboBox::down-arrow { image: url(down_arrow.png); } QComboBox::down-arrow:pressed { position: relative; top: 1px; left: 1px; }
Das absolute Positionierungsschema(position: absolute) ermöglicht es, die Position und Größe des Untersteuerelements in Bezug auf das Referenzelement zu ändern.
Nach der Positionierung werden sie wie Widgets behandelt und können mithilfe des Box-Modells gestaltet werden.
Eine Liste der unterstützten Untersteuerelemente finden Sie in der Liste der Untersteuerelemente weiter unten, und ein realistisches Beispiel finden Sie unter Anpassen des Untersteuerelements QPushButton's Menu Indicator.
Hinweis: Wenn bei komplexen Widgets wie QComboBox und QScrollBar eine Eigenschaft oder ein Untersteuerelement angepasst wird, müssen auch alle anderen Eigenschaften oder Untersteuerelemente angepasst werden.
Pseudo-Zustände
Selektoren können Pseudozustände enthalten, die die Anwendung der Regel auf der Grundlage des Zustands des Widgets einschränken. Pseudo-Zustände erscheinen am Ende des Selektors, mit einem Doppelpunkt (:
) dazwischen. Die folgende Regel gilt beispielsweise, wenn der Mauszeiger über einem QPushButton schwebt:
QPushButton:hover { color: white }
Pseudo-Zustände können mit dem Ausrufezeichen-Operator negiert werden. Die folgende Regel gilt zum Beispiel, wenn der Mauszeiger nicht über einem QRadioButton schwebt:
QRadioButton:!hover { color: red }
Pseudo-Zustände können verkettet werden, in diesem Fall wird ein logisches UND impliziert. Die folgende Regel gilt beispielsweise, wenn der Mauszeiger über ein angekreuztes QCheckBox bewegt wird:
QCheckBox:hover:checked { color: white }
Negierte Pseudo-Zustände können in Pseudo-Zustandsketten erscheinen. Die folgende Regel gilt z. B., wenn der Mauszeiger über einem nicht gedrückten QPushButton schwebt:
QPushButton:hover:!pressed { color: blue; }
Falls erforderlich, kann die logische ODER-Verknüpfung durch den Komma-Operator ausgedrückt werden:
Pseudo-Zustände können in Kombination mit Untersteuerungen auftreten. Zum Beispiel:
QComboBox::drop-down:hover { image: url(dropdown_bright.png) }
Im Abschnitt Liste der Pseudozustände unten finden Sie eine Liste der Pseudozustände, die von Qt Widgets bereitgestellt werden.
Konfliktauflösung
Konflikte entstehen, wenn mehrere Stilregeln dieselben Eigenschaften mit unterschiedlichen Werten spezifizieren. Betrachten Sie die folgende Stilvorlage:
QPushButton#okButton { color: gray } QPushButton { color: red }
Beide Regeln entsprechen QPushButton Instanzen mit dem Namen okButton
und es gibt einen Konflikt für die Eigenschaft color
. Um diesen Konflikt aufzulösen, müssen wir die Spezifität der Selektoren berücksichtigen. Im obigen Beispiel wird QPushButton#okButton
als spezifischer angesehen als QPushButton
, da es sich (normalerweise) auf ein einzelnes Objekt und nicht auf alle Instanzen einer Klasse bezieht.
In ähnlicher Weise sind Selektoren mit Pseudo-Zuständen spezifischer als solche, die keine Pseudo-Zustände angeben. So legt die folgende Stilvorlage fest, dass ein QPushButton weißen Text haben soll, wenn die Maus darüber schwebt, ansonsten roten Text:
QPushButton:hover { color: white } QPushButton { color: red }
Hier ist eine knifflige Frage:
QPushButton:hover { color: white } QPushButton:enabled { color: red }
Hier haben beide Selektoren die gleiche Spezifität. Wenn also die Maus über die Schaltfläche bewegt wird, während sie aktiviert ist, hat die zweite Regel Vorrang. Wenn wir wollen, dass der Text in diesem Fall weiß ist, können wir die Regeln wie folgt neu anordnen:
QPushButton:enabled { color: red } QPushButton:hover { color: white }
Alternativ dazu können wir die erste Regel spezifischer gestalten:
QPushButton:hover:enabled { color: white } QPushButton:enabled { color: red }
Ein ähnliches Problem ergibt sich in Verbindung mit Type Selectors. Betrachten Sie das folgende Beispiel:
QPushButton { color: red } QAbstractButton { color: gray }
Beide Regeln gelten für QPushButton Instanzen (da QPushButton von QAbstractButton erbt) und es gibt einen Konflikt für die Eigenschaft color. Da QPushButton von QAbstractButton erbt, könnte man annehmen, dass QPushButton
spezifischer ist als QAbstractButton
. Für Stylesheet-Berechnungen haben jedoch alle Type Selectors die gleiche Spezifität, und die Regel, die zuletzt erscheint, hat Vorrang. Mit anderen Worten, die Farbe wird für alle QAbstractButtons auf gray
gesetzt, einschließlich QPushButtons. Wenn wir wirklich wollen, dass QPushButtons roten Text hat, können wir die Regeln jederzeit neu anordnen.
Um die Spezifität einer Regel zu bestimmen, folgen Qt Style Sheets der CSS2-Spezifikation:
Die Spezifität eines Selektors wird wie folgt berechnet:
- Zählen Sie die Anzahl der ID-Attribute im Selektor (= a)
- Zählen Sie die Anzahl der anderen Attribute und Pseudoklassen im Selektor (= b)
- Zählen der Anzahl der Elementnamen im Selektor (= c)
- Pseudo-Elemente [d.h. Subcontrols] werden ignoriert.
Die Verkettung der drei Zahlen a-b-c (in einem Zahlensystem mit einer großen Basis) ergibt die Spezifität.
Einige Beispiele:
* {} /* a=0 b=0 c=0 -> specificity = 0 */ LI {} /* a=0 b=0 c=1 -> specificity = 1 */ UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */ UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */ H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */ UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */ LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */ #x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
Kaskadierung
Stilvorlagen können auf QApplication, auf übergeordneten Widgets und auf untergeordneten Widgets festgelegt werden. Das effektive Stylesheet eines beliebigen Widgets ergibt sich aus der Zusammenführung der Stylesheets, die auf den Vorgängern des Widgets (Eltern, Großeltern usw.) eingestellt sind, sowie aus allen Stylesheets, die auf QApplication eingestellt sind.
Bei Konflikten wird die eigene Stilvorlage des Widgets immer der geerbten Stilvorlage vorgezogen, unabhängig von der Spezifität der widersprüchlichen Regeln. Ebenso wird die Stilvorlage des übergeordneten Widgets gegenüber der des Großelternteils bevorzugt usw.
Eine Folge davon ist, dass das Setzen einer Stilregel für ein Widget automatisch Vorrang vor anderen Regeln hat, die in den Stilvorlagen der Vorgänger-Widgets oder in der Stilvorlage QApplication angegeben sind. Betrachten Sie das folgende Beispiel. Zuerst legen wir eine Stilvorlage für das QApplication fest:
qApp->setStyleSheet("QPushButton { color: white }");
Dann legen wir eine Stilvorlage für ein QPushButton Objekt fest:
myPushButton->setStyleSheet("* { color: blue }");
Die Formatvorlage auf QPushButton zwingt QPushButton (und alle untergeordneten Widgets) dazu, blauen Text zu verwenden, obwohl die anwendungsweite Formatvorlage spezifischere Regeln vorsieht.
Das Ergebnis wäre das gleiche gewesen, wenn wir geschrieben hätten
myPushButton->setStyleSheet("color: blue");
geschrieben hätten, mit der Ausnahme, dass, wenn QPushButton Kinder hätte (was unwahrscheinlich ist), die Stilvorlage keinen Einfluss auf diese hätte.
Die Kaskadierung von Stylesheets ist ein komplexes Thema. In der CSS2-Spezifikation finden Sie die genauen Details. Beachten Sie, dass Qt derzeit keine !important
implementiert.
Vererbung
Im klassischen CSS werden Schriftart und -farbe eines Elements, wenn sie nicht explizit festgelegt werden, automatisch vom übergeordneten Element geerbt. Standardmäßig erbt ein Widget bei der Verwendung von Qt Style Sheets nicht automatisch seine Schrift- und Farbeinstellungen von seinem übergeordneten Widget.
Nehmen wir zum Beispiel ein QPushButton innerhalb eines QGroupBox:
qApp->setStyleSheet("QGroupBox { color: red; } ");
Das QPushButton hat keine explizite Farbeinstellung. Anstatt die Farbe des übergeordneten QGroupBox zu erben, hat es daher die Systemfarbe. Wenn wir die Farbe eines QGroupBox und seiner Kinder einstellen wollen, können wir schreiben:
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
Im Gegensatz dazu wird die Einstellung einer Schriftart und einer Palette mit QWidget::setFont() und QWidget::setPalette() auf untergeordnete Widgets übertragen.
Wenn Sie es vorziehen, dass die Schriftart und die Palette auf untergeordnete Widgets übertragen werden, können Sie das Flag Qt::AA_UseStyleSheetPropagationInWidgetStyles setzen, wie folgt:
Verwendung:
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
Wenn die Weitergabe von Schriftart und Palette im Widget-Stil aktiviert ist, verhalten sich Schriftart- und Palettenänderungen, die über Qt Style Sheets vorgenommen wurden, so, als ob der Benutzer die entsprechenden Methoden QWidget::setPalette() und QWidget::setFont() auf allen QWidgets, auf die das Style Sheet abzielt, manuell aufgerufen hätte.
- Änderungen, die durch ein Stylesheet vorgenommen werden, werden propagiert. Sie werden an alle Widgets, die dem Stylesheet entsprechen, einmal zum Zeitpunkt der Änderung übertragen.
- Änderungen, die durch den Aufruf von QWidget::setPalette() oder QWidget::setFont() vorgenommen wurden, werden vererbt. Sie werden an alle bestehenden und zukünftigen untergeordneten Widgets vererbt, für die der entsprechende Pinsel oder die Schriftart nicht explizit festgelegt wurde.
Widgets innerhalb von C++-Namensräumen
Der Type Selector kann verwendet werden, um Widgets eines bestimmten Typs zu gestalten. Zum Beispiel,
class MyPushButton : public QPushButton { // ...}// ...qApp->setStyleSheet("MyPushButton { background: yellow; }");
Qt Style Sheet verwendet QObject::className() des Widgets, um zu bestimmen, wann der Type Selector angewendet werden soll. Wenn benutzerdefinierte Widgets innerhalb von Namespaces sind, gibt QObject::className() <Namespace>::<classname> zurück. Dies steht im Konflikt mit der Syntax für Sub-Controls. Um dieses Problem zu lösen, müssen wir bei der Verwendung des Type Selector für Widgets innerhalb von Namespaces die ::
durch --
ersetzen. Zum Beispiel,
namespace ns { class MyPushButton : public QPushButton { // ...} }// ...qApp->setStyleSheet("ns--MyPushButton { background: yellow; }");
QObject-Eigenschaften setzen
Ab 4.3 und höher kann jede gestaltbare Q_PROPERTY mit der Syntax qproperty-<Eigenschaftsname> gesetzt werden.
Zum Beispiel,
MyLabel { qproperty-pixmap: url(pixmap.png); } MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); } QPushButton { qproperty-iconSize: 20px 20px; }
Wenn die Eigenschaft auf ein Enum verweist, das mit Q_ENUM deklariert wurde, sollten Sie dessen Konstanten mit ihrem Namen referenzieren, nicht mit ihrem numerischen Wert.
Hinweis: Verwenden Sie die qproperty-Syntax mit Vorsicht, da sie das gemalte Widget modifiziert. Außerdem wird die qproperty-Syntax nur einmal ausgewertet, nämlich dann, wenn das Widget durch den Stil poliert wird. Das bedeutet, dass jeder Versuch, sie in Pseudo-Zuständen wie QPushButton:hover zu verwenden, nicht funktionieren wird.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.