Anpassen Qt Quick Controls
Qt Quick Controls bestehen aus einer Hierarchie (Baumstruktur) von Elementen. Um ein individuelles Erscheinungsbild zu erzielen, kann die Standard-QML-Implementierung jedes Elements durch eine benutzerdefinierte ersetzt werden.
Anpassung eines Steuerelements
Manchmal möchten Sie für einen bestimmten Teil Ihrer Benutzeroberfläche ein „einzigartiges“ Erscheinungsbild erstellen und an allen anderen Stellen einen einheitlichen Stil verwenden. Vielleicht sind Sie mit dem verwendeten Stil zufrieden, aber es gibt eine bestimmte Schaltfläche, die eine besondere Bedeutung hat.
Die erste Möglichkeit, diese Schaltfläche zu erstellen, besteht darin, sie einfach an der Stelle zu definieren, an der sie benötigt wird. Beispielsweise sind Sie vielleicht nicht damit zufrieden, dass die Schaltfläche des „Basic“-Stils eckige Ecken hat. Um sie abzurunden, können Sie das Element „ background “ überschreiben und die Eigenschaft „radius“ von „Rectangle“ festlegen:
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
}
}
}Hinweis: Da die verschiedenen Elemente, aus denen sich ein Steuerelement in einem bestimmten Stil zusammensetzt, so konzipiert sind, dass sie zusammenwirken, kann es erforderlich sein, weitere Elemente zu überschreiben, um das gewünschte Erscheinungsbild zu erzielen. Außerdem lassen sich nicht alle Stile anpassen. Weitere Informationen finden Sie im Hinweis in der Referenz zur Anpassung.
Die zweite Methode zum Erstellen der Schaltfläche eignet sich gut, wenn Sie Ihre abgerundete Schaltfläche an mehreren Stellen verwenden möchten. Dabei wird der Code in eine eigene QML-Datei innerhalb Ihres Projekts verschoben.
Für diesen Ansatz kopieren wir den Hintergrundcode aus der Datei „ Button.qml “ des Stils „Basic“. Diese Datei befindet sich in Ihrer Qt-Installation unter folgendem Pfad:
$QTDIR/qml/QtQuick/Controls/Basic/Button.qml
Anschließend fügen wir einfach die folgende Zeile hinzu:
radius: 4Um Verwechslungen mit den Steuerelementen im Modul selbst zu vermeiden, nennen wir die Datei „ MyButton.qml “. Um das Steuerelement in Ihrer Anwendung zu verwenden, verweisen Sie mit dem Dateinamen darauf:
import QtQuick.Controls.Basic
ApplicationWindow {
MyButton {
text: qsTr("A Special Button")
}
}Die dritte Möglichkeit, die Schaltfläche zu erstellen, ist etwas strukturierter, sowohl hinsichtlich des Speicherorts der Datei im Dateisystem als auch hinsichtlich ihrer Verwendung in QML. Kopieren Sie zunächst wie oben beschrieben eine vorhandene Datei, legen Sie sie diesmal jedoch in einem Unterordner Ihres Projekts ab, der beispielsweise den Namen „ controls “ trägt. Um das Steuerelement zu verwenden, importieren Sie zunächst den Ordner in einen Namensraum:
import QtQuick.Controls.Basic
import "controls" as MyControls
ApplicationWindow {
MyControls.Button {
text: qsTr("A Special Button")
}
}Da Sie nun über den Namensraum „ MyControls “ verfügen, können Sie die Steuerelemente nach ihren tatsächlichen Entsprechungen im Modul „ Qt Quick Controls “ benennen. Sie können diesen Vorgang für jedes Steuerelement wiederholen, das Sie hinzufügen möchten.
Ein weiterer Vorteil dieser drei Methoden besteht darin, dass die Vorlage nicht von Grund auf neu implementiert werden muss.
Hinweis: Die drei hier genannten Ansätze funktionieren nicht für die Anpassung des angehängten „ ToolTip “, da es sich dabei um ein intern erstelltes gemeinsames Element handelt. Informationen zur einmaligen Anpassung eines „ ToolTip “ finden Sie unter Custom Tool Tips. Um das angehängte „ ToolTip “ anzupassen, muss es als Teil Ihres eigenen Stils bereitgestellt werden.
Erstellen eines benutzerdefinierten Stils
Es gibt verschiedene Möglichkeiten, eigene Stile zu erstellen. Im Folgenden erläutern wir die verschiedenen Ansätze.
Definition eines Stils
In „ Qt Quick Controls “ ist ein Stil im Wesentlichen eine Sammlung von QML-Dateien in einem einzigen Verzeichnis. Damit ein Stil verwendet werden kann, müssen vier Voraussetzungen erfüllt sein:
- Es muss mindestens eine QML-Datei vorhanden sein, deren Name mit einem Steuerelement übereinstimmt (zum Beispiel „
Button.qml“). - Jede QML-Datei muss den entsprechenden Typ aus dem Import „QtQuick.Templates“ als Stammelement enthalten. Beispielsweise muss „Button.qml“ eine „Button“-Vorlage als Stammelement enthalten.
Würden wir stattdessen, wie im vorherigen Abschnitt, den entsprechenden Typ aus dem Import „QtQuick.Controls“ verwenden, würde dies nicht funktionieren: Das von uns definierte Steuerelement würde versuchen, von sich selbst abzuleiten.
- Neben der/den QML-Datei(en) muss eine „qmldir“-Datei vorhanden sein. Nachfolgend finden Sie ein Beispiel für eine einfache „
qmldir“-Datei für einen Stil, der eine Schaltfläche bereitstellt:module MyStyle Button 2.15 Button.qmlWenn Sie die Stilauswahl zur Kompilierungszeit verwenden, sollte die `qmldir`-Datei auch den Fallback-Stil importieren:
# ... import QtQuick.Controls.Basic autoDies ist auch bei der Laufzeit-Stilauswahl möglich, anstatt beispielsweise QQuickStyle::setFallbackStyle() zu verwenden.
Die Verzeichnisstruktur für einen solchen Stil sieht wie folgt aus:
MyStyle ├─── Button.qml └─── qmldir - Die Dateien müssen sich in einem Verzeichnis befinden, das über den QML-Importpfad auffindbar ist.
Wenn der Pfad zum oben genannten Verzeichnis „MyStyle“ beispielsweise
/home/user/MyApp/MyStylelautet, muss/home/user/MyAppzum QML-Importpfad hinzugefügt werden.Um „MyStyle“ in „MyApp“ zu verwenden, verweisen Sie mit dem Namen darauf:
./MyApp -style MyStyle
Der Stilname muss der Groß-/Kleinschreibung des Stilverzeichnisses entsprechen; die Übergabe von „mystyle“ oder „MYSTYLE“ wird nicht unterstützt.
Standardmäßig verwendet das Styling-System den „Basic“-Stil als Fallback für Steuerelemente, die nicht implementiert sind. Um einen anderen integrierten Stil anzupassen oder zu erweitern, kann mithilfe von ` QQuickStyle` ein anderer Fallback-Stil angegeben werden.
Das bedeutet, dass Sie für Ihren benutzerdefinierten Stil beliebig viele Steuerelemente implementieren und diese fast überall platzieren können. Außerdem können Benutzer auf diese Weise eigene Stile für Ihre Anwendung erstellen.
Vorschau benutzerdefinierter Stile im „ Qt Quick Designer“
Mit dem oben beschriebenen Ansatz ist es möglich, eine Vorschau eines benutzerdefinierten Stils im „ Qt Quick -Designer“ anzuzeigen. Stellen Sie dazu sicher, dass das Projekt eine Datei „qtquickcontrols2.conf“ enthält und dass der folgende Eintrag vorhanden ist:
[Controls]
Style=MyStyleWeitere Informationen finden Sie im Beispiel „Flat Style“.
Stilspezifische C++-Erweiterungen
Manchmal kann es erforderlich sein, C++ zu verwenden, um Ihren benutzerdefinierten Stil zu erweitern.
- Wenn der Stil, der den Typ verwendet, der einzige Stil ist, der von einer Anwendung genutzt wird, registrieren Sie den Typ bei der QML-Engine, indem Sie das Makro „ QML_ELEMENT “ hinzufügen und die Datei in Ihr QML-Modul integrieren:
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 = 1Falls die Header-Datei, in der die Klasse deklariert ist, über den Include-Pfad Ihres Projekts nicht zugänglich ist, müssen Sie den Include-Pfad möglicherweise anpassen, damit der generierte Registrierungscode kompiliert werden kann.
INCLUDEPATH += MyItemsWeitere Informationen finden Sie unter „Definieren von QML-Typen aus C++ “ und „Erstellen einer QML-Anwendung “.
- Wenn der Stil, der den Typ verwendet, einer von vielen Stilen ist, die von einer Anwendung genutzt werden, sollten Sie in Erwägung ziehen, jeden Stil in ein separates Modul zu packen. Die Module werden dann bei Bedarf geladen.
Überlegungen zu benutzerdefinierten Stilen
Bei der Implementierung eines eigenen Stils und der Anpassung von Steuerelementen sollten Sie einige Punkte beachten, um sicherzustellen, dass Ihre Anwendung so leistungsfähig wie möglich ist.
Vermeiden Sie es, den Implementierungen von Element-Delegaten in Stilen eine ID zuzuweisen
Wie unter „Definition eines Stils“ erläutert, gehen Sie bei der Implementierung eines eigenen Stils für ein Steuerelement von der entsprechenden Vorlage für dieses Steuerelement aus. Beispielsweise ist die Datei „ Button.qml “ eines Stils in etwa wie folgt aufgebaut:
Wenn Sie in Ihrer Anwendung eine Schaltfläche (Button) verwenden, werden die Elemente „ background “ und „ contentItem “ erstellt und dem Stammelement „ Button “ untergeordnet:
// Creates the Button root item, the Rectangle background,
// and the Text contentItem.
Button {
text: qsTr("Confirm")
}Angenommen, Sie müssten dann eine einmalige Anpassung der Schaltfläche vornehmen (wie unter „Anpassen eines Steuerelements“ erläutert):
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
}
}
}In QML würde dies normalerweise dazu führen, dass sowohl die Standardimplementierung „ background “ als auch das einmalige, benutzerdefinierte Element „ background “ erstellt werden. „ Qt Quick Controls “ nutzt eine Technik, die die Erstellung beider Elemente vermeidet und stattdessen nur das benutzerdefinierte Element „ background “ erstellt, wodurch die Erstellungsleistung von Steuerelementen erheblich verbessert wird.
Diese Technik setzt voraus, dass in der Stilimplementierung dieses Elements keine ID vorhanden ist. Wird eine ID zugewiesen, funktioniert die Technik nicht, und beide Elemente werden erstellt. So kann es beispielsweise verlockend sein, dem „ background “ oder dem „ contentItem “ eine ID zuzuweisen, damit andere Objekte innerhalb der Datei auf diese Elemente verweisen können:
T.Button {
// ...
background: Rectangle {
id: backgroundRect
// ...
}
contentItem: Text {
// Use backgroundRect in some way...
}
// ...
}Mit diesem Code werden jedes Mal, wenn eine „Button“-Instanz mit einem angepassten Hintergrund erstellt wird, beide Hintergründe erstellt, was zu einer suboptimalen Erstellungleistung führt.
Vor Qt 5.15 wurde der alte, nicht mehr verwendete Hintergrund gelöscht, um die damit verbundenen Ressourcen freizugeben. Da das Steuerelement jedoch nicht Eigentümer der Elemente ist, sollte es diese nicht löschen. Ab Qt 5.15 werden alte Elemente nicht mehr gelöscht, sodass das Element „ backgroundRect “ länger bestehen bleibt, als nötig – in der Regel bis zum Beenden der Anwendung. Obwohl das alte Element ausgeblendet, visuell vom Steuerelement getrennt und aus dem Barrierefreiheitsbaum entfernt wird, ist es wichtig, die Erstellungszeit und den Speicherverbrauch dieser ungenutzten Elemente zu berücksichtigen, wenn in diesem Kontext eine ID zugewiesen wird.
Vermeiden Sie imperative Zuweisungen benutzerdefinierter Elemente
Die im obigen Abschnitt erwähnte Technik funktioniert nur, wenn ein Element zum ersten Mal deklarativ zugewiesen wird; imperativische Zuweisungen führen daher zu verwaisten Elementen. Verwenden Sie nach Möglichkeit immer deklarative Bindungen, um benutzerdefinierte Elemente zuzuweisen.
Importieren Sie „QtQuick.Controls“ nicht in QML-Implementierungen
Beim Schreiben des QML-Codes für die Implementierung eines Steuerelements in Ihrem Stil ist es wichtig, „ QtQuick.Controls “ nicht zu importieren. Andernfalls kann der QML-Compiler den QML-Code nicht kompilieren.
Implementieren Sie Typen, die von anderen Typen verwendet werden
Angenommen, Sie verwenden in Ihrer Anwendung `ScrollViews` und möchten deren Bildlaufleisten anpassen. Es ist verlockend, einfach eine benutzerdefinierte ` ScrollBar.qml` zu implementieren und darauf zu vertrauen, dass ` ScrollView ` die angepasste ` ScrollBar ` automatisch übernimmt. Dies funktioniert jedoch nicht. Sie müssen sowohl ` ScrollBar.qml ` als auch ` ScrollView.qml` implementieren.
Angehängte Eigenschaften
Es ist üblich, dass ein Stil bestimmte Eigenschaften oder Attribute aufweist, die für alle Steuerelemente gelten. Angehängte Eigenschaften sind eine hervorragende Möglichkeit, ein Element in QML zu erweitern, ohne den zugehörigen bestehenden C++-Code ändern zu müssen. Beispielsweise verfügen sowohl der Material- als auch der Universal-Stil über eine angehängte „theme“-Eigenschaft, die steuert, ob ein Element und seine untergeordneten Elemente in einem hellen oder dunklen Design dargestellt werden.
Fügen wir als Beispiel eine angehängte Eigenschaft hinzu, die die Höhe steuert. Unser Stil wird die Höhe durch einen Schlagschatten veranschaulichen; je höher die Höhe, desto größer der Schatten.
Der erste Schritt besteht darin, eine neue „ Qt Quick Controls “-Anwendung unter Qt Creator oder unter Qt Extension for Visual Studio Code zu erstellen. Anschließend fügen wir einen C++-Typ hinzu (unter Qt Creator oder unter Qt Extension for Visual Studio Code), der die „Elevation“ speichert. Da der Typ für jedes von unserem Stil unterstützte Steuerelement verwendet wird und wir später möglicherweise weitere angehängte Eigenschaften hinzufügen möchten, nennen wir ihn „MyStyle“. Hier ist „ 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_HMyStyle.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();
}Der Typ „ MyStyle “ ist insofern besonders, als er nicht instanziiert werden sollte, sondern vielmehr für seine zugehörigen Eigenschaften verwendet wird. Aus diesem Grund registrieren wir ihn auf folgende Weise in „ 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();
}Anschließend kopieren wir „ Button.qml “ aus dem Stil „Basic“ in „ $QTDIR/qml/QtQuick/Controls/Basic/ “ in einen neuen Ordner „ myproject “ in unserem Projektverzeichnis. Fügen Sie die neu kopierte Datei „ Button.qml “ zu „ qml.qrc “ hinzu, der Ressourcendatei, die unsere QML-Dateien enthält.
Als Nächstes fügen wir dem Delegaten „ background “ des Buttons einen Schlagschatten hinzu:
// ...
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
}
}Beachten Sie, dass wir:
- Den Schlagschatten nicht verwenden, wenn die Erhebung
0 - die Farbe des Schattens je nachdem ändern, ob die Schaltfläche den Fokus hat oder nicht
- die Größe des Schattens von der Erhebung abhängig machen
Um die angehängte Eigenschaft auszuprobieren, erstellen wir in „ main.qml “ ein „ Row “ mit zwei Schaltflächen:
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
}
}
}Eine Schaltfläche hat keine Erhebung, die andere hat eine Erhebung von „ 10 “.
Nachdem dies eingerichtet ist, können wir unser Beispiel ausführen. Um der Anwendung mitzuteilen, dass sie unseren neuen Stil verwenden soll, übergeben wir „ -style MyStyle “ als Anwendungsargument; es gibt jedoch viele Möglichkeiten, den zu verwendenden Stil anzugeben.
Das Endergebnis:

