Personnalisation des contrôles Qt Quick
Qt Quick Les contrôles consistent en une hiérarchie (arbre) d'éléments. Afin d'obtenir un aspect et une convivialité personnalisés, l'implémentation QML par défaut de chaque élément peut être remplacée par une implémentation personnalisée.
Personnalisation d'un contrôle
Il arrive que vous souhaitiez créer une apparence "unique" pour une partie spécifique de votre interface utilisateur et utiliser un style complet partout ailleurs. Vous êtes peut-être satisfait du style que vous utilisez, mais il y a un bouton qui a une signification particulière.
La première façon de créer ce bouton est de le définir sur place, là où il est nécessaire. Par exemple, vous n'êtes peut-être pas satisfait des coins carrés du bouton du style Basique. Pour les arrondir, vous pouvez remplacer l'élément background et définir la propriété de rayon Rectangle :
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { width: 400 height: 400 visible: true Button { id: button text: "A Special Button" background: Rectangle { implicitWidth: 100 implicitHeight: 40 color: button.down ? "#d6d6d6" : "#f6f6f6" border.color: "#26282a" border.width: 1 radius: 4 } } }
Remarque : comme les différents éléments qui composent un contrôle dans un style donné sont conçus pour fonctionner ensemble, il peut être nécessaire de remplacer d'autres éléments pour obtenir l'aspect souhaité. En outre, tous les styles ne peuvent pas être personnalisés. Voir la note dans la référence de personnalisation pour plus d'informations.
La deuxième façon de créer le bouton est intéressante si vous prévoyez d'utiliser votre bouton arrondi à plusieurs endroits. Elle consiste à déplacer le code dans son propre fichier QML au sein de votre projet.
Pour cette approche, nous copierons le code de l'arrière-plan à partir du fichier Button.qml du style Basic. Ce fichier se trouve dans le chemin suivant de votre installation Qt :
$QTDIR/qml/QtQuick/Controls/Basic/Button.qml
Après avoir fait cela, nous ajouterons simplement la ligne suivante :
radius: 4Pour éviter toute confusion avec les contrôles du module lui-même, nous appellerons le fichier MyButton.qml. Pour utiliser le contrôle dans votre application, référez-vous à lui par son nom de fichier :
import QtQuick.Controls.Basic ApplicationWindow { MyButton { text: qsTr("A Special Button") } }
La troisième façon de créer le bouton est un peu plus structurée, à la fois en termes d'emplacement du fichier dans le système de fichiers et de la façon dont il est utilisé dans QML. Tout d'abord, copiez un fichier existant comme vous l'avez fait ci-dessus, mais cette fois-ci, placez-le dans un sous-dossier de votre projet nommé (par exemple) controls. Pour utiliser le contrôle, importez d'abord le dossier dans un espace de noms :
import QtQuick.Controls.Basic import "controls" as MyControls ApplicationWindow { MyControls.Button { text: qsTr("A Special Button") } }
Comme vous disposez maintenant de l'espace de noms MyControls, vous pouvez nommer les contrôles d'après leurs équivalents réels dans le module Qt Quick Controls. Vous pouvez répéter ce processus pour tout contrôle que vous souhaitez ajouter.
Un avantage supplémentaire de ces trois méthodes est qu'il n'est pas nécessaire d'implémenter le modèle à partir de zéro.
Remarque : les trois approches mentionnées ici ne fonctionnent pas pour la personnalisation de la pièce jointe ToolTip, car il s'agit d'un élément partagé créé en interne. Pour une personnalisation unique d'un ToolTip, voir Custom Tool Tips. Pour personnaliser le document joint ToolTip, il doit être fourni dans le cadre de votre propre style.
Création d'un style personnalisé
Il existe plusieurs façons de créer vos propres styles. Nous expliquons ci-dessous les différentes approches.
Définition d'un style
Dans Qt Quick Controls, un style est essentiellement un ensemble de fichiers QML dans un seul répertoire. Pour qu'un style soit utilisable, quatre conditions doivent être remplies :
- Il doit exister au moins un fichier QML dont le nom correspond à un contrôle (par exemple,
Button.qml). - Chaque fichier QML doit contenir le type correspondant de l'importation QtQuick.Templates en tant qu'élément racine. Par exemple, Button.qml doit contenir un modèle Button comme élément racine.
Si nous utilisions à la place le type correspondant de l'importation QtQuick.Controls comme nous l'avons fait dans la section précédente, cela ne fonctionnerait pas : le contrôle que nous définissons essaierait de dériver de lui-même.
- Un fichier qmldir doit exister avec le(s) fichier(s) QML. Voici un exemple de fichier
qmldirsimple pour un style qui fournit un bouton :module MyStyle Button 2.15 Button.qml
Si vous utilisez la sélection de style à la compilation, le qmldir doit également importer le style de repli :
# ... import QtQuick.Controls.Basic auto
Cela peut également être fait pour la sélection de style au moment de l'exécution au lieu d'utiliser, par exemple, QQuickStyle::setFallbackStyle().
La structure du répertoire pour un tel style ressemble à ceci :
MyStyle ├─── Button.qml └─── qmldir
- Les fichiers doivent se trouver dans un répertoire accessible via le chemin d'importation QML.
Par exemple, si le chemin d'accès au répertoire MyStyle mentionné ci-dessus est
/home/user/MyApp/MyStyle, alors/home/user/MyAppdoit être ajouté au chemin d'importation QML.Pour utiliser MyStyle dans MyApp, il faut le désigner par son nom :
./MyApp -style MyStyle
Le nom du style doit correspondre à la casse du répertoire de style ; passer mystyle ou MYSTYLE n'est pas supporté.
Par défaut, le système de style utilise le style Basic comme solution de repli pour les contrôles qui ne sont pas implémentés. Pour personnaliser ou étendre tout autre style intégré, il est possible de spécifier un style de repli différent à l'aide de QQuickStyle.
Cela signifie que vous pouvez implémenter autant de contrôles que vous le souhaitez pour votre style personnalisé et les placer presque n'importe où. Cela permet également aux utilisateurs de créer leurs propres styles pour votre application.
Prévisualisation des styles personnalisés dans Qt Quick Designer
En utilisant l'approche ci-dessus, il est possible de prévisualiser un style personnalisé dans Qt Quick Designer. Pour ce faire, assurez-vous que le projet possède un fichier qtquickcontrols2.conf et que l'entrée suivante existe :
[Controls] Style=MyStyle
Pour plus d'informations, consultez l'exemple Flat Style.
Extensions C++ spécifiques au style
Il peut arriver que vous ayez besoin d'utiliser le langage C++ pour étendre votre style personnalisé.
- Si le style qui utilise le type est le seul style utilisé par une application, enregistrez le type auprès du moteur QML en ajoutant la macro QML_ELEMENT et en intégrant le fichier à votre module QML :
qt_add_qml_module(ACoolItem URI MyItems VERSION 1.0 SOURCES acoolcppitem.cpp acoolcppitem.h )CONFIG += qmltypes QML_IMPORT_NAME = MyItems QML_IMPORT_MAJOR_VERSION = 1
Si l'en-tête dans lequel la classe est déclarée n'est pas accessible à partir du chemin d'inclusion de votre projet, vous devrez peut-être modifier le chemin d'inclusion pour que le code d'enregistrement généré puisse être compilé.
INCLUDEPATH += MyItems
Voir Définir les types QML à partir de C++ et Construire une application QML pour plus d'informations.
- Si le style qui utilise le type est l'un des nombreux styles utilisés par une application, envisagez de placer chaque style dans un module distinct. Les modules seront alors chargés à la demande.
Considérations relatives aux styles personnalisés
Lorsque vous mettez en œuvre votre propre style et que vous personnalisez les contrôles, il convient de garder à l'esprit certains points afin de garantir que votre application est aussi performante que possible.
Évitez d'attribuer un identifiant aux implémentations des délégués d'éléments des styles
Comme expliqué dans Définition d'un style, lorsque vous implémentez votre propre style pour un contrôle, vous commencez par le modèle correspondant à ce contrôle. Par exemple, le site Button.qml d'un style sera structuré de la même manière :
Lorsque vous utilisez un bouton dans votre application, les éléments background et contentItem sont créés et rattachés à l'élément racine Button:
// Creates the Button root item, the Rectangle background, // and the Text contentItem. Button { text: qsTr("Confirm") }
Supposons que vous ayez ensuite besoin de personnaliser le bouton une seule fois (comme expliqué dans la section Personnalisation d'un contrôle) :
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { width: 400 height: 400 visible: true Button { id: button text: "A Special Button" background: Rectangle { implicitWidth: 100 implicitHeight: 40 color: button.down ? "#d6d6d6" : "#f6f6f6" border.color: "#26282a" border.width: 1 radius: 4 } } }
En QML, cela entraînerait normalement la création de l'implémentation par défaut background et des éléments personnalisés background. Qt Quick Les contrôles utilisent une technique qui évite de créer les deux éléments et ne crée que l'élément personnalisé background, ce qui améliore considérablement les performances de création des contrôles.
Cette technique repose sur l'absence d'identifiant dans l'implémentation du style de cet élément. Si un identifiant est attribué, la technique ne peut pas fonctionner et les deux éléments seront créés. Par exemple, il peut être tentant d'attribuer un identifiant à background ou contentItem afin que d'autres objets du fichier puissent faire référence à ces éléments :
T.Button { // ... background: Rectangle { id: backgroundRect // ... } contentItem: Text { // Use backgroundRect in some way... } // ... }
Avec ce code, chaque fois qu'une instance de bouton avec un arrière-plan personnalisé est créée, les deux arrière-plans seront créés, ce qui se traduit par des performances de création sous-optimales.
Avant Qt 5.15, l'ancien arrière-plan inutilisé était supprimé pour libérer les ressources qui lui étaient associées. Cependant, comme le contrôle ne possède pas les éléments, il ne doit pas les supprimer. Depuis Qt 5.15, les anciens éléments ne sont plus supprimés, et l'élément backgroundRect vivra donc plus longtemps que nécessaire, généralement jusqu'à ce que l'application se termine. Bien que l'ancien élément soit caché, visuellement non apparenté au contrôle et supprimé de l'arbre d'accessibilité, il est important de garder à l'esprit le temps de création et l'utilisation de la mémoire de ces éléments inutilisés lors de l'attribution d'un identifiant dans ce contexte.
Éviter les affectations impératives d'éléments personnalisés
La technique mentionnée dans la section ci-dessus ne fonctionne que lorsqu'un élément est assigné de manière déclarative pour la première fois, et les assignations impératives se traduiront par des éléments orphelins. Utilisez toujours des liens déclaratifs pour assigner des éléments personnalisés lorsque c'est possible.
Ne pas importer QtQuick.Controls dans les implémentations QML
Lorsque vous écrivez le QML pour l'implémentation d'un contrôle dans votre style, il est important de ne pas importer QtQuick.Controls. Cela empêchera le QML d'être compilé par le compilateur QML.
Implémenter des types utilisés par d'autres types
Supposons que vous utilisiez des ScrollViews dans votre application et que vous souhaitiez personnaliser leurs barres de défilement. Il est tentant d'implémenter un ScrollBar.qml personnalisé et de faire en sorte que ScrollView reprenne automatiquement le ScrollBar personnalisé. Cependant, cela ne fonctionnera pas. Vous devez implémenter à la fois ScrollBar.qml et ScrollView.qml.
Propriétés attachées
Il est courant qu'un style ait certaines propriétés ou certains attributs qui s'appliquent à tous les contrôles. Les propriétés attachées sont un excellent moyen d'étendre un élément en QML sans avoir à modifier un C++ existant appartenant à cet élément. Par exemple, les styles Material et Universal ont tous deux une propriété attachée theme qui contrôle si un élément et ses enfants seront rendus dans un thème clair ou foncé.
À titre d'exemple, ajoutons une propriété attachée qui contrôle l'élévation. Notre style illustrera l'élévation par une ombre portée ; plus l'élévation est élevée, plus l'ombre est grande.
La première étape consiste à créer une nouvelle application Qt Quick Controls dans Qt Creator. Ensuite, nous ajoutons un type C++ qui stocke l'élévation. Étant donné que ce type sera utilisé pour chaque contrôle pris en charge par notre style, et que nous pourrions souhaiter ajouter d'autres propriétés attachées ultérieurement, nous l'appellerons MyStyle. Voici MyStyle.h:
#ifndef MYSTYLE_H #define MYSTYLE_H #include <QObject> #include <QtQml> class MyStyle : public QObject { Q_OBJECT Q_PROPERTY(int elevation READ elevation WRITE setElevation NOTIFY elevationChanged) public: explicit MyStyle(QObject *parent = nullptr); static MyStyle *qmlAttachedProperties(QObject *object); int elevation() const; void setElevation(int elevation); signals: void elevationChanged(); private: int m_elevation; }; QML_DECLARE_TYPEINFO(MyStyle, QML_HAS_ATTACHED_PROPERTIES) #endif // MYSTYLE_H
MyStyle.cpp:
#include "mystyle.h" MyStyle::MyStyle(QObject *parent) : QObject(parent), m_elevation(0) { } MyStyle *MyStyle::qmlAttachedProperties(QObject *object) { return new MyStyle(object); } int MyStyle::elevation() const { return m_elevation; } void MyStyle::setElevation(int elevation) { if (elevation == m_elevation) return; m_elevation = elevation; emit elevationChanged(); }
Le type MyStyle est spécial dans le sens où il ne doit pas être instancié, mais plutôt utilisé pour ses propriétés attachées. Pour cette raison, nous l'enregistrons de la manière suivante dans main.cpp:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include "mystyle.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterUncreatableType<MyStyle>("MyStyle", 1, 0, "MyStyle", "MyStyle is an attached property"); QQmlApplicationEngine engine; // Make the directory containing our style known to the QML engine. engine.addImportPath(":/"); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); return app.exec(); }
Nous copions ensuite Button.qml du style Basic dans $QTDIR/qml/QtQuick/Controls/Basic/ dans un nouveau dossier myproject dans notre répertoire de projet. Nous ajoutons la nouvelle copie de Button.qml à qml.qrc, qui est le fichier de ressources contenant nos fichiers QML.
Ensuite, nous ajoutons une ombre portée au délégué background du bouton :
// ...
import QtQuick.Effects
import MyStyle
// ...
background: Rectangle {
// ...
layer.enabled: control.enabled && control.MyStyle.elevation > 0
layer.effect: MultiEffect {
shadowEnabled: true
shadowHorizontalOffset: 3
shadowVerticalOffset: 3
shadowColor: control.visualFocus ? "#330066ff" : "#aaaaaa"
shadowBlur: control.pressed ? 0.8 : 0.4
}
}Notez que nous :
- Nous n'avons pas besoin d'utiliser l'ombre portée lorsque l'élévation est de 1,5 m.
0 - changeons la couleur de l'ombre selon que le bouton a ou non le focus
- La taille de l'ombre dépend de l'élévation.
Pour tester la propriété attached, nous créons un site Row avec deux boutons dans main.qml:
import QtQuick import QtQuick.Controls import MyStyle 1.0 ApplicationWindow { id: window width: 400 height: 400 visible: true Row { spacing: 20 anchors.centerIn: parent Button { text: "Button 1" } Button { text: "Button 2" MyStyle.elevation: 10 } } }
L'un des boutons n'a pas d'élévation et l'autre a une élévation de 10.
Une fois ces éléments en place, nous pouvons exécuter notre exemple. Pour indiquer à l'application d'utiliser notre nouveau style, nous passons -style MyStyle comme argument d'application, mais il existe de nombreuses façons de spécifier le style à utiliser.
Le résultat final :

Notez que la déclaration import MyStyle 1.0 n'est nécessaire que parce que nous utilisons la propriété attachée appartenant à MyStyle. Les deux boutons utiliseront notre style personnalisé, même si nous supprimons l'importation.
Référence de personnalisation
Les extraits suivants présentent des exemples où les contrôles du style Basic ont été personnalisés en utilisant la même approche que celle décrite dans la section Personnaliser un contrôle. Le code peut être utilisé comme point de départ pour mettre en œuvre une apparence personnalisée.
Note : Les styles macOS et Windows ne sont pas adaptés à la personnalisation. Il est recommandé de toujours baser un contrôle personnalisé sur un style unique disponible sur toutes les plateformes, par exemple Style de base, Style Fusion, Style Imagine, Style Matériel, Style Universel. Ce faisant, vous avez la garantie que le contrôle aura toujours la même apparence, quel que soit le style avec lequel l'application est exécutée. Pour savoir comment utiliser un style différent, voir Utilisation des styles dans les contrôles Qt Quick . Vous pouvez également créer votre propre style.
Personnaliser ApplicationWindow
ApplicationWindow se compose d'un élément visuel : background.
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { visible: true background: Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#ffffff" } GradientStop { position: 1; color: "#c1bbf9" } } } }
Personnaliser BusyIndicator
BusyIndicator se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic BusyIndicator { id: control contentItem: Item { implicitWidth: 64 implicitHeight: 64 Item { id: item x: parent.width / 2 - 32 y: parent.height / 2 - 32 width: 64 height: 64 opacity: control.running ? 1 : 0 Behavior on opacity { OpacityAnimator { duration: 250 } } RotationAnimator { target: item running: control.visible && control.running from: 0 to: 360 loops: Animation.Infinite duration: 1250 } Repeater { id: repeater model: 6 Rectangle { id: delegate x: item.width / 2 - width / 2 y: item.height / 2 - height / 2 implicitWidth: 10 implicitHeight: 10 radius: 5 color: "#21be2b" required property int index transform: [ Translate { y: -Math.min(item.width, item.height) * 0.5 + 5 }, Rotation { angle: delegate.index / repeater.count * 360 origin.x: 5 origin.y: 5 } ] } } } } }
Personnalisation du bouton
Button se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic Button { id: control text: qsTr("Button") contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1 : 0.3 border.color: control.down ? "#17a81a" : "#21be2b" border.width: 1 radius: 2 } }
Personnalisation de CheckBox
CheckBox se compose de trois éléments visuels : background, contentItem et indicator.

import QtQuick import QtQuick.Controls.Basic CheckBox { id: control text: qsTr("CheckBox") checked: true indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.leftPadding y: parent.height / 2 - height / 2 radius: 3 border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 2 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: control.indicator.width + control.spacing } }
Personnalisation de CheckDelegate
CheckDelegate se compose de trois éléments visuels : background, contentItem et indicator.

import QtQuick import QtQuick.Controls.Basic CheckDelegate { id: control text: qsTr("CheckDelegate") checked: true contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.width - width - control.rightPadding y: control.topPadding + control.availableHeight / 2 - height / 2 radius: 3 color: "transparent" border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 2 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down || control.highlighted color: control.down ? "#bdbebf" : "#eeeeee" } }
Personnalisation de ComboBox
ComboBox se compose de background, contentItem, popup, indicator et delegate.

pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls.Basic ComboBox { id: control model: ["First", "Second", "Third"] delegate: ItemDelegate { id: delegate required property var model required property int index width: control.width contentItem: Text { text: delegate.model[control.textRole] color: "#21be2b" font: control.font elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } highlighted: control.highlightedIndex === index } indicator: Canvas { id: canvas x: control.width - width - control.rightPadding y: control.topPadding + (control.availableHeight - height) / 2 width: 12 height: 8 contextType: "2d" Connections { target: control function onPressedChanged() { canvas.requestPaint(); } } onPaint: { context.reset(); context.moveTo(0, 0); context.lineTo(width, 0); context.lineTo(width / 2, height); context.closePath(); context.fillStyle = control.pressed ? "#17a81a" : "#21be2b"; context.fill(); } } contentItem: Text { leftPadding: 0 rightPadding: control.indicator.width + control.spacing text: control.displayText font: control.font color: control.pressed ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 120 implicitHeight: 40 border.color: control.pressed ? "#17a81a" : "#21be2b" border.width: control.visualFocus ? 2 : 1 radius: 2 } popup: Popup { y: control.height - 1 width: control.width height: Math.min(contentItem.implicitHeight, control.Window.height - topMargin - bottomMargin) padding: 1 contentItem: ListView { clip: true implicitHeight: contentHeight model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex ScrollIndicator.vertical: ScrollIndicator { } } background: Rectangle { border.color: "#21be2b" radius: 2 } } }
Comme expliqué dans ComboBox Model Roles, ComboBox prend en charge plusieurs types de modèles.
Étant donné que tous les modèles fournissent une propriété anonyme avec modelData, l'expression suivante récupère le bon texte dans tous les cas :
text: model[control.textRole]
Lorsque vous fournissez un textRole spécifique et un modèle avec des données structurées qui fournissent le rôle sélectionné, cette expression est une recherche de propriété régulière. Lorsque vous fournissez un modèle avec des données singulières, telles qu'une liste de chaînes, et un textRole vide, cette expression récupère le modelData.
Personnalisation de DelayButton
DelayButton se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic DelayButton { id: control checked: true text: qsTr("Delay\nButton") contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: "white" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 100 implicitHeight: 100 opacity: enabled ? 1 : 0.3 color: control.down ? "#17a81a" : "#21be2b" radius: size / 2 readonly property real size: Math.min(control.width, control.height) width: size height: size anchors.centerIn: parent Canvas { id: canvas anchors.fill: parent Connections { target: control function onProgressChanged() { canvas.requestPaint(); } } onPaint: { var ctx = getContext("2d") ctx.clearRect(0, 0, width, height) ctx.strokeStyle = "white" ctx.lineWidth = parent.size / 20 ctx.beginPath() var startAngle = Math.PI / 5 * 3 var endAngle = startAngle + control.progress * Math.PI / 5 * 9 ctx.arc(width / 2, height / 2, width / 2 - ctx.lineWidth / 2 - 2, startAngle, endAngle) ctx.stroke() } } } }
Personnalisation de Dial
Dial se compose de deux éléments visuels : background et handle.

