Sur cette page

Présentation des fonctionnalités de StyleKit

Cette page présente brièvement les principales fonctionnalités de StyleKit. Pour une référence complète de tous les types et propriétés disponibles, consultez la page « QML Types ».

Création d’un style

Un « Style » est un objet QML qui décrit l’apparence visuelle de tous les Qt Quick Controls éléments de votre application : button, slider, checkBox, etc. Chacun dispose de son propre groupe dans le style, où vous pouvez définir des propriétés telles que les couleurs, les tailles, les rayons et les ombres pour les éléments visuels qui composent le contrôle.

Le control group est particulier, car il sert de solution de secours pour tous les autres groupes de contrôles. Si vous omettez certaines propriétés pour un slider, par exemple, celles-ci seront alors lues à partir de control. Les propriétés non définies dans slider ou control sont alors réexploitées à partir de fallback style, qui est un style complet similaire au style de base. Cela signifie que vous n’avez pas nécessairement besoin de définir un style pour tous les contrôles disponibles, mais uniquement pour ceux que vous souhaitez personnaliser — le système de repli se charge de définir le style des autres :

// PlainStyle.qml

Style {
    control {
        // control does not map to an actual Qt Quick Control, but is a shared
        // fallback for all other controls. Use it to define styling that is
        // common to all of them. Unset properties fall back to Style.fallbackStyle.
        padding: 6
        text.color: "white"
        background {
            radius: 4
            border.color: "gray"
        }
        indicator {
            width: 20
            height: 20
            border.width: 1
            radius: 3
        }
        handle {
            width: 20
            height: 20
            radius: 10
        }
    }

    slider {
        // slider defines the styling for a Qt Quick Slider.
        // Unset properties fall back to control.
        handle.color: "white"
        indicator {
            fillWidth: true
            height: 6
            color: "steelblue"
            foreground.color: "skyblue"
        }
    }

    abstractButton {
        // abstractButton does not map to an actual Qt Quick Control, but
        // is a shared fallback for button-like controls, such as button,
        // radioButton, checkBox). Use it to define styling that is common
        // to all of them. Unset properties fall back to control.
        background.shadow {
            opacity: 0.6
            verticalOffset: 2
            horizontalOffset: 2
            color: "gray"
        }
    }

    button {
        // button defines the styling for a Qt Quick Button.
        // Unset properties fall back to abstractButton.
        background {
            width: 120
            color: "lightsteelblue"
            gradient: Gradient {
                GradientStop { position: 0.0; color: Qt.alpha("black", 0.0)}
                GradientStop { position: 1.0; color: Qt.alpha("black", 0.2)}
            }
        }
    }

    // Controls left undefined — such as radioButton, checkBox, roundButton
    // or switchControl — fall back to their immediate base type, which in
    // this style will be either abstractButton or control directly.
}

Activation d’un style

Pour activer le style, attribuez-le à ` StyleKit.style ` à la racine ` ApplicationWindow`. Tous les contrôles de l’application l’adoptent alors automatiquement :

// Main.qml

import QtQuick
import Qt.labs.StyleKit

ApplicationWindow {
    id: app
    width: 1024
    height: 800
    visible: true

    // Assign the style to be used
    StyleKit.style: PlainStyle {}

    // Controls are used as normal
    Column {
        anchors.fill: parent
        anchors.margins: 10
        spacing: 10

        Button {
            text: "Button"
        }

        Slider {
            width: 200
        }
    }
}

États des contrôles

L’apparence des contrôles varie en fonction de l’interaction de l’utilisateur : un bouton a un aspect différent lorsqu’on passe la souris dessus, lorsqu’on appuie dessus ou lorsqu’il est désactivé. StyleKit vous permet d’exprimer cela dans le style en plaçant le nom de l’ state devant les propriétés concernées, afin de leur attribuer des valeurs alternatives lorsque le contrôle se trouve dans cet état.

Les états peuvent être imbriqués, et une combinaison plus spécifique (par exemple, ` hovered.checked`) prévaut sur ses composants individuels :

button {
    text.color: "aliceblue"
    background.color: "cornflowerblue"
    pressed.background.color: "deepskyblue"
    hovered.background.color: "lightskyblue"
    focused.background.color: "lightsteelblue"
    checked.background.color: "royalblue"
    highlighted.background.color: "lightblue"
    disabled {
        background.color: "lightgray"
        background.border.color: "darkgray"
    }

    // Nested states, such as hovered.checked in this case, takes
    // precedence over both hovered and checked:
    hovered.checked.background.color: "steelblue"
}