Beachten Sie, dass die Anweisung „ import MyStyle 1.0 “ nur deshalb erforderlich ist, weil wir die angehängte Eigenschaft von „ MyStyle “ verwenden. Beide Schaltflächen verwenden unseren benutzerdefinierten Stil, selbst wenn wir den Import entfernen würden.
Referenz zur Anpassung
Die folgenden Codeausschnitte zeigen Beispiele, bei denen die Steuerelemente des „Basic“-Stils nach dem gleichen Ansatz wie im Abschnitt „Anpassen eines Steuerelements“ angepasst wurden. Der Code kann als Ausgangspunkt für die Implementierung eines benutzerdefinierten Erscheinungsbilds dienen.
Hinweis: Die Stile „macOS“ und „Windows“ eignen sich nicht für die Anpassung. Es wird stattdessen empfohlen, ein angepasstes Steuerelement stets auf einem einzigen Stil aufzubauen, der auf allen Plattformen verfügbar ist, z. B. „Basic Style“, „Fusion Style“, „Imagine Style“, „Material Style“ oder „Universal Style“. Auf diese Weise ist gewährleistet, dass das Steuerelement immer gleich aussieht, unabhängig davon, mit welchem Stil die Anwendung ausgeführt wird. Informationen zur Verwendung eines anderen Stils finden Sie unter „Verwenden von Stilen“ unter Qt Quick Controls. Alternativ können Sie auch einen eigenen Stil erstellen.
Hinweis: Beim Ändern der Größe von Steuerelementen bleibt die tatsächliche Inhaltsgröße in der Regel unverändert. Beispielsweise können einige Stile dafür sorgen, dass ihre Schaltfläche die Grenzen des Steuerelements ausfüllt, das Kontrollkästchen und der Text eines „ CheckBox “ jedoch horizontal und/oder vertikal zentriert werden. Wenn das standardmäßige Verhalten bei der Größenanpassung nicht gewünscht ist, überschreiben Sie die entsprechenden Delegaten.
Anpassen von ApplicationWindow
ApplicationWindow besteht aus einem visuellen Element: background.
import QtQuick
import QtQuick.Controls.Basic
ApplicationWindow {
visible: true
background: Rectangle {
gradient: Gradient {
GradientStop { position: 0; color: "#ffffff" }
GradientStop { position: 1; color: "#c1bbf9" }
}
}
}Anpassung von „BusyIndicator“
BusyIndicator besteht aus zwei visuellen Elementen: background und 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
}
]
}
}
}
}
}Anpassen der Schaltfläche
Die Schaltfläche besteht aus zwei visuellen Elementen: background und 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
}
}Anpassen des Kontrollkästchens
CheckBox besteht aus drei visuellen Elementen: background, contentItem und 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 {
Breite: 14
Höhe: 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
Farbe: control.down? "#17a81a": "#21be2b"
vertikale Ausrichtung: Text.AlignVCenter
Abstand links: control.indicator.width + control.spacing
}
}Anpassen von CheckDelegate
CheckDelegate besteht aus drei visuellen Elementen: background, contentItem und 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"
}
}Anpassung von „ComboBox“
ComboBox besteht aus background, contentItem, popup, indicator und 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
}
}
}Wie unter ComboBox Model Roles erläutert, unterstützt ComboBox mehrere Modelltypen.
Da alle Modelle eine anonyme Eigenschaft mit dem Namen „ modelData “ bereitstellen, liefert der folgende Ausdruck in allen Fällen den richtigen Text:
text: model[control.textRole]Wenn Sie ein bestimmtes ` textRole ` und ein Modell mit strukturierten Daten angeben, das die ausgewählte Rolle bereitstellt, handelt es sich bei diesem Ausdruck um eine reguläre Eigenschaftssuche. Wenn Sie ein Modell mit singulären Daten, wie beispielsweise einer Liste von Zeichenfolgen, und ein leeres ` textRole` angeben, ruft dieser Ausdruck die Eigenschaft ` modelData` ab.
Anpassen von „DelayButton“
DelayButton besteht aus zwei visuellen Elementen: „ background “ und „ 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()
}
}
}
}Anpassen von „Dial“
„Dial“ besteht aus zwei visuellen Elementen: background und 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
}
]
}
}Anpassung der DoubleSpinBox
DoubleSpinBox kann auf dieselbe Weise wie ein Button angepasst werden.
Anpassen von „Drawer“
„Drawer“ kann ein Element namens „Visual background “ enthalten.
background: Rectangle {
Rectangle {
x: parent.width - 1
width: 1
height: parent.height
color: "#21be2b"
}
}Anpassung des Rahmens
Der Rahmen besteht aus einem visuellen Element: „ background “.