import QtQuick import QtQuick.Controls.Basic Dial { id: control background: Rectangle { x: control.width / 2 - width / 2 y: control.height / 2 - height / 2 implicitWidth: 140 implicitHeight: 140 width: Math.max(64, Math.min(control.width, control.height)) height: width color: "transparent" radius: width / 2 border.color: control.pressed ? "#17a81a" : "#21be2b" opacity: control.enabled ? 1 : 0.3 } handle: Rectangle { id: handleItem x: control.background.x + control.background.width / 2 - width / 2 y: control.background.y + control.background.height / 2 - height / 2 width: 16 height: 16 color: control.pressed ? "#17a81a" : "#21be2b" radius: 8 antialiasing: true opacity: control.enabled ? 1 : 0.3 transform: [ Translate { y: -Math.min(control.background.width, control.background.height) * 0.4 + handleItem.height / 2 }, Rotation { angle: control.angle origin.x: handleItem.width / 2 origin.y: handleItem.height / 2 } ] } }
Personnalisation de DoubleSpinBox
DoubleSpinBox peut être personnalisé de la même manière que le bouton.
Personnalisation du tiroir
Le tiroir peut avoir un élément visuel background.
background: Rectangle {
Rectangle {
x: parent.width - 1
width: 1
height: parent.height
color: "#21be2b"
}
}Personnalisation du cadre
Frame se compose d'un élément visuel : background.

