Personalización Qt Quick Controls
Qt Quick Controls consisten en una jerarquía (árbol) de elementos. Para proporcionar un aspecto personalizado, la implementación QML predeterminada de cada elemento puede sustituirse por una personalizada.
Personalizar un control
A veces querrás crear un aspecto "único" para una parte específica de tu interfaz de usuario, y utilizar un estilo completo en todas las demás partes. Tal vez esté satisfecho con el estilo que utiliza, pero hay un botón que tiene un significado especial.
La primera forma de crear este botón es simplemente definirlo in situ, allí donde sea necesario. Por ejemplo, tal vez no esté satisfecho con que el botón del estilo Básico tenga las esquinas cuadradas. Para hacerlas redondeadas, puede anular el elemento background y establecer la propiedad radio de Rectángulo:
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 } } }
Nota: como los diferentes elementos que componen un control en cualquier estilo están diseñados para trabajar juntos, puede ser necesario anular otros elementos para obtener el aspecto que buscas. Además, no todos los estilos pueden personalizarse. Consulte la nota en Referencia de personalización para obtener más información.
La segunda forma de crear el botón es buena si planea utilizar su botón redondeado en varios lugares. Implica mover el código a su propio archivo QML dentro de su proyecto.
Para ello, copiaremos el código de fondo del estilo Basic en Button.qml. Este archivo se encuentra en la siguiente ruta en tu instalación de Qt:
$QTDIR/qml/QtQuick/Controls/Basic/Button.qml
Una vez hecho esto, simplemente añadiremos la siguiente línea:
radius: 4Para evitar confusiones con los controles del propio módulo, llamaremos al fichero MyButton.qml. Para utilizar el control en su aplicación, refiérase a él por su nombre de archivo:
import QtQuick.Controls.Basic ApplicationWindow { MyButton { text: qsTr("A Special Button") } }
La tercera forma de crear el botón es un poco más estructurada, tanto en términos de dónde se sitúa el archivo en el sistema de archivos como de cómo se utiliza en QML. En primer lugar, copie un archivo existente como hizo anteriormente, pero esta vez, póngalo en una subcarpeta de su proyecto llamada (por ejemplo) controls. Para utilizar el control, primero importa la carpeta a un espacio de nombres:
import QtQuick.Controls.Basic import "controls" as MyControls ApplicationWindow { MyControls.Button { text: qsTr("A Special Button") } }
Como ahora tiene el espacio de nombres MyControls, puede nombrar los controles como sus homólogos reales en el módulo Qt Quick Controls. Puede repetir este proceso para cualquier control que desee añadir.
Una ventaja añadida de estos tres métodos es que no es necesario implementar la plantilla desde cero.
Nota: los tres enfoques mencionados aquí no funcionan para personalizar el ToolTip adjunto, ya que se trata de un elemento compartido creado internamente. Para realizar una personalización puntual de un ToolTip, consulte Custom Tool Tips. Para personalizar el ToolTip adjunto , debe proporcionarlo como parte de su propio estilo.
Creación de un estilo personalizado
Hay varias formas de crear estilos propios. A continuación, explicaremos los distintos enfoques.
Definición de un estilo
En Qt Quick Controls, un estilo es esencialmente un conjunto de archivos QML dentro de un mismo directorio. Hay cuatro requisitos para que un estilo sea utilizable:
- Debe existir al menos un archivo QML cuyo nombre coincida con un control (por ejemplo,
Button.qml). - Cada archivo QML debe contener el tipo correspondiente de la importación QtQuick.Templates como elemento raíz. Por ejemplo, Button.qml debe contener una plantilla Button como elemento raíz.
Si en su lugar utilizáramos el tipo correspondiente de la importación QtQuick.Controls como hicimos en la sección anterior, no funcionaría: el control que estuviéramos definiendo intentaría derivar de sí mismo.
- Debe existir un archivo qmldir junto al archivo o archivos QML. A continuación se muestra un ejemplo de un simple archivo
qmldirpara un estilo que proporciona un botón:module MyStyle Button 2.15 Button.qml
Si está utilizando la selección de estilo en tiempo de compilación, el qmldir también debe importar el estilo de reserva:
# ... import QtQuick.Controls.Basic auto
Esto también se puede hacer para la selección de estilo en tiempo de ejecución en lugar de utilizar, por ejemplo, QQuickStyle::setFallbackStyle().
La estructura de directorios para un estilo de este tipo es la siguiente:
MyStyle ├─── Button.qml └─── qmldir
- Los archivos deben estar en un directorio que se pueda encontrar a través de la ruta de importación de QML.
Por ejemplo, si la ruta al directorio MyStyle mencionado anteriormente era
/home/user/MyApp/MyStyle, entonces/home/user/MyAppdebe añadirse a la ruta de importación QML.Para utilizar MyStyle en MyApp, haga referencia a él por su nombre:
./MyApp -style MyStyle
El nombre del estilo debe coincidir con el del directorio de estilos; no se admite el uso de mystyle o MYSTYLE.
Por defecto, el sistema de estilos utiliza el estilo Basic como alternativa para los controles que no están implementados. Para personalizar o ampliar cualquier otro estilo incorporado, es posible especificar un estilo alternativo diferente utilizando QQuickStyle.
Lo que esto significa es que puedes implementar tantos controles como quieras para tu estilo personalizado, y colocarlos casi en cualquier lugar. También permite a los usuarios crear sus propios estilos para tu aplicación.
Vista previa de los estilos personalizados en Qt Quick Designer
Usando el enfoque anterior, es posible previsualizar un estilo personalizado en Qt Quick Designer. Para ello, asegúrese de que el proyecto tiene un archivo qtquickcontrols2.conf, y que existe la siguiente entrada:
[Controls] Style=MyStyle
Para obtener más información, eche un vistazo al ejemplo de estilo plano.
Extensiones C++ específicas del estilo
A veces puede que necesite utilizar C++ para ampliar su estilo personalizado.
- Si el estilo que utiliza el tipo es el único utilizado por una aplicación, registre el tipo con el motor QML añadiendo la macro QML_ELEMENT y haciendo que el archivo forme parte de su módulo 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 la cabecera en la que se declara la clase no es accesible desde la ruta de inclusión de su proyecto, es posible que tenga que modificar la ruta de inclusión para que se pueda compilar el código de registro generado.
INCLUDEPATH += MyItems
Consulte Definición de tipos QML desde C++ y Construcción de una aplicación QML para obtener más información.
- Si el estilo que utiliza el tipo es uno de los muchos estilos que utiliza una aplicación, considere la posibilidad de colocar cada estilo en un módulo independiente. Los módulos se cargarán bajo demanda.
Consideraciones para los estilos personalizados
Cuando implementes tu propio estilo y personalices los controles, hay algunos puntos a tener en cuenta para asegurar que tu aplicación tenga el mayor rendimiento posible.
Evita asignar un id a las implementaciones de delegados de elementos de los estilos
Como se explica en Definición de un Estilo, cuando implementas tu propio estilo para un control, comienzas con la plantilla relevante para ese control. Por ejemplo, un estilo Button.qml se estructurará de forma similar a esta:
Cuando utilice un Botón en su aplicación, los elementos background y contentItem serán creados y emparentados con el elemento raíz Button:
// Creates the Button root item, the Rectangle background, // and the Text contentItem. Button { text: qsTr("Confirm") }
Supongamos que necesita personalizar el botón (como se explica en Personalizar un control):
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, esto normalmente daría lugar a la creación tanto de la implementación por defecto background como de los elementos personalizados background. Qt Quick Controls utiliza una técnica que evita la creación de ambos elementos, y en su lugar sólo crea el elemento personalizado background, mejorando enormemente el rendimiento de creación de los controles.
Esta técnica se basa en la ausencia de un id en la implementación del estilo de ese elemento. Si se asigna un id, la técnica no puede funcionar, y se crearán ambos elementos. Por ejemplo, puede ser tentador asignar un id a background o contentItem para que otros objetos dentro del archivo puedan referirse a esos elementos:
T.Button { // ... background: Rectangle { id: backgroundRect // ... } contentItem: Text { // Use backgroundRect in some way... } // ... }
Con este código, cada vez que se cree una instancia de Button con un fondo personalizado, se crearán ambos fondos, lo que resultará en un rendimiento de creación subóptimo.
Antes de Qt 5.15, el fondo antiguo no utilizado se eliminaba para liberar los recursos asociados a él. Sin embargo, como el control no es propietario de los elementos, no debería borrarlos. A partir de Qt 5.15, los elementos antiguos ya no se borran, por lo que el elemento backgroundRect vivirá más tiempo del necesario, normalmente hasta que se cierre la aplicación. Aunque el elemento antiguo se ocultará, visualmente no tendrá parentesco con el control y se eliminará del árbol de accesibilidad, es importante tener en cuenta el tiempo de creación y el uso de memoria de estos elementos no utilizados al asignar un id en este contexto.
Evitar asignaciones imperativas de elementos personalizados
La técnica mencionada en la sección anterior sólo funciona cuando un elemento se asigna de forma declarativa por primera vez, por lo que las asignaciones imperativas darán lugar a elementos huérfanos. Siempre que sea posible, utilice vínculos declarativos para asignar elementos personalizados.
No importar QtQuick.Controls en implementaciones QML
Cuando escriba el QML para la implementación de un control en su estilo, es importante no importar QtQuick.Controls. Hacerlo impedirá que el compilador QML compile el QML.
Implementar tipos utilizados por otros tipos
Supongamos que estás utilizando ScrollViews en tu aplicación, y decides que quieres personalizar sus barras de desplazamiento. Es tentador simplemente implementar un ScrollBar.qml personalizado y hacer que ScrollView recoja el ScrollBar personalizado automáticamente. Sin embargo, esto no funcionará. Debe implementar tanto ScrollBar.qml como ScrollView.qml.
Propiedades adjuntas
Es habitual que un estilo tenga ciertas propiedades o atributos que se aplican a todos los controles. Las propiedades adjuntas son una buena forma de ampliar un elemento en QML sin tener que modificar ningún C++ existente perteneciente a ese elemento. Por ejemplo, tanto el estilo Material como el Universal tienen una propiedad adjunta theme que controla si un ítem y sus hijos serán renderizados en un tema claro u oscuro.
Como ejemplo, vamos a añadir una propiedad adjunta que controla la elevación. Nuestro estilo ilustrará la elevación con una sombra; cuanto mayor sea la elevación, mayor será la sombra.
El primer paso es crear una nueva aplicación Qt Quick Controls en Qt Creator. Después, añadimos un tipo C++ que almacena la elevación. Dado que el tipo se utilizará para cada control soportado por nuestro estilo, y porque es posible que deseemos añadir otras propiedades adjuntas más adelante, lo llamaremos MyStyle. Aquí está 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(); }
El tipo MyStyle es especial en el sentido de que no debe ser instanciado, sino utilizado para sus propiedades adjuntas. Por esa razón, lo registramos de la siguiente manera en 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(); }
A continuación, copiamos Button.qml del estilo Basic en $QTDIR/qml/QtQuick/Controls/Basic/ en una nueva carpeta myproject en el directorio de nuestro proyecto. Añadimos el Button.qml recién copiado a qml.qrc, que es el archivo de recursos que contiene nuestros archivos QML.
A continuación, añadimos una sombra paralela al delegado background del Botón:
// ...
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
}
}Fíjate que nosotros:
- No nos molestamos en usar la sombra cuando la elevación es
0 - Cambiamos el color de la sombra dependiendo de si el botón tiene o no foco
- Hacemos que el tamaño de la sombra dependa de la elevación
Para probar la propiedad adjunta, creamos un Row con dos Botones en 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 } } }
Un botón no tiene elevación, y el otro tiene una elevación de 10.
Con eso en su lugar, podemos ejecutar nuestro ejemplo. Para decirle a la aplicación que utilice nuestro nuevo estilo, pasamos -style MyStyle como argumento de la aplicación, pero hay muchas formas de especificar el estilo a utilizar.
El resultado final:

Observe que la declaración import MyStyle 1.0 sólo es necesaria porque estamos utilizando la propiedad adjunta perteneciente a MyStyle. Ambos botones utilizarán nuestro estilo personalizado, incluso si elimináramos la importación.
Referencia de personalización
Los siguientes fragmentos de código presentan ejemplos en los que los controles del estilo Básico se han personalizado utilizando el mismo enfoque que en la sección Personalización de un control. El código puede utilizarse como punto de partida para implementar un aspecto personalizado.
Nota: Los estilos macOS y Windows no se pueden personalizar. En su lugar, se recomienda basar siempre un control personalizado en un único estilo que esté disponible en todas las plataformas, por ejemplo, Basic Style, Fusion Style, Imagine Style, Material Style, Universal Style. De este modo, se garantiza que siempre tendrá el mismo aspecto, independientemente del estilo con el que se ejecute la aplicación. Para aprender a utilizar un estilo diferente, consulte Uso de estilos en Qt Quick Controls. Alternativamente, puede crear su propio estilo.
La personalización de ApplicationWindow
ApplicationWindow consta de un elemento visual: background.
import QtQuick import QtQuick.Controls.Basic ApplicationWindow { visible: true background: Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#ffffff" } GradientStop { position: 1; color: "#c1bbf9" } } } }
La personalización de BusyIndicator
BusyIndicator consta de dos elementos visuales: background y 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 } ] } } } } }
Personalización de Button
Button consta de dos elementos visuales: background y 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 } }
Personalización de CheckBox
CheckBox consta de tres elementos visuales: background contentItem y 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 } }
La personalización de CheckDelegate
CheckDelegate consta de tres elementos visuales: background, contentItem y 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" } }
Personalización de ComboBox
ComboBox consta de background, contentItem, popup, indicator, y 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 } } }
Como se explica en ComboBox Model Roles, ComboBox soporta múltiples tipos de modelos.
Dado que todos los modelos proporcionan una propiedad anónima con modelData, la siguiente expresión recupera el texto correcto en todos los casos:
text: model[control.textRole]
Cuando se proporciona un textRole específico y un modelo con datos estructurados que proporciona el rol seleccionado, esta expresión es una búsqueda regular de propiedades. Cuando se proporciona un modelo con datos singulares, como una lista de cadenas, y un textRole vacío, esta expresión recupera el modelData.
Personalización de DelayButton
DelayButton consta de dos elementos visuales: background y 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() } } } }
Personalización de Dial
Dial consta de dos elementos visuales: background y 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 } ] } }
Personalización de DoubleSpinBox
DoubleSpinBox puede personalizarse de la misma manera que Button.
Personalización de Drawer
El cajón puede tener un elemento visual background.
background: Rectangle {
Rectangle {
x: parent.width - 1
width: 1
height: parent.height
color: "#21be2b"
}
}Personalización de Frame
El marco consta de un elemento visual: background.

