Syntaxe des feuilles de style
La terminologie et les règles syntaxiques des feuilles de style Qt sont pratiquement identiques à celles du CSS HTML. Si vous connaissez déjà le CSS, vous pouvez probablement survoler rapidement cette section.
Règles de style
Les feuilles de style sont constituées d'une séquence de règles de style. Une règle de style se compose d'un sélecteur et d'une déclaration. Le sélecteur précise quels widgets sont concernés par la règle ; la déclaration précise quelles propriétés doivent être définies sur le widget. Par exemple :
QPushButton { color: red }Dans la règle de style ci-dessus, ` QPushButton ` est le sélecteur et ` { color: red } ` est la déclaration. La règle spécifie que ` QPushButton ` et ses sous-classes (par exemple, ` MyPushButton`) doivent utiliser le rouge comme couleur de premier plan.
Les feuilles de style Qt ne font généralement pas la distinction entre majuscules et minuscules (c'est-à-dire que color, Color, COLOR et cOloR font référence à la même propriété). Les seules exceptions sont les noms de classes, object names, et les noms de propriétés Qt, qui sont sensibles à la casse.
Plusieurs sélecteurs peuvent être spécifiés pour une même déclaration, en les séparant par des virgules (,). Par exemple, la règle
QPushButton, QLineEdit, QComboBox { color: red }est équivalente à cette séquence de trois règles :
QPushButton { color: red }
QLineEdit { color: red }
QComboBox { color: red }La partie « déclaration » d’une règle de style est une liste de property: value paires, entre accolades ({}) et séparées par des points-virgules. Par exemple :
QPushButton { color: red; background-color: white }Consultez la section « Liste des propriétés » ci-dessous pour connaître la liste des propriétés fournies par les Qt Widgets.
Types de sélecteurs
Tous les exemples présentés jusqu'à présent utilisaient le type de sélecteur le plus simple, le sélecteur de type. Les feuilles de style Qt prennent en charge tous les sélecteurs définis dans CSS2. Le tableau ci-dessous récapitule les types de sélecteurs les plus utiles.
| Sélecteur | Exemple | Explication |
|---|---|---|
| Sélecteur universel | * | Correspond à tous les widgets. |
| Sélecteur de type | QPushButton | Correspond aux instances de ` QPushButton ` et de ses sous-classes. |
| Sélecteur de propriété | QPushButton[flat="false"] | Correspond aux instances de QPushButton qui ne sont pas de type flat. Vous pouvez utiliser ce sélecteur pour tester toute propriété Qt prenant en charge la méthode QVariant::toString() (voir la documentation de la fonction toString() pour plus de détails). De plus, la propriété spéciale class est prise en charge, pour le nom de la classe.Ce sélecteur peut également être utilisé pour tester des propriétés dynamiques. Pour plus d’informations sur la personnalisation à l’aide de propriétés dynamiques, reportez-vous à la section « Personnalisation à l’aide de propriétés dynamiques ». Au lieu de ` Avertissement : si la valeur de la propriété Qt change après la définition de la feuille de style, il peut être nécessaire de forcer le recalcul de la feuille de style. Pour ce faire, vous pouvez notamment désactiver la feuille de style, puis la réactiver. |
| Sélecteur de classe | .QPushButton | Correspond aux instances de QPushButton, mais pas à celles de ses sous-classes. Cela équivaut à ` |
| Sélecteur d'ID | QPushButton#okButton | Correspond à toutes les instances de QPushButton dont l'object name est okButton. |
| Sélecteur de descendants | QDialog QPushButton | Correspond à toutes les instances de QPushButton qui sont des descendants (enfants, petits-enfants, etc.) d’un QDialog. |
| Sélecteur d’enfants | QDialog > QPushButton | Correspond à toutes les instances de QPushButton qui sont des enfants directs d’une QDialog. |
Sous-contrôles
Pour styliser des widgets complexes, il est nécessaire d’accéder aux sous-contrôles du widget, tels que le bouton déroulant d’un QComboBox ou les flèches haut et bas d’un QSpinBox. Les sélecteurs peuvent contenir des sous-contrôles qui permettent de restreindre l’application d’une règle à des sous-contrôles spécifiques du widget. Par exemple :
QComboBox::drop-down { image: url(dropdown.png) }La règle ci-dessus applique un style au bouton déroulant de tous les QComboBox. Bien que la syntaxe à double deux-points (::) rappelle les pseudo-éléments CSS3, les sous-contrôles Qt diffèrent conceptuellement de ces derniers et possèdent une sémantique de cascade différente.
Les sous-contrôles sont toujours positionnés par rapport à un autre élément : un élément de référence. Cet élément de référence peut être le widget lui-même ou un autre sous-contrôle. Par exemple, le ::drop-down d’un QComboBox est placé, par défaut, dans le coin supérieur droit du rectangle de remplissage (Padding) du QComboBox. Le ::drop-down est placé, par défaut, au centre du rectangle « Contents » du sous-contrôle ::drop-down. Consultez la liste des widgets personnalisables ci-dessous pour connaître les sous-contrôles à utiliser pour personnaliser un widget ainsi que leurs positions par défaut.
Le rectangle d’origine à utiliser peut être modifié à l’aide de la propriété `subcontrol-origin`. Par exemple, si l’on souhaite placer le menu déroulant dans le rectangle « margin » de l’élément « QComboBox » plutôt que dans le rectangle « padding » par défaut, on peut spécifier :
L'alignement du menu déroulant au sein du rectangle de marge est modifié à l'aide de la propriété ` subcontrol-position `.
Les propriétés « width » et « height » permettent de contrôler la taille du sous-contrôle. Notez que le fait de définir une image détermine implicitement la taille du sous-contrôle.
Le schéma de positionnement relatif (position: relative) permet de décaler la position du sous-contrôle par rapport à sa position initiale. Par exemple, lorsque l'on appuie sur le bouton du menu déroulant de l'QComboBox, on peut souhaiter que la flèche à l'intérieur soit décalée pour donner un effet « enfoncé ». Pour ce faire, on peut spécifier :
QComboBox::down-arrow {
image: url(down_arrow.png);
}
QComboBox::down-arrow:pressed {
position: relative;
top: 1px; left: 1px;
}Le schéma de positionnement absolu (position: absolute) permet de modifier la position et la taille du sous-contrôle par rapport à l’élément de référence.
Une fois positionnés, ils sont traités de la même manière que les widgets et peuvent être stylisés à l'aide du modèle de boîte.
Consultez la liste des sous-contrôles ci-dessous pour connaître les sous-contrôles pris en charge, et l'article « Personnalisation du sous-contrôle d'indicateur de menu du QPushButton » pour un exemple concret.
Remarque : avec des widgets complexes tels que QComboBox et QScrollBar, si une propriété ou un sous-contrôle est personnalisé, toutes les autres propriétés ou sous-contrôles doivent également l’être.
Pseudo-états
Les sélecteurs peuvent contenir des pseudo-états qui restreignent l'application de la règle en fonction de l'état du widget. Les pseudo-états apparaissent à la fin du sélecteur, séparés par deux points (:). Par exemple, la règle suivante s'applique lorsque la souris survole un QPushButton:
QPushButton:hover { color: white }QRadioButtonLes pseudo-états peuvent être inversés à l'aide de l'opérateur d'exclamation. Par exemple, la règle suivante s'applique lorsque la souris ne survole pas un :
QRadioButton:!hover { color: red }Les pseudo-états peuvent être enchaînés, auquel cas un ET logique est implicite. Par exemple, la règle suivante s'applique lorsque la souris survole une « QCheckBox » cochée :
QCheckBox:hover:checked { color: white }Les pseudo-états négatifs peuvent apparaître dans des chaînes de pseudo-états. Par exemple, la règle suivante s'applique lorsque le curseur de la souris survole une QPushButton qui n'est pas enfoncée :
QPushButton:hover:!pressed { color: blue; }Si nécessaire, l'opération logique OU peut être exprimée à l'aide de l'opérateur virgule :
Les pseudo-états peuvent apparaître en combinaison avec des sous-commandes. Par exemple :
QComboBox::drop-down:hover { image: url(dropdown_bright.png) }Consultez la section « Liste des pseudo-états » ci-dessous pour connaître la liste des pseudo-états fournis par les Qt Widgets.
Résolution des conflits
Des conflits surviennent lorsque plusieurs règles de style spécifient les mêmes propriétés avec des valeurs différentes. Prenons l'exemple de la feuille de style suivante :
QPushButton#okButton { color: gray }
QPushButton { color: red }Les deux règles s'appliquent aux instances de la classe « QPushButton » nommées « okButton » et il existe un conflit concernant la propriété « color ». Pour résoudre ce conflit, il faut tenir compte de la spécificité des sélecteurs. Dans l'exemple ci-dessus, « QPushButton#okButton » est considéré comme plus spécifique que « QPushButton », car il fait (généralement) référence à un seul objet, et non à toutes les instances d'une classe.
De même, les sélecteurs comportant des pseudo-états sont plus spécifiques que ceux qui n’en comportent pas. Ainsi, la feuille de style suivante spécifie qu’un élément QPushButton doit afficher un texte blanc lorsque la souris survole cet élément, et un texte rouge dans le cas contraire :
QPushButton:hover { color: white }
QPushButton { color: red }En voici une un peu plus délicate :
QPushButton:hover { color: white }
QPushButton:enabled { color: red }Ici, les deux sélecteurs ont la même spécificité ; ainsi, si le curseur de la souris survole le bouton alors qu'il est activé, la deuxième règle prévaut. Si nous voulons que le texte soit blanc dans ce cas, nous pouvons réorganiser les règles comme suit :
QPushButton:enabled { color: red }
QPushButton:hover { color: white }Sinon, nous pouvons rendre la première règle plus spécifique :
QPushButton:hover:enabled { color: white }
QPushButton:enabled { color: red }Un problème similaire se pose avec les sélecteurs de type. Prenons l’exemple suivant :
QPushButton { color: red }
QAbstractButton { color: gray }Les deux règles s’appliquent aux instances de type « QPushButton » (puisque « QPushButton » hérite de « QAbstractButton ») et il y a un conflit concernant la propriété « color ». Comme « QPushButton » hérite de « QAbstractButton », on pourrait être tenté de supposer que « QPushButton » est plus spécifique que « QAbstractButton ». Cependant, pour les calculs de feuille de style, tous les sélecteurs de type ont la même spécificité, et la règle qui apparaît en dernier a la priorité. En d’autres termes, la couleur est définie sur gray pour tous les QAbstractButton, y compris les QPushButton. Si nous voulons vraiment que les QPushButtonaient un texte rouge, nous pouvons toujours réorganiser l’ordre des règles.
Pour déterminer la spécificité d’une règle, les feuilles de style Qt suivent la spécification CSS2:
La spécificité d’un sélecteur est calculée comme suit :
- compter le nombre d’attributs ID dans le sélecteur (= a)
- compter le nombre d'autres attributs et pseudo-classes dans le sélecteur (= b)
- compter le nombre de noms d'éléments dans le sélecteur (= c)
- ignorer les pseudo-éléments [c'est-à-dire les sous-contrôles].
La concaténation des trois nombres a-b-c (dans un système de numération à grande base) donne la spécificité.
Quelques exemples :
* {} /* 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 */
Cascade
Les feuilles de style peuvent être définies sur l'QApplication, sur les widgets parents et sur les widgets enfants. La feuille de style effective d'un widget donné est obtenue en fusionnant les feuilles de style définies sur ses ancêtres (parent, grand-parent, etc.), ainsi que toute feuille de style définie sur l'QApplication.
En cas de conflit, la feuille de style propre au widget est toujours privilégiée par rapport à toute feuille de style héritée, quelle que soit la spécificité des règles en conflit. De même, la feuille de style du widget parent est privilégiée par rapport à celle de l’arrière-grand-parent, etc.
L'une des conséquences de ce principe est que la définition d'une règle de style sur un widget lui confère automatiquement la priorité sur les autres règles spécifiées dans les feuilles de style des widgets ancêtres ou dans la feuille de style QApplication. Prenons l'exemple suivant. Tout d'abord, nous définissons une feuille de style sur QApplication:
qApp->setStyleSheet("QPushButton { color: white }");Ensuite, nous définissons une feuille de style sur un objet « QPushButton » :
myPushButton->setStyleSheet("* { color: blue }");La feuille de style appliquée à l’ QPushButton impose à l’ QPushButton (et à tout widget enfant) d’afficher du texte bleu, malgré la règle plus spécifique définie par la feuille de style applicable à l’ensemble de l’application.
Le résultat aurait été le même si nous avions écrit
myPushButton->setStyleSheet("color: blue");sauf que si l’ QPushButton avait eu des enfants (ce qui est peu probable), la feuille de style n’aurait eu aucun effet sur eux.
La cascade des feuilles de style est un sujet complexe. Reportez-vous à la spécification CSS2 pour en connaître tous les détails. Sachez que Qt n'implémente pas actuellement l'!important.
Héritage
Dans le CSS classique, lorsque la police et la couleur d’un élément ne sont pas explicitement définies, elles sont automatiquement héritées du parent. Par défaut, lors de l’utilisation des feuilles de style Qt, un widget n’ hérite pas automatiquement les paramètres de police et de couleur de son widget parent.
Prenons par exemple un élément « QPushButton » situé à l'intérieur d'un élément « QGroupBox » :
qApp->setStyleSheet("QGroupBox { color: red; } ");L’ QPushButton n’a pas de couleur explicitement définie. Par conséquent, au lieu d’hériter de la couleur de son parent QGroupBox, il affiche la couleur par défaut du système. Si nous souhaitons définir la couleur d’un QGroupBox et de ses enfants, nous pouvons écrire :
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");En revanche, la définition d’une police et d’une palette à l’aide de ` QWidget::setFont()` et ` QWidget::setPalette()` se répercute sur les widgets enfants.
Si vous préférez que la police et la palette soient répercutées sur les widgets enfants, vous pouvez activer le drapeau Qt::AA_UseStyleSheetPropagationInWidgetStyles, comme ceci :
Utilisation :
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);Lorsque la propagation de la police et de la palette de style du widget est activée, les modifications apportées à la police et à la palette via les feuilles de style Qt se comportent comme si l'utilisateur avait appelé manuellement les méthodes correspondantes ` QWidget::setPalette()` et ` QWidget::setFont()` sur tous les `Qt Widgets` ciblés par la feuille de style.
- Les modifications apportées par une feuille de style sont propagées. Elles sont appliquées une seule fois à tous les widgets correspondant à la feuille de style, au moment où la modification est effectuée.
- Les modifications apportées en appelant QWidget::setPalette() ou QWidget::setFont() sont héritées. Elles sont héritées par tous les enfants existants et futurs, pour lesquels le pinceau ou la police n’a pas été explicitement défini.
Widgets dans les espaces de noms C++
Le sélecteur de type peut être utilisé pour styliser des widgets d’un type particulier. Par exemple,
class MyPushButton : public QPushButton {
// ...
};
// ...
void someFunction()
{
qApp->setStyleSheet("MyPushButton { background: yellow; }");
//...Qt Style Sheet utilise la méthode QObject::className() du widget pour déterminer quand appliquer le sélecteur de type. Lorsque des widgets personnalisés se trouvent dans des espaces de noms, la méthode QObject::className() renvoie <ESPACE de noms>::<NOM de classe>. Cela entre en conflit avec la syntaxe des sous-contrôles. Pour contourner ce problème, lorsque l’on utilise le sélecteur de type pour des widgets situés dans des espaces de noms, il faut remplacer :: par --. Par exemple,
namespace ns {
class MyPushButton : public QPushButton {
// ...
};
}
// ...
void someMethod()
{
qApp->setStyleSheet("ns--MyPushButton { background: yellow; }");
//...Définition des propriétés de QObject
À partir de la version 4.3, tout objet Q_PROPERTY pouvant faire l'objet d'une conception peut être configuré à l'aide de la syntaxe qproperty-<nom de la propriété>.
Par exemple,
MyLabel { qproperty-pixmap: url(pixmap.png); }
MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); }
QPushButton { qproperty-iconSize: 20px 20px; }si la propriété fait référence à une énumération déclarée avec ` Q_ENUM`, vous devez référencer ses constantes par leur nom, et non par leur valeur numérique.
Remarque : utilisez la syntaxe `qproperty` avec précaution, car elle modifie le widget en cours de dessin. De plus, la syntaxe `qproperty` n'est évaluée qu'une seule fois, au moment où le widget est mis en forme par le style. Cela signifie que toute tentative de l'utiliser dans des pseudo-états tels que ` QPushButton:hover` ne fonctionnera pas.
© 2026 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.