import QtQuick import QtQuick.Controls.Basic Frame { background: Rectangle { color: "transparent" border.color: "#21be2b" radius: 2 } Label { text: qsTr("Content goes here!") } }
Personnalisation de GroupBox
GroupBox se compose de deux éléments visuels : background et label.

import QtQuick import QtQuick.Controls.Basic GroupBox { id: control title: qsTr("GroupBox") background: Rectangle { y: control.topPadding - control.bottomPadding width: parent.width height: parent.height - control.topPadding + control.bottomPadding color: "transparent" border.color: "#21be2b" radius: 2 } label: Label { x: control.leftPadding width: control.availableWidth text: control.title color: "#21be2b" elide: Text.ElideRight } Label { text: qsTr("Content goes here!") } }
Personnalisation de ItemDelegate
ItemDelegate se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic ItemDelegate { id: control text: qsTr("ItemDelegate") contentItem: Text { rightPadding: control.spacing text: control.text font: control.font color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } background: Rectangle { implicitWidth: 100 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: control.down ? "#dddedf" : "#eeeeee" Rectangle { width: parent.width height: 1 color: control.down ? "#17a81a" : "#21be2b" anchors.bottom: parent.bottom } } }
Personnalisation de l'étiquette
L'étiquette peut comporter un élément visuel background.