Transitions d’états

Les changements d’état peuvent être animés en définissant la propriété « transition » dans le style d’un contrôle. Une « StyleAnimation » offre un moyen pratique d’animer des groupes de propriétés de style associées, telles que toutes les couleurs d’arrière-plan ou d’indicateur, mais vous pouvez également utiliser des animations QML standard telles que « ColorAnimation » et « NumberAnimation » :

comboBox {
    background.color: "lightgray"
    hovered.background.color: "plum"

    indicator.color: "white"
    hovered.indicator.color: "pink"
    hovered.indicator.border.width: 4

    transition: Transition {
        StyleAnimation {
            animateBackgroundColors: true
            animateIndicatorColors: true
            animateIndicatorBorder: true
            easing.type: Easing.OutQuad
            duration: 500
        }
    }
}

La gestion des thèmes

StyleKit intègre la prise en charge des thèmes clairs et sombres via les propriétés ` light ` et ` dark ` d’un ` Style`. À l’instar d’un ` Style`, un ` Theme ` vous permet de définir le style que chaque contrôle doit adopter lorsque ce thème est actif. Les propriétés qui ne sont pas définies dans un thème seront lues par défaut à partir du style :

Style {
    light: Theme {
        applicationWindow.background.color: "gainsboro"
        control.text.color: "#202020"
        control.background.color: "#f0f0f0"
        control.background.border.color: "#d0d0d0"
        button.hovered.background.color: "#4a90d9"
        radioButton.indicator.foreground.color: "#d0d0d0"
    }

    dark: Theme {
        applicationWindow.background.color: "#2b2b2b"
        control.text.color: "#e0e0e0"
        control.background.color: "#404040"
        control.background.border.color: "#606060"
        button.hovered.background.color: "#6ab0f9"
        radioButton.indicator.foreground.color: "#606060"
    }
}

Thèmes personnalisés

Au-delà des thèmes clair et foncé, vous pouvez définir autant de thèmes supplémentaires que vous le souhaitez à l’aide de CustomTheme. Chaque CustomTheme dispose d’un name et contient un objet Theme présentant la même structure que les thèmes intégrés :

Style {
    CustomTheme {
        name: "HighContrast"
        theme: Theme {
            control.background.color: "white"
            control.background.border.color: "black"
            control.background.border.width: 2
        }
    }

    CustomTheme {
        name: "Sepia"
        theme: Theme {
            control.text.color: "#5b4636"
            control.background.color: "#f4ecd8"
            control.background.border.color: "#c8b99a"
            applicationWindow.background.color: "#efe6d0"
        }
    }
}

Pour changer de thème à l’exécution, définissez ` Style.themeName ` depuis un fichier QML de votre application sur le nom du thème souhaité. La propriété `Style.themeNames` répertorie tous les noms de thèmes disponibles, ce qui facilite le remplissage d’un contrôle de sélection :

ComboBox {
    model: StyleKit.style.availableThemeNames
    onCurrentTextChanged: StyleKit.style.themeName = currentText
}

Pour activer un thème au démarrage de l’application, définissez ` themeName ` lors de l’attribution du style :

ApplicationWindow {
    width: 1024
    height: 800
    visible: true

    StyleKit.style: MyStyleKitStyle {
        themeName: "HighContrast"
    }
}

Variations de style

Un ` StyleVariation ` vous permet de définir des styles alternatifs pour certaines parties de l’application. Cela s’avère utile lorsque vous devez appliquer des styles différents aux contrôles lorsqu’ils sont des enfants, par exemple, d’un ` ToolBar ` ou d’un ` GroupBox`, ou si vous souhaitez implémenter des indications de style que l’application peut appliquer de manière facultative à certains contrôles.

Il existe deux types de variations de style : les variations de type et les variations d’instance.

Variations de type

Une variation de type contient des styles alternatifs pour les contrôles qui sont des enfants (ou des descendants) d’un autre type de contrôle. Cela signifie que si une ` StyleVariation ` contient un style pour un bouton et qu’elle est ajoutée à la propriété ` variations ` d’un cadre, ` StyleKit ` appliquera ce style à tous les ` Buttons ` qui sont des enfants de ` Frames ` dans l’application :