import QtQuick
import QtQuick.Controls.Basic
Frame {
background: Rectangle {
color: "transparent"
border.color: "#21be2b"
radius: 2
}
Label {
text: qsTr("Content goes here!")
}
}Anpassen von GroupBox
GroupBox besteht aus zwei visuellen Elementen: „ background “ und „ 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!")
}
}Anpassung von „ItemDelegate“
ItemDelegate besteht aus zwei visuellen Elementen: „ background “ und „ 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
}
}
}Anpassen von „Label“
Ein Label kann ein visuelles „ background “-Element enthalten.

import QtQuick
import QtQuick.Controls.Basic
Label {
text: qsTr("Label")
color: "#21be2b"
}Anpassung von „Menu“
- Menu besteht aus einem visuellen Element „ background “.
- MenuItem besteht aus vier visuellen Elementen: background, contentItem, indicator und arrow.
- MenuSeparator besteht aus den visuellen Elementen „ background “ und „ 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
}
}Anpassen der Menüleiste
MenuBar kann ein visuelles Element „ background “ enthalten, und „ MenuBarItem “ besteht aus zwei visuellen Elementen: „ background “ und „ 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
}
}
}Anpassung von „PageIndicator“
PageIndicator besteht aus einem „ background “, einem „ contentItem “ und einem „ 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
}
}
}
}Anpassung des Bereichs
Der Bereich besteht aus einem „ background “.