import QtQuick import QtQuick.Controls.Basic Label { text: qsTr("Label") color: "#21be2b" }
Personnalisation du menu
- Menu se compose d'un élément visuel background.
- MenuItem Le menu se compose de quatre éléments visuels : background, contentItem, indicator, et arrow.
- MenuSeparator se compose d'un élément visuel background et contentItem.

import QtQuick import QtQuick.Controls.Basic Menu { id: menu Action { text: qsTr("Tool Bar"); checkable: true } Action { text: qsTr("Side Bar"); checkable: true; checked: true } Action { text: qsTr("Status Bar"); checkable: true; checked: true } MenuSeparator { contentItem: Rectangle { implicitWidth: 200 implicitHeight: 1 color: "#21be2b" } } Menu { title: qsTr("Advanced") // ... } topPadding: 2 bottomPadding: 2 delegate: MenuItem { id: menuItem implicitWidth: 200 implicitHeight: 40 arrow: Canvas { x: parent.width - width implicitWidth: 40 implicitHeight: 40 visible: menuItem.subMenu onPaint: { var ctx = getContext("2d") ctx.fillStyle = menuItem.highlighted ? "#ffffff" : "#21be2b" ctx.moveTo(15, 15) ctx.lineTo(width - 15, height / 2) ctx.lineTo(15, height - 15) ctx.closePath() ctx.fill() } } indicator: Item { implicitWidth: 40 implicitHeight: 40 Rectangle { width: 26 height: 26 anchors.centerIn: parent visible: menuItem.checkable border.color: "#21be2b" radius: 3 Rectangle { width: 14 height: 14 anchors.centerIn: parent visible: menuItem.checked color: "#21be2b" radius: 2 } } } contentItem: Text { leftPadding: menuItem.indicator.width rightPadding: menuItem.arrow.width text: menuItem.text font: menuItem.font opacity: enabled ? 1.0 : 0.3 color: menuItem.highlighted ? "#ffffff" : "#21be2b" horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 200 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: menuItem.highlighted ? "#21be2b" : "transparent" } } background: Rectangle { implicitWidth: 200 implicitHeight: 40 color: "#ffffff" border.color: "#21be2b" radius: 2 } }
Personnalisation de la barre de menu
MenuBar peut avoir un élément visuel background et MenuBarItem se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic MenuBar { id: menuBar Menu { title: qsTr("File") } Menu { title: qsTr("Edit") } Menu { title: qsTr("View") } Menu { title: qsTr("Help") } delegate: MenuBarItem { id: menuBarItem contentItem: Text { text: menuBarItem.text font: menuBarItem.font opacity: enabled ? 1.0 : 0.3 color: menuBarItem.highlighted ? "#ffffff" : "#21be2b" horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 40 implicitHeight: 40 opacity: enabled ? 1 : 0.3 color: menuBarItem.highlighted ? "#21be2b" : "transparent" } } background: Rectangle { implicitWidth: 40 implicitHeight: 40 color: "#ffffff" Rectangle { color: "#21be2b" width: parent.width height: 1 anchors.bottom: parent.bottom } } }
Personnalisation de PageIndicator
PageIndicator se compose d'un élément background, contentItem, et delegate.

import QtQuick import QtQuick.Controls.Basic PageIndicator { id: control count: 5 currentIndex: 2 delegate: Rectangle { implicitWidth: 8 implicitHeight: 8 radius: width / 2 color: "#21be2b" opacity: index === control.currentIndex ? 0.95 : pressed ? 0.7 : 0.45 required property int index Behavior on opacity { OpacityAnimator { duration: 100 } } } }
Personnalisation du volet
Le volet se compose d'un élément background.

import QtQuick import QtQuick.Controls.Basic Pane { background: Rectangle { color: "#eeeeee" } Label { text: qsTr("Content goes here!") } }
Personnalisation du Popup
Popup se compose de background et contentItem.

import QtQuick import QtQuick.Controls.Basic Popup { id: popup background: Rectangle { implicitWidth: 200 implicitHeight: 200 border.color: "#444" } contentItem: Column {} }
Personnalisation de la barre de progression
ProgressBar se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic ProgressBar { id: control value: 0.5 padding: 2 background: Rectangle { implicitWidth: 200 implicitHeight: 6 color: "#e6e6e6" radius: 3 } contentItem: Item { implicitWidth: 200 implicitHeight: 4 // Progress indicator for determinate state. Rectangle { width: control.visualPosition * parent.width height: parent.height radius: 2 color: "#17a81a" visible: !control.indeterminate } // Scrolling animation for indeterminate state. Item { anchors.fill: parent visible: control.indeterminate clip: true Row { spacing: 20 Repeater { model: control.width / 40 + 1 Rectangle { color: "#17a81a" width: 20 height: control.height } } XAnimator on x { from: 0 to: -40 loops: Animation.Infinite running: control.indeterminate } } } } }
Ci-dessus, l'élément contentItem est également animé pour représenter l'état de la barre de progression indeterminate.
Personnalisation de RadioButton
RadioButton se compose de trois éléments visuels : background contentItem et indicator.

import QtQuick import QtQuick.Controls.Basic RadioButton { id: control text: qsTr("RadioButton") checked: true indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.leftPadding y: parent.height / 2 - height / 2 radius: 13 border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 7 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: control.indicator.width + control.spacing } }
Personnalisation de RadioDelegate
RadioDelegate se compose de trois éléments visuels : background, contentItem et indicator.

import QtQuick import QtQuick.Controls.Basic RadioDelegate { id: control text: qsTr("RadioDelegate") checked: true contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 26 implicitHeight: 26 x: control.width - width - control.rightPadding y: parent.height / 2 - height / 2 radius: 13 color: "transparent" border.color: control.down ? "#17a81a" : "#21be2b" Rectangle { width: 14 height: 14 x: 6 y: 6 radius: 7 color: control.down ? "#17a81a" : "#21be2b" visible: control.checked } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down || control.highlighted color: control.down ? "#bdbebf" : "#eeeeee" } }
Personnalisation de RangeSlider
RangeSlider se compose de trois éléments visuels : background, first.handle et second.handle.

import QtQuick import QtQuick.Controls.Basic RangeSlider { id: control first.value: 0.25 second.value: 0.75 background: Rectangle { x: control.leftPadding y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 4 width: control.availableWidth height: implicitHeight radius: 2 color: "#bdbebf" Rectangle { x: control.first.visualPosition * parent.width width: control.second.visualPosition * parent.width - x height: parent.height color: "#21be2b" radius: 2 } } first.handle: Rectangle { x: control.leftPadding + control.first.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 color: control.first.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } second.handle: Rectangle { x: control.leftPadding + control.second.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 color: control.second.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } }
Personnalisation de RoundButton
RoundButton peut être personnalisé de la même manière que le bouton.
Personnalisation de ScrollBar
ScrollBar se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic ScrollBar { id: control size: 0.3 position: 0.2 active: true orientation: Qt.Vertical contentItem: Rectangle { implicitWidth: 6 implicitHeight: 100 radius: width / 2 color: control.pressed ? "#81e889" : "#c2f4c6" // Hide the ScrollBar when it's not needed. opacity: control.policy === ScrollBar.AlwaysOn || (control.active && control.size < 1.0) ? 0.75 : 0 // Animate the changes in opacity (default duration is 250 ms). Behavior on opacity { NumberAnimation {} } } }
Personnalisation de ScrollIndicator
ScrollIndicator se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic ScrollIndicator { id: control size: 0.3 position: 0.2 active: true orientation: Qt.Vertical contentItem: Rectangle { implicitWidth: 2 implicitHeight: 100 color: "#c2f4c6" } }
Personnalisation de ScrollView
ScrollView se compose d'un élément background et de barres de défilement horizontales et verticales.

ScrollView { id: control width: 200 height: 200 focus: true Label { text: "ABC" font.pixelSize: 224 } ScrollBar.vertical: ScrollBar { parent: control x: control.mirrored ? 0 : control.width - width y: control.topPadding height: control.availableHeight active: control.ScrollBar.horizontal.active } ScrollBar.horizontal: ScrollBar { parent: control x: control.leftPadding y: control.height - height width: control.availableWidth active: control.ScrollBar.vertical.active } background: Rectangle { border.color: control.activeFocus ? "#21be2b" : "#bdbebf" } }
Personnalisation de Slider
Slider se compose de deux éléments visuels : background, et handle.

import QtQuick import QtQuick.Controls.Basic Slider { id: control value: 0.5 background: Rectangle { x: control.leftPadding y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 200 implicitHeight: 4 width: control.availableWidth height: implicitHeight radius: 2 color: "#bdbebf" Rectangle { width: control.visualPosition * parent.width height: parent.height color: "#21be2b" radius: 2 } } handle: Rectangle { x: control.leftPadding + control.visualPosition * (control.availableWidth - width) y: control.topPadding + control.availableHeight / 2 - height / 2 implicitWidth: 26 implicitHeight: 26 radius: 13 color: control.pressed ? "#f0f0f0" : "#f6f6f6" border.color: "#bdbebf" } }
Personnalisation de SpinBox
SpinBox se compose de quatre éléments visuels : background, contentItem, up indicator, et down indicator.

import QtQuick import QtQuick.Controls.Basic SpinBox { id: control value: 50 editable: true contentItem: TextInput { z: 2 text: control.textFromValue(control.value, control.locale) font: control.font color: "#21be2b" selectionColor: "#21be2b" selectedTextColor: "#ffffff" horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter readOnly: !control.editable validator: control.validator inputMethodHints: Qt.ImhFormattedNumbersOnly } up.indicator: Rectangle { x: control.mirrored ? 0 : parent.width - width height: parent.height implicitWidth: 40 implicitHeight: 40 color: control.up.pressed ? "#e4e4e4" : "#f6f6f6" border.color: enabled ? "#21be2b" : "#bdbebf" Text { text: "+" font.pixelSize: control.font.pixelSize * 2 color: "#21be2b" anchors.fill: parent fontSizeMode: Text.Fit horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } down.indicator: Rectangle { x: control.mirrored ? parent.width - width : 0 height: parent.height implicitWidth: 40 implicitHeight: 40 color: control.down.pressed ? "#e4e4e4" : "#f6f6f6" border.color: enabled ? "#21be2b" : "#bdbebf" Text { text: "-" font.pixelSize: control.font.pixelSize * 2 color: "#21be2b" anchors.fill: parent fontSizeMode: Text.Fit horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter } } background: Rectangle { implicitWidth: 140 border.color: "#bdbebf" } }
Personnalisation de SplitView
SplitView consiste en un délégué visuel handle.

SplitView { id: splitView anchors.fill: parent handle: Rectangle { implicitWidth: 4 implicitHeight: 4 color: SplitHandle.pressed ? "#81e889" : (SplitHandle.hovered ? Qt.lighter("#c2f4c6", 1.1) : "#c2f4c6") } Rectangle { implicitWidth: 150 color: "#444" } Rectangle { implicitWidth: 50 color: "#666" } }
Personnaliser StackView
StackView peut avoir un élément visuel background et permet de personnaliser les transitions utilisées pour les opérations de poussée, de sortie et de remplacement.
import QtQuick import QtQuick.Controls.Basic StackView { id: control popEnter: Transition { XAnimator { from: (control.mirrored ? -1 : 1) * -control.width to: 0 duration: 400 easing.type: Easing.OutCubic } } popExit: Transition { XAnimator { from: 0 to: (control.mirrored ? -1 : 1) * control.width duration: 400 easing.type: Easing.OutCubic } } }
Personnaliser SwipeDelegate
SwipeDelegate se compose de six éléments visuels : background, contentItem, indicator, swipe.left, swipe.right, et swipe.behind.

import QtQuick import QtQuick.Controls.Basic SwipeDelegate { id: control text: qsTr("SwipeDelegate") Component { id: component Rectangle { color: SwipeDelegate.pressed ? "#333" : "#444" width: parent.width height: parent.height clip: true Label { text: qsTr("Press me!") color: "#21be2b" anchors.centerIn: parent } } } swipe.left: component swipe.right: component contentItem: Text { text: control.text font: control.font color: control.enabled ? (control.down ? "#17a81a" : "#21be2b") : "#bdbebf" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter Behavior on x { enabled: !control.down NumberAnimation { easing.type: Easing.InOutCubic duration: 400 } } } }
Personnalisation de SwipeView
SwipeView peut avoir un élément visuel background. La navigation est mise en œuvre par le site contentItem.
import QtQuick import QtQuick.Controls.Basic SwipeView { id: control background: Rectangle { color: "#eeeeee" } }
Personnalisation de Switch
Switch se compose de trois éléments visuels : background contentItem et indicator.

import QtQuick import QtQuick.Controls.Basic Switch { id: control text: qsTr("Switch") indicator: Rectangle { implicitWidth: 48 implicitHeight: 26 x: control.leftPadding y: parent.height / 2 - height / 2 radius: 13 color: control.checked ? "#17a81a" : "#ffffff" border.color: control.checked ? "#17a81a" : "#cccccc" Rectangle { x: control.checked ? parent.width - width : 0 width: 26 height: 26 radius: 13 color: control.down ? "#cccccc" : "#ffffff" border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" } } contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" verticalAlignment: Text.AlignVCenter leftPadding: control.indicator.width + control.spacing } }
Personnalisation de SwitchDelegate
SwitchDelegate se compose de trois éléments visuels : background, contentItem et indicator.

import QtQuick import QtQuick.Controls.Basic SwitchDelegate { id: control text: qsTr("SwitchDelegate") checked: true contentItem: Text { rightPadding: control.indicator.width + control.spacing text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } indicator: Rectangle { implicitWidth: 48 implicitHeight: 26 x: control.width - width - control.rightPadding y: parent.height / 2 - height / 2 radius: 13 color: control.checked ? "#17a81a" : "transparent" border.color: control.checked ? "#17a81a" : "#cccccc" Rectangle { x: control.checked ? parent.width - width : 0 width: 26 height: 26 radius: 13 color: control.down ? "#cccccc" : "#ffffff" border.color: control.checked ? (control.down ? "#17a81a" : "#21be2b") : "#999999" } } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: control.down || control.highlighted color: control.down ? "#bdbebf" : "#eeeeee" } }
Personnalisation de TabBar
TabBar se compose de deux éléments visuels : background, et contentItem.

import QtQuick import QtQuick.Controls.Basic TabBar { id: control background: Rectangle { color: "#eeeeee" } TabButton { text: qsTr("Home") } TabButton { text: qsTr("Discover") } TabButton { text: qsTr("Activity") } }
Personnalisation de TabButton
TabButton peut être personnalisé de la même manière que le bouton.
Personnalisation de TextArea
TextArea consiste en un élément background.

import QtQuick import QtQuick.Controls.Basic TextArea { id: control placeholderText: qsTr("Enter description") background: Rectangle { implicitWidth: 200 implicitHeight: 40 border.color: control.enabled ? "#21be2b" : "transparent" } }
Personnalisation de TextField
TextField consiste en un élément background.

import QtQuick import QtQuick.Controls.Basic TextField { id: control placeholderText: qsTr("Enter description") background: Rectangle { implicitWidth: 200 implicitHeight: 40 color: control.enabled ? "transparent" : "#353637" border.color: control.enabled ? "#21be2b" : "transparent" } }
Personnalisation de la barre d'outils
ToolBar se compose d'un élément visuel : background.

ToolBar { id: control background: Rectangle { implicitHeight: 40 color: "#eeeeee" Rectangle { width: parent.width height: 1 anchors.bottom: parent.bottom color: "transparent" border.color: "#21be2b" } } RowLayout { anchors.fill: parent ToolButton { text: qsTr("Undo") } ToolButton { text: qsTr("Redo") } } }
Personnalisation de ToolButton
ToolButton se compose de deux éléments visuels : background et contentItem.

import QtQuick import QtQuick.Controls.Basic ToolButton { id: control text: qsTr("ToolButton") width: 120 contentItem: Text { text: control.text font: control.font opacity: enabled ? 1.0 : 0.3 color: control.down ? "#17a81a" : "#21be2b" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter elide: Text.ElideRight } background: Rectangle { implicitWidth: 40 implicitHeight: 40 color: Qt.darker("#33333333", control.enabled && (control.checked || control.highlighted) ? 1.5 : 1.0) opacity: enabled ? 1 : 0.3 visible: control.down || (control.enabled && (control.checked || control.highlighted)) } }
Personnalisation de ToolSeparator
ToolSeparator se compose de deux éléments visuels : background et contentItem.

ToolBar { RowLayout { anchors.fill: parent ToolButton { text: qsTr("Action 1") } ToolButton { text: qsTr("Action 2") } ToolSeparator { padding: vertical ? 10 : 2 topPadding: vertical ? 2 : 10 bottomPadding: vertical ? 2 : 10 contentItem: Rectangle { implicitWidth: parent.vertical ? 1 : 24 implicitHeight: parent.vertical ? 24 : 1 color: "#c3c3c3" } } ToolButton { text: qsTr("Action 3") } ToolButton { text: qsTr("Action 4") } Item { Layout.fillWidth: true } } }
Personnalisation de ToolTip
ToolTip se compose de deux éléments visuels : background et contentItem.
import QtQuick import QtQuick.Controls.Basic ToolTip { id: control text: qsTr("A descriptive tool tip of what the button does") contentItem: Text { text: control.text font: control.font color: "#21be2b" } background: Rectangle { border.color: "#21be2b" } }
Remarque : pour personnaliser le site attached ToolTip, il doit être fourni dans le cadre de votre propre style. Pour une personnalisation unique d'un élément ToolTip, voir Custom Tool Tips.
Personnalisation du Tumbler
Le Tumbler se compose de trois éléments visuels : background, contentItem, et delegate.

import QtQuick import QtQuick.Controls.Basic Tumbler { id: control model: 15 background: Item { Rectangle { opacity: control.enabled ? 0.2 : 0.1 border.color: "#000000" width: parent.width height: 1 anchors.top: parent.top } Rectangle { opacity: control.enabled ? 0.2 : 0.1 border.color: "#000000" width: parent.width height: 1 anchors.bottom: parent.bottom } } delegate: Text { text: qsTr("Item %1").arg(modelData + 1) font: control.font horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter opacity: 1.0 - Math.abs(Tumbler.displacement) / (control.visibleItemCount / 2) required property var modelData required property int index } Rectangle { anchors.horizontalCenter: control.horizontalCenter y: control.height * 0.4 width: 40 height: 1 color: "#21be2b" } Rectangle { anchors.horizontalCenter: control.horizontalCenter y: control.height * 0.6 width: 40 height: 1 color: "#21be2b" } }
Si vous souhaitez définir votre propre contentItem, utilisez ListView ou PathView comme élément racine. Pour un Tumbler enveloppant, utilisez PathView:
Tumbler { id: tumbler contentItem: PathView { id: pathView model: tumbler.model delegate: tumbler.delegate clip: true pathItemCount: tumbler.visibleItemCount + 1 preferredHighlightBegin: 0.5 preferredHighlightEnd: 0.5 dragMargin: width / 2 path: Path { startX: pathView.width / 2 startY: -pathView.delegateHeight / 2 PathLine { x: pathView.width / 2 y: pathView.pathItemCount * pathView.delegateHeight - pathView.delegateHeight / 2 } } property real delegateHeight: tumbler.availableHeight / tumbler.visibleItemCount } }
Pour un Tumbler non enveloppant, utilisez ListView:
Tumbler { id: tumbler contentItem: ListView { model: tumbler.model delegate: tumbler.delegate snapMode: ListView.SnapToItem highlightRangeMode: ListView.StrictlyEnforceRange preferredHighlightBegin: height / 2 - (height / tumbler.visibleItemCount / 2) preferredHighlightEnd: height / 2 + (height / tumbler.visibleItemCount / 2) clip: true } }
Personnalisation de TableViewDelegate
TableViewDelegate hérite de ItemDelegate, ce qui signifie qu'il est composé de deux éléments visuels : background et contentItem.
Vous pouvez toujours attribuer votre propre délégué d'édition personnalisé à editDelegate si vous avez des besoins autres que ceux offerts par le délégué d'édition par défaut.

delegate: TableViewDelegate { id: tableCell checked: column === 0 ? checkBox.checked : tableView.itemAtIndex(tableView.index(row, 0)).checked selected: checked background: Item { Rectangle { anchors.fill: parent anchors.margins: tableCell.current ? 3 : 1 color: tableCell.selected ? "blue" : "white" } Rectangle { anchors.fill: parent color: "transparent" border.color: "darkblue" border.width: tableCell.current ? 2 : 0 } } contentItem: Item { implicitHeight: 40 visible: !tableCell.editing RowLayout { anchors.fill: parent CheckBox { id: checkBox implicitWidth: height Layout.fillHeight: true checked: false visible: tableCell.column === 0 } Text { Layout.leftMargin: 4 Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: Text.AlignVCenter color: tableCell.selected ? "white" : "black" text: tableCell.model.display } } } TableView.editDelegate: FocusScope { width: parent.width height: parent.height TableView.onCommit: { let qaim = tableCell.tableView.model if (!qaim) return const index = qaim.index(tableCell.row, tableCell.column) // instead of the edit role, any custom role supported by the model can be checked // e.g. if (!tableCell.checked || !tableCell.model.customRole) if (!tableCell.checked || !tableCell.model.edit) return // instead of the edit role, any custom role supported by the model can be set // e.g. tableCell.model.customRole = textField.text tableCell.model.edit = textField.text tableCell.model.display = textField.text } Component.onCompleted: textField.selectAll() TextField { id: textField anchors.fill: parent text: tableCell.model.edit ?? tableCell.model.display ?? "" focus: true } } }
Personnalisation de HeaderViewDelegate
HeaderViewDelegate hérite de TableViewDelegate, ce qui signifie qu'il est composé de deux éléments : background et contentItem. Vous pouvez toujours les personnaliser avec des éléments arbitraires.

Voici un exemple de personnalisation du délégué de la vue d'en-tête horizontale :
delegate: HorizontalHeaderViewDelegate { id: horizontalDelegate required property int index required property string modelData background: Rectangle { height: horizontalDelegate.height color: columnCheckBox.checked ? palette.highlight : palette.base radius: 8 } contentItem: Item { implicitWidth: columnCheckBox.implicitWidth * 2 implicitHeight: 40 CheckBox { id: columnCheckBox anchors.centerIn: parent text: horizontalDelegate.modelData Component.onCompleted: checked = horizontalDelegate.index === 1 } } }
Voici un exemple de personnalisation du délégué de la vue de l'en-tête vertical :
delegate: VerticalHeaderViewDelegate { id: verticalDelegate required property int index background: Rectangle { height: verticalDelegate.height color: palette.base border.width: rowCheckBox.checked ? 2 : 0 border.color: palette.highlight radius: 8 } contentItem: Item { implicitWidth: rowCheckBox.implicitWidth * 2 implicitHeight: 40 CheckBox { id: rowCheckBox anchors.centerIn: parent text: verticalDelegate.index + 1 Component.onCompleted: checked = verticalDelegate.index % 3 === 0 } } }
Styliser les contrôles à l'aide de StyleKit
Le module StyleKit de Qt Labs fournit un ensemble de types QML pour styliser les contrôles Qt Quick, construits sur les modèles Qt Quick. Il vous permet de définir un style visuel complet pour tous vos contrôles à partir d'un seul objet Style, y compris la prise en charge des thèmes, du style basé sur l'état et des transitions. StyleKit gère automatiquement l'implémentation du modèle sous-jacent, vous permettant de vous concentrer uniquement sur les aspects visuels tels que les couleurs, les dimensions, les bordures et les ombres.
Le module StyleKit de Qt Labs est un module d'aperçu technologique dans Qt 6.11.
© 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.