import QtQuick import QtQuick.Controls.Basic Frame { background: Rectangle { color: "transparent" border.color: "#21be2b" radius: 2 } Label { text: qsTr("Content goes here!") } }
Personalización de GroupBox
GroupBox consta de dos elementos visuales: background y 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!") } }
Personalización de ItemDelegate
ItemDelegate consta de dos elementos visuales: background y 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 } } }
Personalización de la etiqueta
La etiqueta puede tener un elemento visual background.

import QtQuick import QtQuick.Controls.Basic Label { text: qsTr("Label") color: "#21be2b" }
Menú de personalización
- Menu consta de un elemento visual background.
- MenuItem consta de cuatro elementos visuales: background, contentItem, indicator, y arrow.
- MenuSeparator consta de un elemento visual background y 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 } }
Personalización de MenuBar
MenuBar puede tener un elemento visual background y MenuBarItem consta de dos elementos visuales: background y 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 } } }
Personalización de PageIndicator
PageIndicator consta de un background, contentItem, y 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 } } } }
Personalización de Pane
Pane consta de background.

import QtQuick import QtQuick.Controls.Basic Pane { background: Rectangle { color: "#eeeeee" } Label { text: qsTr("Content goes here!") } }
Personalización de Popup
Popup consta de background y contentItem.