import QtQuick
import QtQuick.Controls.Basic
Pane {
background: Rectangle {
color: "#eeeeee"
}
Label {
text: qsTr("Content goes here!")
}
}Anpassung des Popups
Das Popup besteht aus einem „ background “ und einem „ contentItem “.

import QtQuick
import QtQuick.Controls.Basic
Popup {
id: popup
background: Rectangle {
implicitWidth: 200
implicitHeight: 200
border.color: "#444"
}
contentItem: Column {}
}Anpassung der ProgressBar
ProgressBar besteht aus zwei visuellen Elementen: „ background “ und „ 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
}
}
}
}
}Oben wird das „contentItem“ ebenfalls animiert, um den Status eines „ indeterminate “-Fortschrittsbalkens darzustellen.
Anpassen des RadioButton
RadioButton besteht aus drei visuellen Elementen: „ background “, „ contentItem “ und „ 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
}
}Anpassung von RadioDelegate
RadioDelegate besteht aus drei visuellen Elementen: „ background “, „ contentItem “ und „ 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"
}
}Anpassung von „RangeSlider“
RangeSlider besteht aus drei visuellen Elementen: background, first.handle und 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"
}
}Anpassung von „RoundButton“
RoundButton kann auf dieselbe Weise wie „Button“ angepasst werden.
Anpassen von „ScrollBar“
ScrollBar besteht aus zwei visuellen Elementen: „ background “ und „ 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 {}
}
}
}Anpassung von „ScrollIndicator“
ScrollIndicator besteht aus zwei visuellen Elementen: „ background “ und „ 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"
}
}Anpassen von „ScrollView“
ScrollView besteht aus einem „ background “-Element sowie horizontalen und vertikalen Bildlaufleisten.

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"
}
}Anpassen des „Slider“
Der „Slider“ besteht aus zwei visuellen Elementen: „ background “ und „ 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"
}
}Anpassen der SpinBox
SpinBox besteht aus vier visuellen Elementen: „ background “, „ contentItem “, „ up indicator “ und „ 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"
}
}Anpassung von SplitView
SplitView besteht aus einem visuellen „ handle “-Delegaten.

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"
}
}Anpassung von „StackView“
StackView kann ein visuelles „ background “-Element enthalten und ermöglicht die Anpassung der Übergänge, die für „Push“--, „Pop“- und „Replace“-Operationen verwendet werden.
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
}
}
}Anpassen von SwipeDelegate
SwipeDelegate besteht aus sechs visuellen Elementen: background, contentItem, indicator, swipe.left, swipe.right und 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
}
}
}
}Anpassen von SwipeView
SwipeView kann ein visuelles „ background “-Element enthalten. Die Navigation wird über die Klasse contentItem implementiert.
import QtQuick
import QtQuick.Controls.Basic
SwipeView {
id: control
background: Rectangle {
color: "#eeeeee"
}
}Anpassen von „Switch“
„Switch“ besteht aus drei visuellen Elementen: „ background “, „ contentItem “ und „ 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
}
}Anpassung von „SwitchDelegate“
SwitchDelegate besteht aus drei visuellen Elementen: „ background “, „ contentItem “ und „ 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"
}
}Anpassung von „TabBar“
TabBar besteht aus zwei visuellen Elementen: background und 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")
}
}Anpassen von „TabButton“
TabButton kann auf dieselbe Weise wie ein Button angepasst werden.
Anpassen von „TextArea“
TextArea besteht aus einem „ background “-Element.

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"
}
}Anpassen von „TextField“
TextField besteht aus einem „ background “-Element.

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"
}
}Anpassung der „ToolBar“
ToolBar besteht aus einem visuellen Element: „ 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")
}
}
}Anpassen von „ToolButton“
ToolButton besteht aus zwei visuellen Elementen: „ background “ und „ 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))
}
}Anpassen von „ToolSeparator“
ToolSeparator besteht aus zwei visuellen Elementen: background und 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
}
}
}Anpassung von „ToolTip“
ToolTip besteht aus zwei visuellen Elementen: „ background “ und „ 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"
}
}Hinweis: Um das „ attached ToolTip “ anzupassen, muss es als Teil Ihres eigenen Stils bereitgestellt werden. Informationen zur einmaligen Anpassung eines „ ToolTip “ finden Sie unter Custom Tool Tips.
Anpassen von Tumbler
Tumbler besteht aus drei visuellen Elementen: background, contentItem und 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"
}
}Wenn Sie ein eigenes „contentItem“ definieren möchten, verwenden Sie entweder ein „ ListView “ oder ein „ PathView “ als Stammelement. Für einen Tumbler mit Zeilenumbruch verwenden Sie „ 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
}
}Für einen Tumbler ohne Umbruch verwenden Sie 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
}
}Anpassen von „TableViewDelegate“
TableViewDelegate erbt von ` ItemDelegate`, was bedeutet, dass er aus zwei visuellen Elementen besteht: ` background ` und ` contentItem`.
Sie können „ editDelegate “ jederzeit einen eigenen, benutzerdefinierten Bearbeitungsdelegaten zuweisen, wenn Sie Anforderungen haben, die über die Möglichkeiten des Standard-Bearbeitungsdelegaten hinausgehen.

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
}
}
}Anpassen von „HeaderViewDelegate“
„HeaderViewDelegate“ erbt von „ TableViewDelegate “, was bedeutet, dass es aus zwei Elementen besteht: „ background “ und „ contentItem “. Sie können diese jederzeit mit beliebigen Elementen anpassen.

Hier ist ein Beispiel für die Anpassung des Delegaten für die horizontale Kopfzeilenansicht:
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
}
}
}Hier ist ein Beispiel für die Anpassung des vertikalen Header-View-Delegaten:
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
}
}
}Gestaltung von Steuerelementen mit StyleKit
Das Qt Labs StyleKit-Modul bietet eine Reihe von QML-Typen zur Gestaltung von Qt Quick Controls, die auf Qt Quick Templates 2 aufsetzen. Damit können Sie einen vollständigen visuellen Stil für alle Ihre Steuerelemente über ein einziges Style-Objekt definieren, einschließlich der Unterstützung für Themen, zustandsbasierte Gestaltung und Übergänge. StyleKit übernimmt automatisch die zugrunde liegende Template-Implementierung, sodass Sie sich ganz auf visuelle Aspekte wie Farben, Abmessungen, Rahmen und Schatten konzentrieren können.
Das Qt Labs StyleKit -Modul ist ein Technology Preview-Modul in 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.