Style {
    frame {
        variations: StyleVariation {
            button {
                text.color: "ghostwhite"
                background.border.width: 0
                background.color: "slategrey"
            }
        }
    }

    groupBox {
        // groupBox falls back to frame. Therefore, if the varations set on a
        // frame is not wanted on a groupBox, just override it and set it back to [].
        variations: []
    }
}

Variantes d’instance

Des « StyleVariations » nommées peuvent être appliquées à des contrôles individuels de l’application à l’aide de la propriété attachée « StyleVariation.variations ». Une fois appliquée, le contrôle lui-même, ainsi que tous ses descendants, recevront le nouveau style. Cela diffère d’une variation de type, qui affecte tous les contrôles d’un certain type, tels que tous les Frames. Les variations d’instance n’affecteront que l’instance du contrôle (et ses descendants) à laquelle elles sont associées :

Style {
    StyleVariation {
        name: "mini"
        control {
            padding: 2
            background.height: 15
            indicator.width: 15
            indicator.height: 15
            handle.width: 15
            handle.height: 15
        }
    }

    StyleVariation {
        name: "alert"
        abstractButton.background.color: "red"
    }
}

Appliquez-les aux contrôles de votre application :

GroupBox {
    title: "Mini controls"
    StyleVariation.variations: ["mini"]

    Row {
        spacing: 10
        Button { text: "Save" }
        CheckBox { text: "Option" }
        // This button also has the "alert" variation, in addition to "mini"
        Button {
            text: "Delete"
            StyleVariation.variations: ["alert"]
        }
    }
}

Contrôles personnalisés

Si votre application comprend des contrôles personnalisés qui ne font pas partie de Qt Quick Controls, vous pouvez tout de même les intégrer à StyleKit. Il suffit d’ajouter une CustomControl pour chacun d’entre eux et de les styliser de la même manière que vous stylisez les built-in controls:

// MyStyle.qml

Style {
    id: style
    readonly property int myControlType: 0
    CustomControl {
        controlType: style.myControlType
        background {
            width: 120
            height: 30
            radius: 0
        }
        hovered.background.color: "lightslategray"
        pressed.background.color: "skyblue"
    }
}

Dans l’implémentation du contrôle, utilisez un « StyleReader » avec l’« controlType » correspondant pour récupérer les propriétés de style. Les valeurs correctes des propriétés sont déterminées en tenant compte de « Themes », « StyleVariations », « fallback types » et de la propagation des propriétés. Pour qu’un lecteur de style puisse effectuer cette opération, il doit connaître l’état de votre contrôle. Par conséquent, liez l’état de votre contrôle aux propriétés pertinentes de l’ StyleReader, telles que hovered et pressed. À chaque changement d’état, les propriétés de style concernées seront mises à jour, ce qui entraînera le rafraîchissement de votre contrôle :

// Main.qml

component MyControl : Rectangle {
    StyleReader {
        id: styleReader
        controlType: StyleKit.style.myControlType
        hovered: hoverHandler.hovered
        pressed: tapHandler.pressed
        palette: app.palette
    }

    HoverHandler { id: hoverHandler }
    TapHandler { id: tapHandler }

    implicitWidth: styleReader.background.width
    implicitHeight: styleReader.background.height
    color: styleReader.background.color
    radius: styleReader.background.radius

    Text {
        font: styleReader.font
        anchors.centerIn: parent
        text: "ok"
    }
}

Délégués personnalisés

Chaque élément visuel d’un contrôle — background, handle, indicator, etc. — est rendu par un delegate. Par défaut, StyleKit utilise StyledItem pour le rendu, mais vous pouvez le remplacer entièrement par votre propre composant QML.

Le composant doit définir deux propriétés obligatoires que StyleKit remplit automatiquement :

  • delegateStyle — l’ DelegateStyle qui contient les propriétés de style résolues (couleur, rayon, taille implicite, etc.)
  • control — l’ Qt Quick Control à laquelle appartient le délégué

Vous attribuez ensuite le composant à la propriété ` delegate ` de l’élément visuel que vous souhaitez modifier :

// import QtQuick.Templates as T

slider {
    handle.delegate: Rectangle {
        id: handle
        required property DelegateStyle delegateStyle
        required property T.Slider control
        implicitWidth: delegateStyle.width
        implicitHeight: delegateStyle.height
        radius: delegateStyle.radius
        color: delegateStyle.color
        Text {
            anchors.centerIn: parent
            text: handle.control.value.toFixed(0)
        }
    }
}

