Styles et widgets compatibles avec les styles
Les styles (classes qui héritent de QStyle) dessinent au nom des widgets et encapsulent l'aspect et la convivialité d'une interface graphique. La classe QStyle est une classe de base abstraite qui encapsule l'aspect et la convivialité d'une interface graphique. Les widgets intégrés de Qt Widgets l'utilisent pour réaliser la quasi-totalité de leurs dessins, garantissant ainsi qu'ils ressemblent exactement aux widgets natifs équivalents.
Qt est livré avec une sélection de styles intégrés. Certains styles ne sont disponibles que sur des plates-formes spécifiques. Les styles personnalisés sont disponibles sous forme de plugins ou en créant une instance d'une classe de style spécifique à l'aide de QStyleFactory::create() et en la définissant à l'aide de QApplication::setStyle().
Personnalisation d'un style
Pour personnaliser un style existant, héritez de QProxyStyle et réimplémentez les méthodes virtuelles souhaitées. QProxyStyle permet de spécifier un certain style de base ou d'utiliser automatiquement le style de l'application si le style de base n'est pas spécifié. La première option donne un contrôle total sur le style de base et fonctionne mieux si la personnalisation attend un certain comportement du style, tandis que la seconde offre une manière agnostique de personnaliser le style de l'application qui prend par défaut le style natif de la plateforme.
Implémentation d'un style personnalisé
QCommonStyle fournit une base pratique pour l'implémentation complète d'un style personnalisé. L'approche est la même qu'avec QProxyStyle, mais hérite de QCommonStyle et réimplémente les méthodes virtuelles appropriées. L'implémentation d'un style personnalisé complet est quelque peu complexe, c'est pourquoi nous fournissons cette vue d'ensemble. Nous expliquons étape par étape comment styliser les différents widgets de Qt Widgets. Nous examinerons les fonctions virtuelles QStyle, les variables membres et les énumérations.
La partie de ce document qui ne concerne pas le style des différents widgets doit être lue de manière séquentielle, car les sections suivantes dépendent généralement des sections précédentes. La description des widgets peut être utilisée comme référence lors de la mise en œuvre d'un style. Toutefois, il peut être nécessaire de consulter le code source de Qt dans certains cas. La séquence du processus de stylisation devrait devenir claire après la lecture de ce document, ce qui vous aidera à localiser le code pertinent.
Pour développer des widgets sensibles au style (c'est-à-dire des widgets qui se conforment au style dans lequel ils sont dessinés), vous devez les dessiner en utilisant le style actuel. Ce document montre comment les widgets se dessinent et quelles sont les possibilités offertes par le style.
Classes pour le style des widgets
Ces classes sont utilisées pour personnaliser l'apparence et le style d'une application.
Couleurs basées sur les valeurs RVB, HSV ou CMYK | |
Abstraction de l'espace couleur | |
Transformation entre les espaces colorimétriques | |
Encapsule l'aspect et la convivialité communs d'une interface graphique | |
Curseur de souris de forme arbitraire | |
Spécifie une requête pour une police utilisée pour dessiner du texte | |
Informations sur les polices disponibles dans le système de fenêtres sous-jacent | |
Informations générales sur les polices | |
Représente une ancre entre deux éléments dans un QGraphicsAnchorLayout | |
Disposition permettant d'ancrer des widgets ensemble dans une vue graphique | |
Contient des groupes de couleurs pour chaque état de widget | |
Classe de base abstraite qui encapsule l'aspect et la convivialité d'une interface graphique | |
Crée des objets QStyle | |
Indications de style qui renvoient plus que des types de données de base | |
Indications de style renvoyant une QRegion | |
Indications de style renvoyant une QVariant | |
Stocke les paramètres utilisés par les fonctions QStyle | |
Classe de commodité pour dessiner des éléments QStyle à l'intérieur d'un widget |
L'implémentation de QStyle
L'API de QStyle contient des fonctions qui dessinent les widgets, des fonctions d'aide statiques pour effectuer des tâches courantes et difficiles (par exemple, le calcul de la position des poignées des curseurs) et des fonctions pour effectuer les divers calculs nécessaires pendant le dessin (par exemple, pour que les widgets calculent leurs indices de taille). Le style aide également certains widgets à mettre en page leur contenu. En outre, il crée un QPalette qui contient des QBrushes pour dessiner.
QStyle dessine des éléments graphiques ; un élément est un widget ou une partie de widget comme un bouton poussoir, un cadre de fenêtre ou une barre de défilement. La plupart des fonctions de dessin prennent maintenant quatre arguments :
- une valeur enum spécifiant l'élément graphique à dessiner
- une adresse QStyleOption spécifiant comment et où effectuer le rendu de cet élément
- une adresse QPainter qui doit être utilisée pour dessiner l'élément
- une adresse QWidget sur laquelle le dessin est effectué (facultatif).
Lorsqu'un widget demande à un style de dessiner un élément, il lui fournit un QStyleOption, qui est une classe contenant les informations nécessaires au dessin. Grâce à QStyleOption, il est possible de faire dessiner des widgets par QStyle sans lier de code au widget. Cela permet d'utiliser les fonctions de dessin de QStyle sur n'importe quel dispositif de peinture, c'est-à-dire que vous pouvez dessiner un combobox sur n'importe quel widget, et pas seulement sur un QComboBox.
Le widget est passé en dernier argument au cas où le style en aurait besoin pour réaliser des effets spéciaux (comme les boutons animés par défaut sur macOS), mais ce n'est pas obligatoire.
Au cours de cette section, nous examinerons les éléments de style, les options de style et les fonctions de QStyle. Enfin, nous décrirons l'utilisation de la palette.
Les éléments des vues d'éléments sont dessinés par des délégués dans Qt. Les en-têtes des vues d'éléments sont toujours dessinés par le style. Le délégué par défaut de Qt, QStyledItemDelegate, dessine ses éléments partiellement par le biais du style courant ; il dessine les indicateurs de case à cocher et calcule les rectangles de délimitation pour les éléments dont l'élément est constitué. Dans ce document, nous ne décrivons que la mise en œuvre d'une sous-classe de QStyle. Si vous souhaitez ajouter la prise en charge d'autres types de données que ceux pris en charge par la sous-classe QStyledItemDelegate, vous devez mettre en œuvre un délégué personnalisé. Notez que les délégués doivent être définis par programme pour chaque widget individuel (c'est-à-dire que les délégués par défaut ne peuvent pas être fournis en tant que plugins).
Les éléments de style
Un élément de style est une partie graphique d'une interface graphique. Un widget est constitué d'une hiérarchie (ou arbre) d'éléments de style. Par exemple, lorsqu'un style reçoit une demande de dessin d'un bouton poussoir (de QPushButton, par exemple), il dessine une étiquette (texte et icône), un biseau de bouton et un cadre de mise au point. Le biseau du bouton, à son tour, se compose d'un cadre autour du biseau et de deux autres éléments, que nous examinerons plus tard. Vous trouverez ci-dessous une illustration conceptuelle de l'arbre des éléments d'un bouton-poussoir. Nous verrons l'arbre réel à l'adresse QPushButton lorsque nous passerons en revue les différents widgets.