import QtQuick import QtQuick.Controls.Basic Popup { id: popup background: Rectangle { implicitWidth: 200 implicitHeight: 200 border.color: "#444" } contentItem: Column {} }
Personalización de ProgressBar
ProgressBar consta de dos elementos visuales: background y 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 } } } } }
Arriba, el contentItem también se anima para representar un estado de la barra de progreso indeterminate.
Personalización de RadioButton
RadioButton consta de tres elementos visuales: background contentItem y 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 } }
Personalización de RadioDelegate
RadioDelegate consta de tres elementos visuales: background, contentItem y 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" } }
La personalización de RangeSlider
RangeSlider consta de tres elementos visuales: background, first.handle y 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" } }
Personalización de RoundButton
RoundButton puede personalizarse de la misma manera que Button.
Personalización de ScrollBar
ScrollBar consta de dos elementos visuales: background y 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 {} } } }
Personalización de ScrollIndicator
ScrollIndicator consta de dos elementos visuales: background y 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" } }
La personalización de ScrollView
ScrollView consta de un elemento background y barras de desplazamiento horizontal y vertical.

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" } }
Personalización de Slider
Slider consta de dos elementos visuales: background, y 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" } }
Personalización de SpinBox
SpinBox consta de cuatro elementos visuales: background, contentItem, up indicator, y 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" } }
Personalización de SplitView
SplitView consta de un delegado visual 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" } }
Personalizar StackView
StackView consta de un elemento visual background, y permite personalizar las transiciones que se utilizan para las operaciones push, pop y replace.
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 } } }
La personalización de SwipeDelegate
SwipeDelegate consta de seis elementos visuales: background, contentItem, indicator, swipe.left, swipe.right, y 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 } } } }
Personalizar SwipeView
SwipeView puede tener un elemento visual background. La navegación es implementada por el contentItem.
import QtQuick import QtQuick.Controls.Basic SwipeView { id: control background: Rectangle { color: "#eeeeee" } }
Personalización de Switch
Switch consta de tres elementos visuales: background contentItem y 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 } }
Personalización de SwitchDelegate
SwitchDelegate consta de tres elementos visuales: background, contentItem y 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" } }
Personalización de TabBar
TabBar consta de dos elementos visuales: background, y 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") } }
Personalización de TabButton
TabButton puede personalizarse de la misma manera que Button.
Personalizar TextArea
TextArea consta de un elemento 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" } }
La personalización de TextField
TextField consiste en un elemento 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" } }
Personalización de ToolBar
ToolBar consta de un elemento visual: 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") } } }
La personalización de ToolButton
ToolButton consta de dos elementos visuales: background y 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)) } }
La personalización de ToolSeparator
ToolSeparator consta de dos elementos visuales: background y 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 } } }
Personalización de ToolTip
ToolTip consta de dos elementos visuales: background y 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" } }
Nota: para personalizar attached ToolTip, debe proporcionarse como parte de su propio estilo. Para realizar una personalización puntual de un ToolTip, consulte Custom Tool Tips.
Personalización de Tumbler
Tumbler consta de tres elementos visuales: background, contentItem, y 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 desea definir su propio elemento de contenido, utilice ListView o PathView como elemento raíz. Para un Tumbler envolvente, utilice 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 } }
Para un Tumbler sin envoltorio, utilice 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 } }
Personalización TableViewDelegate
TableViewDelegate hereda de ItemDelegate, lo que significa que se compone de dos elementos visuales: background y contentItem.
Siempre puede asignar su propio delegado de edición personalizado a editDelegate si tiene necesidades fuera de lo que ofrece el delegado de edición predeterminado.

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 } } }
Personalización de HeaderViewDelegate
HeaderViewDelegate hereda de TableViewDelegate, lo que significa que está compuesto por dos elementos: background y contentItem. Siempre puedes personalizarlos con cualquier elemento arbitrario.

He aquí un ejemplo de personalización del delegado de vista de cabecera horizontal:
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 } } }
Aquí tienes un ejemplo de personalización de la vista delegada de cabecera 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 } } }
Estilizando Controles usando StyleKit
El módulo StyleKit de Qt Labs proporciona un conjunto de tipos QML para estilizar Qt Quick Controls, construido sobre Qt Quick Templates. Permite definir un estilo visual completo para todos los controles a partir de un único objeto Style, incluyendo soporte para temas, estilos basados en estados y transiciones. StyleKit gestiona automáticamente la implementación de la plantilla subyacente, permitiéndole centrarse únicamente en aspectos visuales como colores, dimensiones, bordes y sombras.
El módulo Qt Labs StyleKit es un módulo de Technology Preview en 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.