Superposition et sous-couche

Si vous souhaitez simplement compléter le rendu par défaut plutôt que de le remplacer complètement, utilisez StyledItem comme racine de votre délégué. Tous les éléments enfants que vous ajoutez à StyledItem sont dessinés par-dessus (superposition) le rendu par défaut :

Style {
    component Star : Shape {
        id: star
        property color color
        ShapePath {
            fillColor: star.color
            scale: Qt.size(star.width, star.height)
            PathMove { x: 0.50; y: 0.00 }
            PathLine { x: 0.59; y: 0.35 }
            PathLine { x: 0.97; y: 0.35 }
            PathLine { x: 0.66; y: 0.57 }
            PathLine { x: 0.78; y: 0.91 }
            PathLine { x: 0.50; y: 0.70 }
            PathLine { x: 0.22; y: 0.91 }
            PathLine { x: 0.34; y: 0.57 }
            PathLine { x: 0.03; y: 0.35 }
            PathLine { x: 0.41; y: 0.35 }
            PathLine { x: 0.50; y: 0.00 }
        }
    }

    button {
        background.delegate: StyledItem {
            width: parent.width
            height: parent.height
            // Draw a star on top the default rendering
            Star {
                anchors.fill: parent
                color: "gold"
            }
        }
    }
}

Pour afficher un élément sous le rendu par défaut, définissez votre délégué comme Item, placez le contenu supplémentaire en premier, puis intégrez un StyledItem en tant qu’élément enfant afin d’afficher l’apparence par défaut par-dessus :

Style {
    component Star : Shape {
        id: star
        property color color
        ShapePath {
            fillColor: star.color
            scale: Qt.size(star.width, star.height)
            PathMove { x: 0.50; y: 0.00 }
            PathLine { x: 0.59; y: 0.35 }
            PathLine { x: 0.97; y: 0.35 }
            PathLine { x: 0.66; y: 0.57 }
            PathLine { x: 0.78; y: 0.91 }
            PathLine { x: 0.50; y: 0.70 }
            PathLine { x: 0.22; y: 0.91 }
            PathLine { x: 0.34; y: 0.57 }
            PathLine { x: 0.03; y: 0.35 }
            PathLine { x: 0.41; y: 0.35 }
            PathLine { x: 0.50; y: 0.00 }
        }
    }

    slider.handle.delegate: Item {
        // Since the root item is not a StyledItem, the following
        // required properties must be defined explicitly:
        required property DelegateStyle delegateStyle
        required property QtObject control

        implicitWidth: delegateStyle.width
        implicitHeight: delegateStyle.height
        width: parent.width
        height: parent.height
        scale: delegateStyle.scale
        rotation: delegateStyle.rotation
        visible: delegateStyle.visible

        // Draw a star underneath the default handle delegate
        Star {
            width: parent.width * 2
            height: parent.height * 2
            anchors.centerIn: parent
            color: "gold"
        }

        StyledItem {
            // Forward delegateStyle into StyledItem. StyledItem doesn't
            // use 'control' for anything, so it can be omitted.
            delegateStyle: parent.delegateStyle
        }
    }
}

Données personnalisées

Les délégués personnalisés ont parfois besoin de propriétés de style supplémentaires qui vont au-delà de celles intégrées — par exemple pour styliser des éléments enfants dont StyleKit n’a pas connaissance. La propriété data rend cela possible. Elle peut contenir n’importe quel objet de type QtObject, et peut donc transporter toutes les informations dont votre délégué a besoin.

Comme toutes les autres propriétés de style, ` data ` participe à la résolution des propriétés de style : le délégué reçoit toujours l’objet qui correspond à l’état actuel du contrôle, au thème actif et aux variations de style. Contrairement aux propriétés intégrées, ` data ` est propagé dans son ensemble : les propriétés individuelles contenues dans l’objet ne sont pas propagées séparément :

component OverlayData : QtObject {
    property color overlayColor
}

toolButton {
    background.delegate: StyledItem {
        id: custom
        Text {
            color: custom.delegateStyle.data.overlayColor
            font.pixelSize: 30
            text: "シ"
        }
    }
    background.data: OverlayData {
        overlayColor: "sandybrown"
    }
    hovered.background.data: OverlayData {
        overlayColor: "magenta"
    }
}

© 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.