Les widgets ne sont pas nécessairement dessinés en demandant au style de ne dessiner qu'un seul élément. Les widgets peuvent faire plusieurs appels au style pour dessiner différents éléments. Un exemple est QTabWidget, qui dessine ses onglets et son cadre individuellement.
Il existe trois types d'éléments : les éléments primitifs, les éléments de contrôle et les éléments de contrôle complexes. Les éléments sont définis par les énumérations ComplexControl, ControlElement et PrimitiveElement. Les valeurs de chaque élément enum ont un préfixe pour identifier leur type : CC_ pour les éléments complexes, CE_ pour les éléments de contrôle et PE_ pour les éléments primitifs. Dans les trois sections suivantes, nous verrons ce qui définit les différents éléments et nous verrons des exemples de widgets qui les utilisent.
La description de la classe QStyle contient une liste de ces éléments et de leur rôle dans le style des widgets. Nous verrons comment ils sont utilisés lorsque nous stylisons des widgets individuels.
Éléments primitifs
Les éléments primitifs sont des éléments de l'interface graphique qui sont communs et souvent utilisés par plusieurs widgets. Il s'agit par exemple des cadres, des biseaux des boutons et des flèches des boîtes tournantes, des barres de défilement et des boîtes combinées. Les éléments primitifs ne peuvent pas exister seuls : ils font toujours partie d'une construction plus large. Ils ne participent pas à l'interaction avec l'utilisateur, mais sont des décorations passives dans l'interface graphique.
Éléments de contrôle
Un élément de contrôle effectue une action ou affiche des informations à l'intention de l'utilisateur. Les boutons-poussoirs, les cases à cocher et les sections d'en-tête des tableaux et des arborescences sont des exemples d'éléments de contrôle. Les éléments de contrôle ne sont pas nécessairement des widgets complets tels que les boutons poussoirs, mais peuvent également être des parties de widget telles que les onglets de la barre de tabulation et les curseurs de la barre de défilement. Ils diffèrent des éléments primitifs en ce qu'ils ne sont pas passifs, mais remplissent une fonction dans l'interaction avec l'utilisateur. Les contrôles composés de plusieurs éléments utilisent souvent le style pour calculer les rectangles de délimitation des éléments. Les sous-éléments disponibles sont définis par l'énumération SubElement. Cette liste n'est utilisée que pour calculer les rectangles de délimitation ; les sous-éléments ne sont pas des éléments graphiques à dessiner comme les éléments primitifs, de contrôle et complexes.
Éléments de contrôle complexes
Les éléments de contrôle complexes contiennent des sous-contrôles. Les contrôles complexes se comportent différemment selon l'endroit où l'utilisateur les manipule à l'aide de la souris et selon les touches du clavier qu'il enfonce. Cela dépend du sous-contrôle (s'il y en a un) sur lequel la souris se trouve ou sur lequel on appuie. Les barres de défilement et les boîtes combinées sont des exemples de contrôles complexes. Dans le cas d'une barre de défilement, vous pouvez utiliser la souris pour déplacer le curseur et appuyer sur les boutons de déplacement vers le haut et vers le bas. Les sous-contrôles disponibles sont définis par l'énumération SubControl.
Outre le dessin, le style doit fournir aux widgets des informations sur le sous-contrôle (le cas échéant) sur lequel la souris a été appuyée. Par exemple, QScrollBar doit savoir si l'utilisateur a appuyé sur le curseur, sur la rainure du curseur ou sur l'un des boutons.
Notez que les sous-contrôles ne sont pas les mêmes que les éléments de contrôle décrits dans la section précédente. Vous ne pouvez pas utiliser le style pour dessiner un sous-contrôle ; le style calculera uniquement le rectangle de délimitation dans lequel le sous-contrôle doit être dessiné. Il est cependant courant que des éléments complexes utilisent des éléments de contrôle et des éléments primitifs pour dessiner leurs sous-contrôles, ce qui est une approche fréquemment utilisée par les styles intégrés dans Qt et également par le style Java. Par exemple, le style Java utilise PE_IndicatorCheckBox pour dessiner la case à cocher dans les boîtes de groupe (qui est un sous-contrôle de CC_GroupBox). Certains sous-contrôles ont un élément de contrôle équivalent, par exemple le curseur de la barre de défilement (SC_SCrollBarSlider et CE_ScrollBarSlider).
Autres tâches QStyle
Les éléments de style et les widgets, comme nous l'avons mentionné, utilisent le style pour calculer les rectangles de délimitation des sous-éléments et des sous-contrôles. Les métriques de pixels, qui sont des tailles en pixels d'écran dépendant du style, sont également utilisées pour les mesures lors du dessin. Les rectangles et les mesures de pixels disponibles sont représentés par trois enums dans QStyle: SubElement, SubControl, et PixelMetric. Les valeurs des enums sont facilement identifiables car elles commencent par SE_, SC_ et PM_.
Le style contient également un ensemble d'indications de style, représentées par des valeurs dans l'énumération StyleHint. Tous les widgets n'ont pas la même fonctionnalité ni le même aspect dans les différents styles. Par exemple, lorsque les éléments d'un menu ne tiennent pas dans une seule colonne à l'écran, certains styles prennent en charge le défilement, tandis que d'autres dessinent plus d'une colonne pour faire tenir tous les éléments.
Un style possède généralement un ensemble d'images standard (telles qu'une image d'avertissement, de question et d'erreur) pour les boîtes de message, les boîtes de dialogue de fichiers, etc. QStyle fournit l'énumération StandardPixmap. Ses valeurs représentent les images standard. Les widgets de Qt Widgets les utilisent, donc lorsque vous implémentez un style personnalisé, vous devez fournir les images utilisées par le style implémenté.
Le style calcule l'espacement entre les widgets dans les présentations. Le style peut gérer ces calculs de deux manières. Vous pouvez définir les valeurs PM_LayoutHorizontalSpacing et PM_LayoutVerticalSpacing, comme le fait le style Java (par l'intermédiaire de QCommonStyle). Vous pouvez également implémenter QStyle::layoutSpacing() et QStyle::layoutSpacingImplementation() si vous avez besoin de plus de contrôle sur cette partie de la mise en page. Dans ces fonctions, vous pouvez calculer l'espacement en fonction des types de contrôle (QSizePolicy::ControlType) pour différentes politiques de taille (QSizePolicy::Policy) et également l'option de style pour le widget en question.
Options de style
Les sous-classes de QStyleOption contiennent toutes les informations nécessaires pour styliser les différents éléments. Les options de style sont instanciées - généralement sur la pile - et remplies par l'appelant de la fonction QStyle. En fonction de ce qui est dessiné, le style attendra une classe d'options de style différente. Par exemple, l'élément QStyle::PE_FrameFocusRect attend un argument QStyleOptionFocusRect, et il est possible de créer des sous-classes personnalisées qu'un style personnalisé peut utiliser. Les options de style conservent des variables publiques pour des raisons de performance.
Les widgets peuvent se trouver dans un certain nombre d'états différents, définis par l'énumération State. Certains drapeaux d'état ont des significations différentes selon le widget, mais d'autres sont communs à tous les widgets, comme State_Disabled. C'est QStyleOption qui définit les états communs avec QStyleOption::initFrom() ; les autres états sont définis par les différents widgets.
Les options de style contiennent notamment la palette et les rectangles de délimitation des widgets à dessiner. La plupart des widgets ont des options de style spécialisées. QPushButton et QCheckBox, par exemple, utilisent QStyleOptionButton comme option de style, qui contient le texte, l'icône et la taille de l'icône. Le contenu exact de toutes les options est décrit lorsque nous examinons les différents widgets.
Lorsque vous réimplémentez des fonctions QStyle qui prennent un paramètre QStyleOption, vous devez souvent convertir QStyleOption en une sous-classe (par exemple, QStyleOptionFocusRect). Par sécurité, vous pouvez utiliser qstyleoption_cast() pour vous assurer que le type du pointeur est correct. Si l'objet n'est pas du bon type, qstyleoption_cast() renvoie nullptr. Par exemple :
const QStyleOptionFocusRect *focusRectOption = qstyleoption_cast<const QStyleOptionFocusRect *>(option); if (focusRectOption) { //... }
L'extrait de code suivant montre comment utiliser QStyle pour dessiner le rectangle de mise au point à partir de la fonction paintEvent() d'un widget personnalisé :
void MyWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); //... QStyleOptionFocusRect option; option.initFrom(this); option.backgroundColor = palette().color(QPalette::Window); style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter, this); }
L'exemple suivant montre comment dériver d'un style existant pour personnaliser l'apparence d'un élément graphique :
class CustomStyle : public QProxyStyle { Q_OBJECT public: explicit CustomStyle(const QWidget *widget = nullptr); ~CustomStyle() {} void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override; }; void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) { QPolygon points(3); int x = option->rect.x(); int y = option->rect.y(); int w = option->rect.width() / 2; int h = option->rect.height() / 2; x += (option->rect.width() - w) / 2; y += (option->rect.height() - h) / 2; if (element == PE_IndicatorSpinUp) { points[0] = QPoint(x, y + h); points[1] = QPoint(x + w, y + h); points[2] = QPoint(x + w / 2, y); } else { // PE_SpinBoxDown points[0] = QPoint(x, y); points[1] = QPoint(x + w, y); points[2] = QPoint(x + w / 2, y + h); } if (option->state & State_Enabled) { painter->setPen(option->palette.mid().color()); painter->setBrush(option->palette.buttonText()); } else { painter->setPen(option->palette.buttonText().color()); painter->setBrush(option->palette.mid()); } painter->drawPolygon(points); } else { QProxyStyle::drawPrimitive(element, option, painter, widget); } }
Fonctions QStyle
La classe QStyle définit trois fonctions pour dessiner les éléments primitifs, de contrôle et complexes : drawPrimitive(), drawControl() et drawComplexControl(). Les fonctions prennent les paramètres suivants
- la valeur enum de l'élément à dessiner.
- un QStyleOption qui contient les informations nécessaires pour dessiner l'élément.
- un QPainter avec lequel dessiner l'élément.
- un pointeur vers un QWidget, généralement le widget sur lequel l'élément est peint.
Tous les widgets n'envoient pas de pointeur sur eux-mêmes. Si l'option de style envoyée à la fonction ne contient pas les informations dont vous avez besoin, vous devez vérifier l'implémentation du widget pour voir s'il envoie un pointeur sur lui-même.
La classe QStyle fournit également des fonctions d'aide qui sont utilisées pour dessiner les éléments. La fonction drawItemText() dessine du texte à l'intérieur d'un rectangle spécifié, en prenant un QPalette comme paramètre. La fonction drawItemPixmap() permet d'aligner un pixmap à l'intérieur d'un rectangle spécifié.
D'autres fonctions de QStyle effectuent divers calculs pour les fonctions qui dessinent. Les widgets utilisent également ces fonctions pour calculer les indices de taille et les rectangles de délimitation s'ils dessinent eux-mêmes plusieurs éléments de style. Comme pour les fonctions qui dessinent les éléments, les fonctions d'aide prennent généralement les mêmes arguments.
- La fonction subElementRect() prend une valeur enum SubElement et calcule un rectangle de délimitation pour un sous-élément. Le style utilise cette fonction pour savoir où dessiner les différentes parties d'un élément. Si vous créez un nouveau style, vous pouvez utiliser le même emplacement pour les sous-éléments que la super-classe.
- La fonction subControlRect() est utilisée pour calculer les rectangles de délimitation des sous-contrôles dans les contrôles complexes. Lorsque vous implémentez un nouveau style, vous réimplémentez
subControlRect()et calculez les rectangles qui sont différents de ceux de la super classe. - La fonction pixelMetric() renvoie une métrique en pixels, qui est une taille dépendant du style et exprimée en pixels d'écran. Elle prend une valeur de l'enum PixelMetric et renvoie la mesure correcte. Notez que les mesures de pixels ne doivent pas nécessairement être des mesures statiques, mais peuvent être calculées avec, par exemple, l'option de style.
- La fonction hitTestComplexControl() renvoie le sous-contrôle sur lequel se trouve le pointeur de la souris dans un contrôle complexe. En général, il suffit d'utiliser subControlRect() pour obtenir les rectangles de délimitation des sous-contrôles, puis de voir quel rectangle contient la position du curseur.
QStyle dispose également des fonctions polish() et unpolish(). Tous les widgets sont envoyés à la fonction polish() avant d'être affichés et à unpolish() lorsqu'ils sont cachés. Vous pouvez utiliser ces fonctions pour définir des attributs sur les widgets ou pour effectuer d'autres tâches requises par votre style. Par exemple, si vous avez besoin de savoir quand la souris survole le widget, vous devez définir l'attribut de widget WA_Hover. L'indicateur d'état State_MouseOver sera alors défini dans les options de style du widget.
QStyle possède quelques fonctions d'aide statiques qui effectuent des tâches courantes et difficiles. Elles peuvent calculer la position d'une poignée de curseur à partir de la valeur du curseur, transformer des rectangles et dessiner du texte en tenant compte des mises en page inversées ; voir la documentation de la classe QStyle pour plus de détails.
L'approche habituelle lorsqu'on réimplémente les fonctions virtuelles de QStyle est de travailler sur les éléments qui sont différents de la super-classe ; pour tous les autres éléments, vous pouvez simplement utiliser l'implémentation de la super-classe.
La palette
Chaque style fournit une palette de couleurs - c'est-à-dire QBrush - qui doit être utilisée pour dessiner les widgets. Il existe un ensemble de couleurs pour les différents états des widgets (QPalette::ColorGroup) : actif (widgets dans la fenêtre qui ont le focus clavier), inactif (widgets utilisés pour d'autres fenêtres) et désactivé (widgets qui sont désactivés). Les états peuvent être trouvés en interrogeant les drapeaux d'état State_Active et State_Enabled. Chaque ensemble contient certains rôles de couleur donnés par l'énumération QPalette::ColorRole. Les rôles décrivent les situations dans lesquelles les couleurs doivent être utilisées (par exemple, pour peindre l'arrière-plan des widgets, le texte ou les boutons).
La manière dont les rôles des couleurs sont utilisés dépend du style. Par exemple, si le style utilise des dégradés, on peut utiliser une couleur de la palette et la rendre plus foncée ou plus claire avec QColor::darker() et QColor::lighter() pour créer le dégradé. En général, si vous avez besoin d'une brosse qui n'est pas fournie par la palette, vous devez essayer de la dériver d'une autre.
QPaletteLa palette, qui fournit la palette, stocke les couleurs pour les différents états des widgets et les rôles des couleurs. La palette d'un style est renvoyée par standardPalette(). La palette standard n'est pas installée automatiquement lorsqu'un nouveau style est défini dans l'application (QApplication::setStyle()) ou le widget (QWidget::setStyle()), vous devez donc définir la palette vous-même avec (QApplication::setPalette()) ou (QWidget::setPalette()).
Il n'est pas recommandé de coder les couleurs en dur, car les applications et les widgets individuels peuvent définir leur propre palette et utiliser également la palette de leur style pour dessiner. Notez qu'aucun des widgets de Qt Widgets ne définit sa propre palette. Le style Java codifie certaines couleurs en dur, mais uniquement sur décision de l'auteur ; ce n'est pas conseillé. Bien entendu, il n'est pas prévu que le style s'affiche correctement avec n'importe quelle palette.
Problèmes de mise en œuvre
Lorsque vous mettez en œuvre des styles, plusieurs questions doivent être prises en compte. Nous donnons ici quelques indications et conseils à ce sujet.
Lors de l'implémentation des styles, il est nécessaire d'examiner le code des widgets et le code de la classe de base et de ses ancêtres. En effet, les widgets utilisent le style différemment, car l'implémentation des fonctions virtuelles des différents styles peut affecter l'état du dessin (par exemple, en modifiant l'état de QPainter sans le restaurer et en dessinant certains éléments sans utiliser les métriques de pixels et les sous-éléments appropriés).
Il est recommandé que les styles ne modifient pas la taille proposée des widgets avec la fonction QStyle::sizeFromContents(), mais qu'ils laissent l'implémentation QCommonStyle s'en charger. Si des modifications doivent être apportées, il faut essayer de les limiter ; le développement d'applications peut être difficile si la disposition des widgets est très différente selon les styles.
Style Java
Nous avons implémenté un style qui ressemble à l'apparence par défaut de Java (anciennement connu sous le nom de Metal). Nous l'avons fait parce qu'il est relativement simple à mettre en œuvre et que nous voulions créer un style pour ce document de synthèse. Pour rester simple et ne pas trop s'étendre, nous avons quelque peu simplifié le style, mais Qt est parfaitement capable de faire une copie exacte du style. Cependant, il n'y a pas de projet concret d'implémentation du style dans Qt.
Dans cette section, nous examinerons certains problèmes d'implémentation. Enfin, nous verrons un exemple complet du style d'un widget Java. Nous continuerons à utiliser le style Java tout au long du document pour les exemples et les images des widgets. L'implémentation elle-même est quelque peu complexe et il n'est pas prévu que vous la lisiez en entier.
Conception et mise en œuvre
La première étape de la conception du style a consisté à sélectionner la classe de base. Nous avons choisi de sous-classer QCommonStyle. Cette classe met en œuvre la plupart des fonctionnalités dont nous avons besoin, à l'exception du dessin proprement dit.
Le style est implémenté dans une seule classe. Nous avons procédé ainsi parce que nous trouvons pratique de conserver tout le code dans un seul fichier. C'est également un avantage en termes d'optimisation, car nous instancions moins d'objets. Nous maintenons également le nombre de fonctions au minimum en utilisant des commutateurs pour identifier l'élément à dessiner dans les fonctions. Il en résulte des fonctions volumineuses, mais comme nous divisons le code pour chaque élément dans les commutateurs, le code devrait rester facile à lire.
Limites et différences par rapport à Java
Nous n'avons pas implémenté tous les éléments du style Java. Nous avons ainsi réduit la quantité et la complexité du code. En général, le style a été conçu comme un exemple pratique pour ce document de présentation du style, et non comme une partie de Qt lui-même.
Tous les widgets n'ont pas tous les états implémentés. Il en va de même pour les états communs, par exemple State_Disabled. Chaque état est cependant implémenté pour au moins un widget.
Nous n'avons implémenté que les ticks sous le curseur. Les boutons-poussoirs plats ne sont pas non plus pris en compte. Nous ne traitons pas le cas où les barres de titre et les titres des fenêtres d'ancrage deviennent trop petits pour leur contenu, mais nous dessinons simplement des sous-contrôles les uns sur les autres.
Nous n'avons pas essayé d'émuler les polices Java. Java et Qt utilisent des moteurs de polices très différents, et nous ne pensons pas que cela vaille la peine, car nous n'utilisons le style qu'à titre d'exemple pour cette présentation.
Nous avons codé en dur les couleurs (nous n'utilisons pas le site QPalette) pour les dégradés linéaires, qui sont utilisés, par exemple, pour les biseaux des boutons, les barres d'outils et les cases à cocher. En effet, la palette Java ne peut pas produire ces couleurs. De toute façon, Java ne modifie pas ces couleurs en fonction du groupe de couleurs ou du rôle du widget (elles ne dépendent pas de la palette), ce qui ne pose donc aucun problème.
Ce sont les widgets de Qt Widgets qui sont stylisés. Certains widgets n'existent pas du tout en Java, par exemple QToolBox. D'autres contiennent des éléments que les widgets Java n'ont pas. Le widget arbre est un exemple de ce dernier, dans lequel le JTree de Java n'a pas d'en-tête.
Le style ne gère pas les mises en page inversées. Nous supposons que la disposition est de gauche à droite. QCommonStyle gère les widgets inversés ; si nous mettions en œuvre des dispositions inversées, les widgets qui modifient la position des sous-éléments ou qui gèrent eux-mêmes l'alignement du texte dans les étiquettes devraient être mis à jour.
Styliser les cases à cocher Java
À titre d'exemple, nous allons examiner le style des cases à cocher dans le style Java. Nous décrivons le processus complet et imprimons tout le code à la fois dans le style Java et dans les classes Qt concernées. Dans le reste de ce document, nous n'examinerons pas le code source des différents widgets. Nous espérons que cela vous donnera une idée de la manière de rechercher dans le code si vous avez besoin de vérifier des détails d'implémentation spécifiques ; la plupart des widgets suivent la même structure que les cases à cocher. Nous avons quelque peu modifié le code de QCommonStyle pour supprimer le code qui n'est pas directement pertinent pour le style des cases à cocher.
Nous commençons par regarder comment QCheckBox construit son option de style, qui est QStyleOptionButton pour les cases à cocher :
opt.initFrom(q); if (down) opt.state |= QStyle::State_Sunken; if (tristate && noChange) opt.state |= QStyle::State_NoChange; else opt.state |= checked ? QStyle::State_On : QStyle::State_Off; if (q->testAttribute(Qt::WA_Hover) && q->underMouse()) { if (hovering) opt.state |= QStyle::State_MouseOver; else opt.state &= ~QStyle::State_MouseOver; } opt.text = text; opt.icon = icon; opt.iconSize = q->size();
Tout d'abord, nous laissons QStyleOption configurer l'option avec les informations communes à tous les widgets avec initFrom(). Nous y reviendrons plus tard.
QStyleOptionLa variable down est true lorsque l'utilisateur appuie sur la case ; ceci est vrai pour la case à cocher, qu'elle soit cochée ou non. L'état State_NoChange est défini lorsque nous avons une case à cocher à trois états et qu'elle est partiellement cochée. L'état est State_On si la case est cochée et State_Off si elle est décochée. State_MouseOver est défini si la souris survole la case à cocher et que le widget a l'attribut Qt::WA_Hover défini - vous le définissez dans QStyle::polish(). En outre, l'option de style contient également le texte, l'icône et la taille de l'icône du bouton.
initFrom() configure l'option de style avec les attributs communs à tous les widgets. Nous imprimons ici sa mise en œuvre :
state = QStyle::State_None; if (widget->isEnabled()) state |= QStyle::State_Enabled; if (widget->hasFocus()) state |= QStyle::State_HasFocus; if (widget->window()->testAttribute(Qt::WA_KeyboardFocusChange)) state |= QStyle::State_KeyboardFocusChange; if (widget->underMouse()) state |= QStyle::State_MouseOver; if (widget->window()->isActiveWindow()) state |= QStyle::State_Active; #ifdef QT_KEYPAD_NAVIGATION if (widget->hasEditFocus()) state |= QStyle::State_HasEditFocus; #endif direction = widget->layoutDirection(); rect = widget->rect(); palette = widget->palette(); fontMetrics = widget->fontMetrics();
L'option State_Enabled est activée lorsque le widget est activé. Lorsque le widget a le focus, le drapeau State_HasFocus est activé. De même, l'indicateur State_Active est activé lorsque le widget est un enfant de la fenêtre active. L'indicateur State_MouseOver n'est activé que si l'indicateur WA_HoverEnabled est activé pour le widget. Notez que la navigation au clavier doit être activée dans Qt XML pour que le drapeau State_HasEditFocus soit inclus ; il n'est pas inclus par défaut.
Outre la définition des drapeaux d'état, QStyleOption contient d'autres informations sur le widget : direction est la direction de la mise en page, rect est le rectangle de délimitation du widget (la zone dans laquelle dessiner), palette est le QPalette qui doit être utilisé pour dessiner le widget et fontMetrics est la métrique de la police de caractères utilisée par le widget.
Nous donnons l'image d'une case à cocher et l'option de style qui lui correspond.

La case à cocher ci-dessus aura les drapeaux d'état suivants dans son option de style :
| Drapeau d'état | Défini |
|---|---|
State_Sunken | Oui |
State_NoChange | Non |
State_On | Oui |
State_Off | Non |
State_MouseOver | Oui |
State_Enabled | Oui |
State_HasFocus | Oui |
State_KeyboardFocusChange | Non |
State_Active | Oui |
Le QCheckBox se peint lui-même en QWidget::paintEvent() avec l'option de style opt et QStylePainter p . La classe QStylePainter est une classe de commodité qui permet de dessiner des éléments de style. Elle englobe notamment les méthodes de QStyle utilisées pour la peinture. La classe QCheckBox se dessine elle-même comme suit :
QStylePainter p; QStyleOptionButton opt; initStyleOption(&opt); p.drawControl(QStyle::CE_CheckBox, opt);
QCommonStyle elle gère l'élément CE_CheckBox. Le site QCheckBox possède deux sous-éléments : SE_CheckBoxIndicator (l'indicateur de case cochée) et SE_CheckBoxContents (le contenu, qui est utilisé pour l'étiquette de la case à cocher). QCommonStyle implémente également les rectangles de délimitation de ces sous-éléments. Nous allons maintenant examiner le code de QCommonStyle:
QStyleOptionButton subopt = *btn; subopt.rect = subElementRect(QStyle::SE_CheckBoxIndicator, btn, widget); drawPrimitive(QStyle::PE_IndicatorCheckBox, &subopt, p, widget); subopt.rect = subElementRect(QStyle::SE_CheckBoxContents, btn, widget); drawControl(QStyle::CE_CheckBoxLabel, &subopt, p, widget); if (btn->state & State_HasFocus) { QStyleOptionFocusRect fropt; fropt.QStyleOption::operator=(*btn); fropt.rect = subElementRect(QStyle::SE_CheckBoxFocusRect, btn, widget); drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, p, widget); }
Comme le montre l'extrait de code, le style commun obtient les rectangles de délimitation des deux sous-éléments de CE_CheckBox, puis les dessine. Si la case à cocher est mise en évidence, le cadre de mise en évidence est également dessiné.
Le style Java dessine CE_CheckBoxIndicator, tandis que QCommonStyle s'occupe de CE_CheckboxLabel. Nous allons examiner chaque implémentation et commencer par CE_CheckBoxLabel :
const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt); uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter); if (!styleHint(SH_UnderlineShortcut, btn, widget)) alignment |= Qt::TextHideMnemonic; QPixmap pix; QRect textRect = btn->rect; if (!btn->icon.isNull()) { const auto dpr = p->device()->devicePixelRatio(); pix = btn->icon.pixmap(btn->iconSize, dpr, btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled); drawItemPixmap(p, btn->rect, alignment, pix); if (btn->direction == Qt::RightToLeft) textRect.setRight(textRect.right() - btn->iconSize.width() - 4); else textRect.setLeft(textRect.left() + btn->iconSize.width() + 4); } if (!btn->text.isEmpty()){ drawItemText(p, textRect, alignment | Qt::TextShowMnemonic, btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText); }
visualAlignment() ajuste l'alignement du texte en fonction de la direction de la mise en page. Nous dessinons ensuite une icône, si elle existe, et ajustons l'espace laissé au texte. drawItemText() dessine le texte en tenant compte de l'alignement, du sens de la mise en page et du mnémonique. Il utilise également la palette pour dessiner le texte dans la bonne couleur.
Le dessin des étiquettes est souvent un peu compliqué. Heureusement, il peut généralement être géré par la classe de base. Le style Java implémente sa propre étiquette de bouton-poussoir, puisque Java centre le contenu du bouton également lorsque le bouton a une icône. Vous pouvez examiner cette implémentation si vous avez besoin d'un exemple de réimplémentation du dessin des étiquettes.
Nous allons maintenant examiner l'implémentation Java de CE_CheckBoxIndicator à l'adresse drawControl():
case PE_IndicatorCheckBox: { painter->save(); drawButtonBackground(option, painter, true); if (option->state & State_Enabled && option->state & State_MouseOver && !(option->state & State_Sunken)) { painter->setPen(option->palette.color(QPalette::Button)); QRect rect = option->rect.adjusted(1, 1, -2, -2); painter->drawRect(rect); rect = rect.adjusted(1, 1, -1, -1); painter->drawRect(rect); } if (option->state & State_On) { QImage image(":/images/checkboxchecked.png"); painter->drawImage(option->rect.topLeft(), image); } painter->restore(); break;
Nous commençons par sauvegarder l'état du peintre. Ce n'est pas toujours nécessaire, mais dans ce cas, QCommonStyle a besoin que le peintre soit dans le même état que lorsqu'il a été appelé par PE_IndicatorCheckBox (nous pourrions aussi définir l'état par des appels de fonction, bien sûr). Nous utilisons ensuite drawButtonBackground() pour dessiner l'arrière-plan de l'indicateur de case à cocher. Il s'agit d'une fonction d'aide qui dessine l'arrière-plan et le cadre des boutons-poussoirs et des cases à cocher. Nous examinons cette fonction ci-dessous. Nous vérifions ensuite si la souris survole la case à cocher. Si c'est le cas, nous dessinons le cadre que les cases à cocher Java ont lorsque la case n'est pas enfoncée et que la souris est au-dessus d'elle. Vous remarquerez que Java ne gère pas les cases à trois états, c'est pourquoi nous ne l'avons pas implémenté.
Nous utilisons ici une image PNG pour notre indicateur. Nous pourrions également vérifier si le widget est désactivé. Nous devrions alors utiliser une autre image avec l'indicateur dans la couleur désactivée.
void JavaStyle::drawButtonBackground(const QStyleOption *option, QPainter *painter, bool isCheckbox) const { QBrush buttonBrush = option->palette.button(); bool sunken = option->state & State_Sunken; bool disabled = !(option->state & State_Enabled); bool on = option->state & State_On; if (!sunken && !disabled && (!on || isCheckbox)) buttonBrush = gradientBrush(option->rect); painter->fillRect(option->rect, buttonBrush); QRect rect = option->rect.adjusted(0, 0, -1, -1); if (disabled) painter->setPen(option->palette.color(QPalette::Disabled, QPalette::WindowText)); else painter->setPen(option->palette.color(QPalette::Mid)); painter->drawRect(rect); if (sunken && !disabled) { drawSunkenButtonShadow(painter, rect, option->palette.color(QPalette::Mid), option->direction == Qt::RightToLeft); } }
Nous avons vu comment les cases à cocher sont stylisées dans le style Java, depuis le moment où le widget reçoit une demande de peinture jusqu'au moment où le style a fini d'être peint. Pour apprendre en détail comment chaque widget est peint, vous devez parcourir le code étape par étape, comme nous l'avons fait ici. Cependant, il suffit généralement de savoir quels éléments de style les widgets dessinent. Le widget construit une option de style et fait appel au style une ou plusieurs fois pour dessiner les éléments de style qui le composent. En général, il suffit également de connaître les états dans lesquels un widget peut se trouver et les autres contenus de l'option de style, c'est-à-dire ce que nous énumérons dans la section suivante.
Présentation du widget
Dans cette section, nous allons examiner comment la plupart des widgets de Qt Widgets sont stylisés. Nous espérons que cela vous permettra d'économiser du temps et des efforts lors du développement de vos propres styles et widgets. Vous ne trouverez pas ici d'informations qui ne soient pas accessibles ailleurs (c'est-à-dire en examinant le code source ou les descriptions des classes liées au style).
Nous utilisons principalement des widgets de style Java comme exemples. Le style Java ne dessine pas tous les éléments des arbres d'éléments. Cela s'explique par le fait qu'ils ne sont pas visibles pour ce widget dans le style Java. Nous veillons néanmoins à ce que tous les éléments soient implémentés d'une manière conforme au style Java, car les widgets personnalisés pourraient en avoir besoin (ce qui n'exclut pas de laisser les implémentations à QCommonStyle ).
Les éléments suivants sont fournis pour chaque widget :
- Un tableau avec les membres (variables, etc.) de son option de style.
- Un tableau des drapeaux d'état (QStyle::StateFlag) qui peuvent être activés sur le widget et quand les états sont activés.
- Son arbre d'éléments (voir la section Les éléments de style).
- Une image du widget dans laquelle les éléments sont soulignés.
L'arbre des éléments contient les éléments de style primitifs, de contrôle et complexes. En parcourant l'arbre des éléments de haut en bas, on obtient l'ordre dans lequel les éléments doivent être dessinés. Dans les nœuds, nous avons écrit les rectangles des sous-éléments, les sous-éléments de contrôle et les métriques de pixels à prendre en compte pour dessiner l'élément du nœud.
Notre approche du style est centrée sur le dessin des widgets. Les calculs des rectangles des sous-éléments, des sous-contrôles et des métriques de pixels utilisés lors du dessin sont uniquement répertoriés en tant que contenu dans les arbres d'éléments. Il convient de noter que certains rectangles et certaines mesures de pixels ne sont utilisés que par les widgets. Ces calculs ne sont donc pas traités dans le guide. Par exemple, les fonctions subControlRect() et sizeFromContents() appellent souvent subElementRect() pour calculer leurs rectangles de délimitation. Nous pourrions également dessiner des arbres pour cela. Cependant, la manière dont ces calculs sont effectués dépend entièrement des styles individuels, et ils ne doivent pas suivre une structure spécifique (Qt n'impose pas de structure spécifique). Vous devez néanmoins vous assurer que vous utilisez les métriques de pixels appropriées. Pour limiter la taille du document, nous avons donc choisi de ne pas inclure d'arbres ni de décrire les calculs effectués par le style Java (ou tout autre style).
Il se peut que vous ne sachiez pas comment utiliser les différentes métriques de pixels, les rectangles de sous-éléments et les rectangles de sous-contrôle lors de l'examen des arbres. Si vous avez des doutes après avoir lu les descriptions de l'enum QStyle, nous vous suggérons d'examiner l'implémentation QCommonStyle.
Certains des rectangles de délimitation que nous décrivons dans les images des widgets sont égaux. Cela s'explique par le fait que certains éléments dessinent des arrière-plans tandis que d'autres dessinent des cadres et des étiquettes. En cas de doute, vérifiez la description de chaque élément sur QStyle. En outre, certains éléments sont là pour mettre en page, c'est-à-dire pour décider où dessiner, d'autres éléments.
Propriétés communes des widgets
Certains états et variables sont communs à tous les widgets. Ils sont définis à l'aide de QStyleOption::initFrom(). Tous les éléments n'utilisent pas cette fonction ; ce sont les widgets qui créent les options de style et, pour certains éléments, les informations fournies par initFrom() ne sont pas nécessaires.
Voici un tableau des états communs :
| État | État Défini quand |
|---|---|
State_Enabled | Défini si le widget n'est pas désactivé (voir QWidget::setEnabled()) |
State_Focus | Activé si le widget a le focus (voir QWidget::hasFocus()) |
State_KeyboardFocusChange | Défini lorsque l'utilisateur change le focus avec le clavier (voir Qt::WA_KeyboardFocusChange) |
State_MouseOver | Défini si le curseur de la souris est au-dessus du widget |
State_Active | Défini si le widget est un enfant de la fenêtre active. |
State_HasEditFocus | Défini si le widget a le focus d'édition |
Les autres membres courants pour les widgets sont les suivants :
| Membre | Contenu |
|---|---|
| rect | Le rectangle de délimitation de l'élément à dessiner. Il est défini sur le rectangle de délimitation du widget (QWidget::rect()). |
| direction | La direction de la mise en page ; une valeur de l'énumération Qt::LayoutDirection. |
| palette | Le site QPalette à utiliser pour dessiner l'élément. Cette valeur correspond à la palette du widget (QWidget::palette()). |
| fontMetrics | QFontMetrics à utiliser pour dessiner le texte sur le widget. |
Les options de style complexe (classes qui héritent de QStyleOptionComplex) utilisées pour les éléments de style complexe partagent deux variables : subControls et activeSubControls. Ces deux variables sont une combinaison OU de valeurs de l'énumération QStyle::SubControl. Elles indiquent les sous-contrôles du contrôle complexe et ceux qui sont actuellement actifs.
Comme indiqué, le style calcule la taille du contenu du widget, à partir duquel les widgets calculent leurs indices de taille. En outre, les contrôles complexes utilisent également le style pour tester les sous-contrôles sur lesquels la souris se trouve.
Référence du widget
Sans plus attendre, nous vous présentons le guide des widgets ; chaque widget a sa propre sous-section.
Boutons poussoirs
La structure de style des boutons poussoirs est présentée ci-dessous. En parcourant l'arbre de haut en bas, on obtient l'ordre dans lequel les éléments doivent être dessinés.

La disposition des boutons, en ce qui concerne les limites des éléments, varie d'un style à l'autre. Il est donc difficile d'en montrer des images conceptuelles. En outre, les éléments peuvent avoir les mêmes limites, même si c'est leur intention ; le bouton PE_PushButtonBevel, par exemple, est utilisé dans QCommonStyle pour dessiner les éléments qu'il contient : PE_FrameDefaultButton PE_FrameButtonBevel PE_PanelButtonCommand PE_PushButtonBevel est également chargé de dessiner l'indicateur de menu (QCommonStyle dessine PE_IndicatorArrowDown).
Une image d'un bouton poussoir dans le style Java qui montre les rectangles de délimitation des éléments est donnée ci-dessous. Les couleurs sont utilisées pour séparer les rectangles de délimitation dans l'image ; elles n'ont pas d'autre fonction. Il en va de même pour les images similaires des autres widgets.

Le style Java, ainsi que tous les autres styles implémentés dans Qt XML, n'utilise pas PE_FrameButtonBevel. Il est habituel qu'un bouton avec PE_DefaultFrame ajuste le rectangle de PE_PanelButtonCommand de PM_ButtonDefaultIndicator. Le CE_PushButtonLabel est trouvé en ajustant le rectangle de PM_DefaultFrameWidth.
Nous allons maintenant examiner l'option de style pour les boutons-poussoirs - QStyleOptionButton. Voici un tableau des états que QPushButton peut définir sur l'option de style :
| État | État défini lorsque |
|---|---|
State_Sunken | Le bouton est enfoncé ou le menu est pressé. |
State_On | Le bouton est coché |
State_Raised | Le bouton n'est pas plat et n'est pas enfoncé |
Les autres membres de QStyleOptionButton sont :
| Membre | Contenu |
|---|---|
| caractéristiques | Drapeaux de l'enum QStyleOptionButton::ButtonFeatures, qui décrit diverses propriétés des boutons (voir enum) |
| icône | Le bouton QIcon (le cas échéant) |
| iconSize | Le QSize de l'icône |
| text | une QString avec le texte des boutons |
Boutons de contrôle et boutons radio
Les structures des boutons radio et des boutons de contrôle sont identiques. Nous montrons la structure en utilisant les noms des éléments et des métriques de pixels sur QCheckBox:

QStyleOptionButton est utilisé comme option de style pour les boutons de contrôle et les boutons radio. Nous présentons tout d'abord un tableau des états qui peuvent être définis dans l'option :
| État | État défini lorsque |
|---|---|
State_sunken | La case est enfoncée |
State_NoChange | La case est partiellement cochée (pour les cases à cocher à trois états). |
State_On | La case est cochée |
State_Off | La case est décochée |
Voir Boutons poussoirs pour un tableau sur les autres membres de la classe QStyleOptionButton.
Onglets
Dans Qt, QTabBar utilise le style pour dessiner ses onglets. Les onglets existent soit dans un QTabWidget, qui contient un QTabBar, soit en tant que barre séparée. Si la barre ne fait pas partie d'un widget d'onglet, elle dessine sa propre base.
QTabBar C'est le style qui dispose les onglets, le style n'a donc pas de contrôle sur l'emplacement des onglets. Toutefois, lors de la mise en place des onglets, la barre demande au style PM_TabBarTabHSpace et PM_TabBarTabVSpace, ce qui représente une largeur et une hauteur supplémentaires par rapport à la taille minimale de l'étiquette (icône et texte) de la barre d'onglets. Le style peut également influencer la taille de l'onglet avant qu'il ne soit mis en place, car la barre d'onglets demande CT_TabBarTab. Le rectangle de délimitation de la barre est déterminé par le widget de l'onglet lorsqu'il fait partie du widget (toujours en tenant compte de CT_TabBarTab).
La barre d'onglets est responsable du dessin des boutons qui apparaissent sur la barre d'onglets lorsque tous les onglets ne tiennent pas. Leur emplacement n'est pas contrôlé par le style, mais les boutons sont QToolButtons et sont donc dessinés par le style.
Voici la structure des styles pour QTabWidget et QTabBar:

Les lignes pointillées indiquent que QTabWidget contient une barre d'onglets, mais ne dessine pas la barre d'onglets elle-même. QTabBar ne dessine que sa ligne de base lorsqu'il ne fait pas partie d'un widget d'onglets, et il conserve deux boutons d'outils qui font défiler la barre lorsque tous les onglets ne tiennent pas ; voir Boutons d'outils pour leur arbre d'éléments. Notez également que les boutons étant des enfants de la barre d'onglets, ils sont dessinés après la barre. Les rectangles de délimitation des onglets chevauchent la base de PM_TabBarBaseOverlap.
Voici un widget d'onglet dans le style Java :

Dans le style Java, la forme et l'étiquette de la barre d'onglets ont le même rectangle de délimitation que CE_TabBarTab. Remarquez que les onglets se superposent au cadre du widget d'onglets. La base de la barre d'onglets (si elle est dessinée) est la zone où les onglets et le cadre se chevauchent.
L'option de style pour les onglets (QStyleOptionTab) contient les informations nécessaires pour dessiner les onglets. L'option contient la position de l'onglet dans la barre d'onglets, la position de l'onglet sélectionné, la forme de l'onglet, le texte, l'icône et la taille de l'icône.
Comme les onglets de style Java ne se chevauchent pas, nous présentons également une image d'un widget d'onglet dans le style commun. Notez que si vous souhaitez que les onglets se chevauchent horizontalement, vous devez le faire lorsque vous dessinez les onglets dans CE_TabBarTabShape; les rectangles de délimitation des onglets ne seront pas modifiés par la barre d'onglets. Les onglets sont dessinés de gauche à droite dans une forme de barre d'onglets nord, de haut en bas dans une forme de barre d'onglets est, etc. L'onglet sélectionné est dessiné en dernier, afin qu'il soit facile de le dessiner au-dessus des autres onglets (s'il doit être plus grand).

Voici un tableau des états qu'une barre d'onglets peut définir sur ses onglets :
| État | État défini lorsque |
|---|---|
State_Sunken | On appuie sur l'onglet avec la souris. |
State_Selected | S'il s'agit de l'onglet actuel. |
State_HasFocus | La barre d'onglets a le focus et l'onglet est sélectionné. |
Notez que les onglets individuels peuvent être désactivés même si la barre d'onglets ne l'est pas. L'onglet sera actif si la barre d'onglets est active.
Voici un tableau des membres de QStyleOptionTab:
| Membre | Contenu |
|---|---|
| cornerWidgets | Drapeaux de l'énumération CornerWidget, qui indiquent si la barre d'onglets possède des widgets d'angle et lesquels. |
| icon | QIcon de l'onglet. |
| iconSize | La taille QSize de l'icône. |
| position | Une valeur TabPosition enum qui indique la position de l'onglet sur la barre par rapport aux autres onglets. |
| row | Indique la rangée dans laquelle se trouve l'onglet. |
| selectedPosition | Valeur de l'énumération SelectedPosition indiquant si l'onglet sélectionné est adjacent à l'onglet ou s'il s'agit de l'onglet lui-même. |
| forme | Valeur de l'énumération QTabBar::Shape indiquant si l'onglet a des coins arrondis ou triangulaires et l'orientation de l'onglet. |
| texte | Le texte de l'onglet. |
Le cadre des widgets d'onglets utilise QStyleOptionTabWidgetFrame comme option de style. La liste de ses membres est donnée ici. Il n'a pas d'états définis en dehors des drapeaux communs.
| Membre | contenu |
|---|---|
| leftCornerWidgetSize | QSize du widget du coin gauche (s'il y en a un). |
| rightCornerWidgetSize | QSize du widget du coin droit (le cas échéant). |
| lineWidth | Indique la largeur de la ligne pour dessiner le panneau. |
| midLineWith | Cette valeur est actuellement toujours égale à 0. |
| shape | Forme des onglets de la barre d'onglets. |
| tabBarSize | QSize de la barre d'onglets. |
Barres de défilement
Voici la structure de style des barres de défilement :

QScrollBar crée simplement son option de style, puis dessine CC_ScrollBar. Certains styles dessinent l'arrière-plan de la page et de la sous-page d'ajout avec PE_PanelButtonBevel, et utilisent également des flèches indicatrices pour dessiner les flèches des indicateurs de ligne suivante et précédente ; nous ne les avons pas incluses dans l'arbre, car leur utilisation est laissée à la discrétion de chaque style. Le style PM_MaximumDragDistance est la distance maximale en pixels que la souris peut parcourir à partir des limites de la barre de défilement tout en déplaçant la poignée.
Voici une image d'une barre de défilement dans le style Java :

Vous remarquerez peut-être que la barre de défilement est légèrement différente de celle de Java, car elle comporte deux indicateurs de ligne. Nous avons fait cela pour montrer qu'il est possible d'avoir deux rectangles de délimitation distincts pour un seul sous-contrôle. La barre de défilement est un exemple de widget entièrement implémenté par le style Java - QCommonStyle n'est pas impliqué dans le dessin.
Nous allons examiner les différents états qu'une barre de défilement peut définir dans l'option de style :
| État | État défini lorsque |
|---|---|
State_Horizontal | La barre de défilement est horizontale. |
L'option de style de QScrollBar est QStyleOptionSlider. Ses membres sont listés dans le tableau suivant. L'option est utilisée par tous les sites QAbstractSlider; nous ne décrivons ici que les membres pertinents pour les barres de défilement.
| Membre | Contenu |
|---|---|
| maximum | Valeur maximale de la barre de défilement. |
| minimum | La valeur minimale de la barre de défilement. |
| notchTarget | Le nombre de pixels entre les encoches. |
| orientation | Une valeur de l'enum Qt::Orientation qui indique si la barre de défilement est verticale ou horizontale. |
| pageStep | Nombre d'augmentation ou de diminution de la valeur du curseur (par rapport à la taille du curseur et à sa plage de valeurs) par pas de page. |
| singleStep | Nombre d'augmentation ou de diminution de la valeur du curseur par pas de page (ou de ligne). |
| sliderValue | La valeur du curseur. |
| sliderPosition | La position de la poignée du curseur. C'est la même chose que sliderValue si la barre de défilement est QAbstractSlider::tracking. Sinon, la barre de défilement ne met pas à jour sa valeur avant que la souris ne relâche la poignée. |
| upsideDown | Indique la direction dans laquelle la barre de défilement augmente sa valeur. Ce paramètre est utilisé à la place de QStyleOption::direction pour tous les curseurs abstraits. |
Curseurs
Lors du calcul de l'indice de taille du curseur, PM_SliderThickness et PM_SliderLength sont demandés à partir du style. Comme pour les barres de défilement, QSlider ne permet à l'utilisateur de déplacer la poignée que si la souris se trouve à l'intérieur de PM_MaximumDragDistance des limites du curseur. Lorsqu'il se dessine, il crée l'option de style et appelle drawComplexControl() avec CC_Slider:

Nous montrons également l'image d'un curseur dans le style Java. Nous montrons les rectangles de délimitation des sous-éléments, car tous les dessins sont effectués dans CC_Slider.

QSlider utilise QStyleOptionSlider comme tous les QAbstractSlider. Nous présentons un tableau avec les membres qui affectent QSlider:
| Membre | Contenu |
|---|---|
| maximum | La valeur maximale du curseur. |
| minimum | La valeur minimale du curseur. |
| cible de l'encoche | C'est le nombre de pixels entre chaque encoche. |
| orientation | Valeur de l'enum Qt::Orientation indiquant si le curseur est vertical ou horizontal. |
| pageStep | Nombre d'augmentation ou de diminution de la valeur du curseur par pas de page. |
| singleStep | Nombre permettant d'augmenter ou de diminuer la valeur du curseur par pas de page (ou de ligne). |
| sliderValue | La valeur du curseur. |
| sliderPosition | La position du curseur donnée comme valeur du curseur. Cette valeur sera égale à sliderValue si le curseur est tracking; sinon, la valeur du curseur ne changera pas jusqu'à ce que la poignée soit relâchée avec la souris. |
| upsideDown | Ce membre est utilisé à la place de QStyleOption::direction pour tous les curseurs abstraits. |
Il convient de noter que le curseur n'utilise pas la direction pour les mises en page inversées ; il utilise upsideDown.
Boîtes tournantes
Lorsque QSpinBox se peint lui-même, il crée un QStyleOptionSpinBox et demande au style de dessiner CC_SpinBox. Le champ d'édition est une ligne d'édition qui est un enfant de la boîte de rotation. Les dimensions du champ sont calculées par le style à l'aide de SC_SpinBoxEditField.
Voici l'arbre des styles pour les boîtes à outils. Il n'est pas nécessaire qu'un style utilise la primitive du panneau de boutons pour peindre les arrière-plans des indicateurs. Vous pouvez voir une image sous l'arbre montrant les sous-éléments dans QSpinBox dans le style Java.


Le style QStyleOptionSpinBox, qui est l'option de style pour les boîtes tournantes. Il permet de définir les états suivants sur la boîte à boutons :
| État | État Défini lorsque |
|---|---|
State_Sunken | Est activé si l'un des sous-contrôles CC_SpinUp ou CC_SpinDown est activé à l'aide de la souris. |
Les autres membres des options de style de la boîte tournante sont les suivants :
| Propriété | Fonction |
|---|---|
| cadre | Booléen qui vaut true si la boîte tournante doit dessiner un cadre. |
| buttonSymbols | Valeur de l'énumération ButtonSymbols qui détermine le symbole des boutons haut/bas. |
| stepEnabled | Valeur de l'énumération StepEnabled, indiquant quels boutons de la boîte à boutons sont enfoncés. |
Barre de titre
Le contrôle complexe de la barre de titre, CC_TitleBar, est utilisé pour dessiner les barres de titre des fenêtres internes dans QMdiArea. Il se compose généralement d'un titre de fenêtre et de boutons de fermeture, de minimisation, de menu système et d'agrandissement. Certains styles proposent également des boutons pour ombrer la fenêtre, ainsi qu'un bouton pour l'aide contextuelle.
La barre est dessinée à l'adresse CC_TitleBar sans utiliser de sous-éléments. La manière dont les styles individuels dessinent leurs boutons est laissée à leur discrétion, mais il existe des pixmaps standard pour les boutons que le style doit fournir.

Dans une image au-dessus d'une barre de titre dans le style Java, nous montrons les rectangles de délimitation des sous-éléments pris en charge par le style Java (qui sont tous dessinés avec des pixmaps standard). Il est habituel de dessiner l'arrière-plan des boutons à l'aide de PE_PanelButtonTool, mais ce n'est pas obligatoire.

L'option de style pour les barres de titre est QStyleOptionTitleBar. Ses membres sont les suivants :
| Membre | Contenu |
|---|---|
| icône | L'icône de la barre de titre. |
| texte | Le texte de l'étiquette de la barre de titre. |
| windowFlags | Drapeaux de l'énumération Qt::WindowFlag. Les drapeaux de fenêtre utilisés par QMdiArea pour la gestion des fenêtres. |
| titleBarState | Il s'agit de l'adresse QWidget::windowState() de la fenêtre qui contient la barre de titre. |
Boîte combinée
Une QComboBox utilise le style pour dessiner le bouton et l'étiquette des boîtes non modifiables avec CC_ComboBox et CE_ComboBoxLabel.
La liste qui s'affiche lorsque l'utilisateur clique sur la boîte combinée est dessinée par un délégué, que nous n'aborderons pas dans cette présentation. Vous pouvez toutefois utiliser le style pour contrôler la taille et la position de la liste à l'aide du sous-élément SC_ComboBoxListBoxPopup. Le style détermine également l'emplacement du champ d'édition des cases modifiables à l'aide de SC_ComboBoxEditField; le champ lui-même est un élément QLineEdit qui est un enfant de la liste déroulante.

Nous montrons une image d'une liste déroulante de style Java dans laquelle nous avons souligné ses sous-éléments et ses rectangles de sous-éléments :

Les combo-boxes Java n'utilisent pas le rectangle de mise au point ; elles changent de couleur d'arrière-plan lorsqu'elles ont la mise au point. Le champ SC_ComboBoxEdit est utilisé à la fois par QComboBox pour calculer la taille du champ d'édition et par le style pour calculer la taille de l'étiquette de la liste déroulante.
L'option de style pour les zones combo est QStyleOptionComboBox. Elle permet de définir les états suivants :
| État | Défini lorsque |
|---|---|
State_Selected | La boîte n'est pas modifiable et a le focus. |
State_Sunken | SC_ComboBoxArrow est active. |
State_on | Le conteneur (liste) de la boîte est visible. |
Les options de style des autres membres sont :
| Membre | Contenu |
|---|---|
| currentIcon | L'icône de l'élément courant (sélectionné) de la liste déroulante. |
| currentText | Le texte de l'élément actuel de la boîte. |
| editable | Indique si la liste déroulante est modifiable ou non. |
| frame | Indique si la liste déroulante a un cadre ou non. |
| iconSize | La taille de l'icône de l'élément courant. |
| popupRect | Le rectangle de délimitation de la liste déroulante de la boîte combo. |
Boîtes de groupe
Lors du calcul de l'indice de taille, QGroupBox récupère trois mesures de pixels dans le style : PM_IndicatorWidth, PM_CheckBoxLabelSpacing, et PM_IndicatorHeight. QGroupBox possède l'arbre d'éléments de style suivant :

Qt XML n'impose pas de restrictions sur la manière dont la case à cocher est dessinée ; le style Java la dessine avec CE_IndicatorCheckBox. Voir Check and Radio Buttons pour l'arbre complet.
Nous donnons également une image du widget avec les sous-contrôles et les rectangles de sous-contrôle dessinés :

L'option de style pour les boîtes de groupe est QStyleOptionGroupBox. Les états suivants peuvent être définis :
| État | Défini lorsque |
|---|---|
State_On | La case est cochée. |
State_Sunken | La case à cocher est enfoncée. |
State_Off | La case est décochée (ou il n'y a pas de case). |
Les membres restants de QStyleOptionGroupBox sont :
| Membre | Contenu |
|---|---|
| caractéristiques | Drapeaux de l'énumération QStyleOptionFrame::FrameFeatures décrivant le cadre de la boîte de groupe. |
| lineWidth | Largeur de ligne avec laquelle le panneau doit être dessiné. Cette valeur est toujours égale à 1. |
| text | Le texte du cadre. |
| textAlignment | L'alignement du titre du cadre. |
| textColor | QColor du texte. |
Séparateurs
Comme la structure des séparateurs est simple et ne contient pas de sous-éléments, nous n'incluons pas d'images de séparateurs. CE_Splitter n'utilise pas d'autres éléments ou métriques.
Pour son option de style, le séparateur utilise la classe de base QStyleOption. Il peut définir les drapeaux d'état suivants :
| État | Défini quand |
|---|---|
State_Horizontal | Défini s'il s'agit d'un séparateur horizontal. |
QSplitter n'utilise pas initFrom() pour définir son option ; il définit lui-même les drapeaux State_MouseOver et State_Disabled.
Barre de progression
L'élément CE_ProgressBar est utilisé par QProgressBar, et c'est le seul élément utilisé par ce widget. Nous commençons par la structure du style :

Voici une barre de progression dans le style commun (les rectangles de délimitation du style Java sont égaux) :

L'option de style pour QProgressBar est QStyleOptionProgressBar. La barre ne définit aucun drapeau d'état, mais les autres membres de l'option le sont :
| Membre | Contenu |
|---|---|
| minimum | La valeur minimale de la barre. |
| maximum | La valeur maximale de la barre. |
| progression | La valeur actuelle de la barre. |
| alignement du texte | La façon dont le texte est aligné dans l'étiquette. |
| textVisible | Indique si l'étiquette est affichée. |
| text | Texte de l'étiquette. |
| orientation | Les barres de progression peuvent être verticales ou horizontales. |
| apparence inversée | La progression est inversée (c'est-à-dire de droite à gauche dans une barre horizontale). |
| bottomToTop | Booléen qui, si true, fait pivoter l'étiquette des barres de progression verticales de 90 degrés. |
Boutons d'outils
Les boutons d'outils peuvent être indépendants ou faire partie de barres d'outils. Ils sont dessinés de la même manière dans les deux cas. Le QToolButton ne dessine qu'un seul élément de style : CC_ToolButton.
Vous trouverez ci-dessous une arborescence de la structure de style du widget :

Notez que PE_FrameButtonTool et PE_IndicatorArrowDown sont inclus dans l'arbre tel que le style Java les dessine, mais ils peuvent être omis en toute sécurité si vous le préférez. La structure peut également être différente. QCommonStyle Le style Java, par exemple, dessine à la fois PE_IndicatorButtonDropDown et PE_IndicatorArrowDown dans CE_ToolButton.
Nous avons également une image d'un bouton d'outil dans laquelle nous avons souligné les rectangles de délimitation des sous-éléments et les sous-contrôles.

Voici le tableau des états des boutons d'outils :
| État | Défini quand |
|---|---|
State_AutoRise | La propriété autoRise est définie pour le bouton d'outil. |
State_Raised | Le bouton n'est pas enfoncé (c'est-à-dire qu'il n'a pas été contrôlé ou pressé avec la souris). |
State_Sunken | Le bouton est enfoncé. |
State_On | Le bouton est contrôlable et contrôlé. |
QStyleOptionToolButton contient également les membres suivants :
| Membre | Contenu |
|---|---|
| arrowType | Une valeur de l'enum Qt::ArrowType, qui contient la direction de la flèche du bouton (si une flèche doit être utilisée à la place d'une icône). |
| caractéristiques | Drapeaux de l'enum QStyleOptionToolButton::ButtonFeature décrivant si le bouton possède une flèche, un menu et/ou un délai d'affichage. |
| police | La police QFont de l'étiquette du bouton. |
| icon | Le QIcon du bouton de l'outil. |
| iconSize | La taille de l'icône du bouton. |
| pos | La position du bouton, telle qu'elle est donnée par QWidget::pos() |
| text | Le texte du bouton. |
| toolButtonStyle | Une valeur de l'enum Qt::ToolButtonStyle qui détermine si le bouton affiche l'icône, le texte ou les deux. |
Barres d'outils
Les barres d'outils font partie du site main window framework et coopèrent avec le site QMainWindow auquel elles appartiennent pendant qu'il élabore son option de style. Une fenêtre principale comporte quatre zones dans lesquelles les barres d'outils peuvent être placées. Elles sont placées à côté des quatre côtés de la fenêtre (c'est-à-dire au nord, au sud, à l'est et à l'ouest). Dans chaque zone, il peut y avoir plus d'une ligne de barres d'outils ; une ligne est constituée de barres d'outils de même orientation (verticale ou horizontale) placées l'une à côté de l'autre.
Toolbars Dans Qt, les barres d'outils sont constituées de trois éléments : CE_ToolBar PE_IndicatorToolBarHandle PE_IndicatorToolBarSeparator C'est QMainWindowLayout qui calcule les rectangles de délimitation (c'est-à-dire la position et la taille des barres d'outils et de leur contenu). La fenêtre principale utilise également le site sizeHint() des éléments des barres d'outils pour calculer la taille des barres.
Voici l'arbre des éléments pour QToolBar:

Les lignes pointillées indiquent que QToolBar conserve une instance de QToolBarLayout et que QToolBarSeparators est conservé par QToolBarLayout. Lorsque la barre d'outils est flottante (c'est-à-dire qu'elle a sa propre fenêtre), l'élément PE_FrameMenu est dessiné, sinon QToolBar dessine CE_ToolBar.
Voici une image d'une barre d'outils dans le style Java :

QToolBarSaparator utilise QStyleOption comme option de style. Il active l'indicateur State_Horizontal si la barre d'outils dans laquelle il se trouve est horizontale. Sinon, il utilise initFrom().
L'option de style pour QToolBar est QStyleOptionToolBar. Le seul indicateur d'état défini (en plus des indicateurs communs) est State_Horizontal si la barre est horizontale (c'est-à-dire dans la zone nord ou sud de la barre d'outils). Les variables membres de l'option de style sont les suivantes
| Membre | Contenu |
|---|---|
| caractéristiques | Indique si la barre est mobile dans une valeur de ToolBarFeature, qui est soit Movable, soit None. |
| lineWidth | Largeur du cadre de la barre d'outils. |
| midLineWidth | Cette variable n'est actuellement pas utilisée et vaut toujours 0. |
| positionOfLine | Position de la ligne de la barre d'outils dans la zone de la barre d'outils à laquelle elle appartient. |
| positionWithinLine | Position de la barre d'outils à l'intérieur de la ligne de la barre d'outils. |
| toolBarArea | La zone de la barre d'outils dans laquelle se trouve la barre d'outils. |
Menus
Les menus dans Qt sont implémentés dans QMenu. Le site QMenu conserve une liste d'actions qu'il affiche sous forme d'éléments de menu. Lorsque QMenu reçoit des événements de peinture, il calcule la taille de chaque élément de menu et les dessine individuellement avec CE_MenuItem. Les éléments de menu n'ont pas d'élément distinct pour leur étiquette (contenu), de sorte que tout le dessin est effectué dans CE_MenuItem. Le menu dessine également le cadre du menu avec PE_FrameMenu. Il dessine également CE_MenuScroller si le style prend en charge le défilement. CE_MenuTearOff est dessiné si le menu est trop grand pour son rectangle de délimitation.
Dans l'arbre de structure du style, nous incluons également QMenu car il effectue également des tâches liées au style. Les rectangles de délimitation des éléments de menu sont calculés en fonction de l'indice de taille du menu et lorsque le menu est affiché ou redimensionné.

Les éléments CE_MenuScroller et CE_MenuTearOff sont gérés par QCommonStyle et ne sont affichés que si le menu est trop grand pour tenir à l'écran. PE_FrameMenu n'est dessiné que pour les menus déroulants.
QMenu calcule les rectangles en fonction de ses actions et appelle CE_MenuItem et CE_MenuScroller si le style le permet.
Il est également courant d'utiliser PE_IndicatorCheckBox (au lieu de PE_IndicatorMenuCheckMark) et PE_IndicatorRadioButton pour dessiner des éléments de menu vérifiables ; nous ne les avons pas inclus dans l'arbre des styles car ils sont facultatifs et varient d'un style à l'autre.

L'option de style pour les éléments de menu est QStyleOptionMenuItem. Les tableaux suivants décrivent ses drapeaux d'État et ses autres membres.
| État | Défini lorsque |
|---|---|
State_Selected | La souris est au-dessus de l'action et celle-ci n'est pas un séparateur. |
State_Sunken | La souris est appuyée sur l'élément de menu. |
State_DownArrow | Défini si l'élément de menu est un défileur de menu et qu'il fait défiler le menu vers le bas. |
| Membre | Contenu |
|---|---|
| checkType | Une valeur de l'enum CheckType, qui est soit NotCheckable, Exclusive ou NonExclusive. |
| checked | Valeur booléenne qui est true si l'élément de menu est coché. |
| police | La police QFont à utiliser pour le texte de l'élément de menu. |
| icon | QIcon de l'élément de menu. |
| maxIconWidth | La largeur maximale autorisée pour l'icône. |
| menuHasCheckableItems | Booléen valant true si au moins un élément du menu est contrôlable. |
| menuItemType | Le type de l'élément de menu. Il s'agit d'une valeur de la variable MenuItemType. |
| menuRect | Le rectangle de délimitation du site QMenu dans lequel se trouve l'élément de menu. |
| tabWidth | Distance entre le texte de l'élément de menu et le raccourci. |
| texte | Le texte de l'élément de menu. |
La configuration de l'option de style pour CE_MenuTearOff et CE_MenuScroller utilise également QStyleOptionMenuItem; elle définit uniquement la variable menuRect en plus des paramètres communs avec QStyleOption's initFrom().
Barre de menu
QMenuBar utilise le style pour dessiner chaque élément de la barre de menu et la zone vide de la barre de menu. Les menus déroulants eux-mêmes sont des QMenu(voir Menus). L'arbre des éléments de style pour la barre de menu est le suivant :

Le panneau et la zone vide sont dessinés après les éléments du menu. Le site QPainter que QMenuBar envoie au style contient les rectangles de délimitation des éléments découpés (c'est-à-dire la région de découpage), de sorte que vous n'avez pas à vous soucier de dessiner par-dessus les éléments. Les mesures en pixels figurant sur le site QMenuBar sont utilisées lors du calcul des rectangles de délimitation des éléments de la barre de menu.

QStyleOptionMenuItem est utilisé pour les éléments de la barre de menu. Les membres utilisés par QMenuBar sont décrits dans le tableau suivant :
| Membre | Contenu |
|---|---|
| menuRect | Le rectangle de délimitation de l'ensemble de la barre de menu à laquelle l'élément appartient. |
| text | Le texte de l'élément. |
| icon | L'icône de l'élément de menu (il n'est pas courant que les styles dessinent cette icône). |
QStyleOptionMenuItem est également utilisé pour dessiner CE_EmptyMenuBarArea.
QStyleOptionFrame est utilisé pour dessiner le cadre du panneau. La valeur de lineWidth est fixée à PM_MenuBarPanelWidth. La valeur de midLineWidth est actuellement toujours fixée à 0.
En-têtes des vues d'éléments
C'est le style qui dessine les en-têtes des vues d'éléments de Qt. Les vues d'éléments conservent les dimensions des sections individuelles. Notez également que les délégués peuvent utiliser ce style pour peindre des décorations et des cadres autour des éléments. QItemDelegate Par exemple, le style de la page d'accueil de Qt, PE_FrameFocusRect et PE_IndicatorItemViewItemCheck, dessine les pages d'accueil de la page d'accueil.

Voici une page QTableWidget montrant les zones de délimitation d'un en-tête Java :

Le site QHeaderView utilise les sites CT_HeaderSection, PM_HeaderMargin et PM_HeaderGripMargin pour le calcul de la taille et du test d'impact. PM_HeaderMarkSize n'est actuellement pas utilisé par Qt XML. QTableView dessine le bouton dans le coin supérieur gauche (c'est-à-dire la zone où les en-têtes verticaux et horizontaux se croisent) sous la forme d'un CE_Header.
L'option de style pour les vues d'en-tête est QStyleOptionHeader. La vue peint une section d'en-tête à la fois, de sorte que les données concernent la section en cours d'affichage. Son contenu est le suivant
| Membre | Contenu |
|---|---|
| icône | L'icône de l'en-tête (pour la section en cours de dessin). |
| alignement de l'icône | L'alignement (Qt::Alignment) de l'icône dans l'en-tête. |
| orientation | Une valeur Qt::Orientation qui détermine si l'en-tête est horizontal, au-dessus de la vue, ou vertical, à gauche. |
| position | Une valeur QStyleOptionHeader::SectionPosition indiquant la position de la section d'en-tête par rapport aux autres sections. |
| section | Contient la section qui est dessinée. |
| selectedPosition | Une valeur QStyleOptionHeader::SelectedPosition indiquant la position de la section sélectionnée par rapport à la section peinte. |
| sortIndicator (indicateur de tri) | Une valeur QStyleOptionHeader::SortIndicator décrivant la direction dans laquelle l'indicateur de tri de la section doit être dessiné. |
| texte | Le texte de la section actuellement dessinée. |
| textAlignment | L'adresse Qt::Alignment du texte dans la section d'en-tête. |
Indicateurs de branche d'arbre
Les indicateurs de branche dans une vue d'arbre sont dessinés par le style avec PE_IndicatorBranch. Nous entendons ici par indicateurs les indicateurs qui décrivent la relation entre les nœuds de l'arbre. Le générique QStyleOption est envoyé au style pour dessiner ces éléments. Les différents types de branches sont décrits par des états. Comme il n'y a pas d'option de style spécifique, nous présentons simplement la table des états :
| État | Défini lorsque |
|---|---|
State_Sibling | Le nœud de l'arbre a un frère (c'est-à-dire qu'il y a un autre nœud dans la même colonne). |
State_Item | Cet indicateur de branche a un élément. |
State_Children | La branche a des enfants (c'est-à-dire qu'un nouveau sous-arbre peut être ouvert dans la branche). |
State_Open | L'indicateur de branche a un sous-arbre ouvert. |
La vue de l'arbre (et le widget de l'arbre) utilise le style pour dessiner les branches (nœuds) de l'arbre.
QStyleOption est utilisé comme style pour PE_IndicatorBranch a des drapeaux d'état définis en fonction du type de branche dont il s'agit.
Comme il n'existe pas d'arborescence pour les indicateurs de branche, nous présentons uniquement une image d'un arbre dans le style Java. Chaque état est marqué dans l'image par un rectangle d'une couleur spécifique (c'est-à-dire que les rectangles ne sont pas des rectangles de délimitation). Toutes les combinaisons d'états que vous devez connaître sont représentées dans l'image.

Boîtes à outils
PM_SmallIconSize pour sizeHints.
QToolBox est un conteneur qui contient une collection de widgets. Il possède un onglet pour chaque widget et en affiche un à la fois. La boîte à outils place les composants qu'elle affiche (les boutons de la boîte à outils et le widget sélectionné) sur un site QVBoxLayout. L'arbre de style des boîtes à outils se présente comme suit :

Nous montrons une image d'une boîte à outils dans le style Plastique :

Tous les éléments ont les mêmes rectangles de délimitation dans le style Plastique ainsi que dans les autres styles Qt intégrés.
L'option de style pour les boîtes à outils est QStyleOptionToolBox. Elle contient le texte et l'icône du contenu de la boîte à outils. Le seul état défini par QToolBox est State_Sunken, qui est défini lorsque l'utilisateur appuie sur une tabulation à l'aide de la souris. Les autres membres de QStyleOptionToolBox sont les suivants
| Membre | Contenu |
|---|---|
| icône | L'icône de l'onglet de la boîte à outils. |
| texte | Le texte de l'onglet de la boîte à outils. |
Poignée de taille
La poignée de taille calcule son indice de taille avec CT_SizeGrip. La métrique des pixels PM_SizeGripSize est actuellement inutilisée par Qt XML. L'arbre des éléments d'une image dans le style Plastique de QSizeGrip est le suivant :


Nous montrons la poignée de taille dans le coin inférieur droit de QMainWindow.
L'option de style de poignée de taille, QStyleOptionSizeGrip, a un membre en plus des membres communs de QStyleOption:
| Membre | Contenu |
|---|---|
| coin | Une valeur Qt::Corner qui décrit le coin d'une fenêtre (ou équivalent) où se trouve la poignée. |
Bande de caoutchouc
L'arbre de style de QRubberBand est constitué de deux nœuds.

Nous présentons une image d'une fenêtre de style Java déplacée dans un site QMdiArea à l'aide d'un élastique :

L'option de style pour les élastiques est QStyleOptionRubberBand. Ses membres sont :
| Membre | Contenu |
|---|---|
| opaque | Booléen qui vaut true si l'élastique doit être dessiné dans un style opaque (c'est-à-dire en couleur). |
| shape (forme) | Une valeur enum QRubberBand::Shape qui contient la forme de l'élastique (qui est soit un rectangle, soit une ligne). |
Widgets d'ancrage
Lorsque le widget d'ancrage présente son contenu, il demande au style ces mesures de pixels : PM_DockWidgetSeparatorExtent PM_DockWidgetTitleBarButtonMargin , PM_DockWidgetFrameWidth, et PM_DockWidgetTitleMargin. Il calcule également les rectangles de délimitation des boutons "flotter" et "fermer" avec SE_DockWidgetCloseButton et SE_DockWidgetFloatButton.

Les lignes pointillées indiquent que l'expéditeur conserve des instances du destinataire de la flèche (c'est-à-dire qu'il ne s'agit pas d'un élément de style à dessiner). Le widget dock ne dessine PE_frameDockWidget que lorsqu'il est détaché de sa fenêtre principale (c'est-à-dire qu'il s'agit d'une fenêtre de niveau supérieur). S'il est ancré, il dessine la poignée de redimensionnement de l'indicateur du widget dock. Nous montrons un widget d'ancrage à la fois ancré et flottant dans le style plastique :

L'option de style est QStyleOptionDockWidget:
| Membre | Contenu |
|---|---|
| fermable | Booléen qui indique si la fenêtre d'ancrage peut être fermée. |
| flottant | Booléen indiquant si la fenêtre d'ancrage peut flotter (c'est-à-dire se détacher de la fenêtre principale dans laquelle elle se trouve). |
| mobile | Booléen indiquant si la fenêtre est mobile (c'est-à-dire qu'elle peut se déplacer vers d'autres zones du widget dock). |
| titre | Le texte du titre de la fenêtre d'ancrage. |
Pour les boutons, QStyleOptionButton est utilisé (voir Boutons d'outils pour une description du contenu). La poignée de redimensionnement du widget de la fenêtre d'ancrage est une simple QStyleOption.
© 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.