La sintaxis de las hojas de estilo
La terminología y las reglas sintácticas de las Hojas de Estilo Qt son casi idénticas a las de HTML CSS. Si ya conoce CSS, probablemente pueda hojear rápidamente esta sección.
Reglas de Estilo
Las hojas de estilo consisten en una secuencia de reglas de estilo. Una regla de estilo se compone de un selector y una declaración. El selector especifica a qué widgets afecta la regla; la declaración especifica qué propiedades deben establecerse en el widget. Por ejemplo:
QPushButton { color: red }En la regla de estilo anterior, QPushButton es el selector y { color: red } es la declaración. La regla especifica que QPushButton y sus subclases (por ejemplo, MyPushButton) deben utilizar el rojo como color de primer plano.
La Hoja de Estilo Qt generalmente no distingue entre mayúsculas y minúsculas (es decir, color, Color, COLOR, y cOloR se refieren a la misma propiedad). Las únicas excepciones son los nombres de clases, object names, y los nombres de propiedades Qt, que distinguen entre mayúsculas y minúsculas.
Se pueden especificar varios selectores para la misma declaración, utilizando comas (,) para separar los selectores. Por ejemplo, la regla
QPushButton, QLineEdit, QComboBox { color: red }
equivale a esta secuencia de tres reglas:
QPushButton { color: red } QLineEdit { color: red } QComboBox { color: red }
La parte de declaración de una regla de estilo es una lista de pares property: value encerrada entre llaves ({}) y separada por punto y coma. Por ejemplo:
QPushButton { color: red; background-color: white }
Consulte la sección Lista de propiedades a continuación para ver la lista de propiedades proporcionadas por los Qt Widgets.
Tipos de selectores
Todos los ejemplos hasta ahora han usado el tipo más simple de selector, el Selector de Tipo. Las Hojas de Estilo Qt soportan todos los selectores definidos en CSS2. La siguiente tabla resume los tipos de selectores más útiles.
| Selector | Ejemplo | Explicación |
|---|---|---|
| Selector universal | * | Coincide con todos los widgets. |
| Selector de tipo | QPushButton | Coincide con instancias de QPushButton y de sus subclases. |
| Selector de propiedades | QPushButton[flat="false"] | Coincide con instancias de QPushButton que no sean flat. Puede utilizar este selector para comprobar cualquier propiedad Qt que admita QVariant::toString() (consulte la documentación de la función toString() para obtener más detalles). Además, admite la propiedad especial class, para el nombre de la clase.Este selector también puede utilizarse para comprobar propiedades dinámicas. Para más información sobre la personalización mediante propiedades dinámicas, consulte Personalización mediante propiedades dinámicas. En lugar de Atención: Si el valor de la propiedad Qt cambia después de haber establecido la hoja de estilo, podría ser necesario forzar un recálculo de la hoja de estilo. Una forma de conseguirlo es desactivar la hoja de estilo y volver a activarla. |
| Selector de clase | .QPushButton | Coincide con instancias de QPushButton, pero no con sus subclases. Equivale a |
| Selector ID | QPushButton#okButton | Coincide con todas las instancias de QPushButton cuyo object name es okButton. |
| Selector de descendientes | QDialog QPushButton | Busca todas las instancias de QPushButton que sean descendientes (hijos, nietos, etc.) de un QDialog. |
| Selector de hijos | QDialog > QPushButton | Busca todas las instancias de QPushButton que son hijos directos de QDialog. |
Subcontroles
Para estilizar widgets complejos, es necesario acceder a subcontroles del widget, como el botón desplegable de un QComboBox o las flechas arriba y abajo de un QSpinBox. Los selectores pueden contener subcontroles que permiten restringir la aplicación de una regla a subcontroles específicos del widget. Por ejemplo:
QComboBox::drop-down { image: url(dropdown.png) }
La regla anterior aplica estilo al botón desplegable de todos los QComboBoxes. Aunque la sintaxis de doble punto (::) recuerda a los pseudoelementos de CSS3, los subcontroles de Qt difieren conceptualmente de éstos y tienen una semántica de cascada diferente.
Los subcontroles siempre se posicionan con respecto a otro elemento, un elemento de referencia. Este elemento de referencia puede ser el widget u otro sub-control. Por ejemplo, el :: drop-down de un QComboBox se coloca, por defecto, en la esquina superior derecha del rectángulo Padding del QComboBox. El ::drop-down se coloca, por defecto, en el Centro del rectángulo Contents del Sub-control ::drop-down. Consulte la Lista de widgets estilizables más abajo para ver los subcontroles que se pueden utilizar para estilizar un widget y sus posiciones predeterminadas.
El rectángulo de origen a utilizar puede cambiarse utilizando la propiedad subcontrol-origin. Por ejemplo, si queremos colocar el desplegable en el rectángulo de margen del QComboBox en lugar del rectángulo Padding por defecto, podemos especificarlo:
La alineación del desplegable dentro del rectángulo Margen se cambia utilizando la propiedad subcontrol-posición.
Las propiedades width y height se pueden utilizar para controlar el tamaño del subcontrol. Tenga en cuenta que al establecer una imagen se establece implícitamente el tamaño de un subcontrol.
El esquema de posicionamiento relativo(position: relative), permite desplazar la posición del Sub-Control respecto a su posición inicial. Por ejemplo, cuando se pulsa el botón desplegable de QComboBox, puede que queramos que la flecha que hay dentro se desplace para dar un efecto de "pulsado". Para conseguirlo, podemos especificar:
QComboBox::down-arrow { image: url(down_arrow.png); } QComboBox::down-arrow:pressed { position: relative; top: 1px; left: 1px; }
El esquema de posicionamiento absoluto(position: absolute), permite cambiar la posición y el tamaño del Sub-control con respecto al elemento de referencia.
Una vez posicionados, se tratan igual que los widgets y se les puede aplicar estilo utilizando el modelo de caja.
Vea la Lista de Subcontroles más abajo para una lista de los subcontroles soportados, y Personalizando el Subcontrol Indicador de Menú de QPushButton para un ejemplo realista.
Nota: Con widgets complejos como QComboBox y QScrollBar, si se personaliza una propiedad o subcontrol, todas las demás propiedades o subcontroles deben personalizarse también.
Pseudo-Estados
Los selectores pueden contener pseudoestados que denotan que restringen la aplicación de la regla basándose en el estado del widget. Los pseudoestados aparecen al final del selector, con dos puntos (:) entre ellos. Por ejemplo, la siguiente regla se aplica cuando el ratón pasa por encima de QPushButton:
QPushButton:hover { color: white }Los pseudoestados pueden negarse utilizando el operador de exclamación. Por ejemplo, la siguiente regla se aplica cuando el ratón no pasa sobre QRadioButton:
QRadioButton:!hover { color: red }
Los pseudoestados pueden encadenarse, en cuyo caso se utiliza el operador lógico AND. Por ejemplo, la siguiente regla se aplica cuando el ratón pasa por encima de una casilla QCheckBox:
QCheckBox:hover:checked { color: white }Los pseudoestados negados pueden aparecer en cadenas de pseudoestados. Por ejemplo, la siguiente regla se aplica cuando el ratón pasa por encima de un QPushButton que no está pulsado:
QPushButton:hover:!pressed { color: blue; }
Si es necesario, se puede expresar OR lógico utilizando el operador coma:
Los pseudoestados pueden aparecer en combinación con subcontroles. Por ejemplo:
QComboBox::drop-down:hover { image: url(dropdown_bright.png) }
Consulte la sección Lista de pseudoestados a continuación para ver la lista de pseudoestados que proporcionan los widgets Qt.
Resolución de conflictos
Los conflictos surgen cuando varias reglas de estilo especifican las mismas propiedades con valores diferentes. Considere la siguiente hoja de estilo:
QPushButton#okButton { color: gray } QPushButton { color: red }
Ambas reglas coinciden con instancias de QPushButton llamadas okButton y existe un conflicto para la propiedad color. Para resolver este conflicto, debemos tener en cuenta la especificidad de los selectores. En el ejemplo anterior, QPushButton#okButton se considera más específico que QPushButton, porque (normalmente) se refiere a un único objeto, no a todas las instancias de una clase.
Del mismo modo, los selectores con pseudoestados son más específicos que los que no especifican pseudoestados. Así, la siguiente hoja de estilo especifica que un QPushButton debe tener texto blanco cuando el ratón pasa por encima, en caso contrario, texto rojo:
QPushButton:hover { color: white } QPushButton { color: red }
Aquí hay un truco:
QPushButton:hover { color: white } QPushButton:enabled { color: red }
Aquí, ambos selectores tienen la misma especificidad, por lo que si el ratón pasa sobre el botón mientras está activado, la segunda regla tiene prioridad. Si queremos que el texto sea blanco en ese caso, podemos reordenar las reglas así:
QPushButton:enabled { color: red } QPushButton:hover { color: white }
Alternativamente, podemos hacer la primera regla más específica:
QPushButton:hover:enabled { color: white } QPushButton:enabled { color: red }
Un problema similar se plantea en relación con los selectores de tipo. Considere el siguiente ejemplo:
QPushButton { color: red } QAbstractButton { color: gray }
Ambas reglas se aplican a las instancias de QPushButton (ya que QPushButton hereda de QAbstractButton) y existe un conflicto para la propiedad color. Dado que QPushButton hereda de QAbstractButton, podría ser tentador asumir que QPushButton es más específica que QAbstractButton. Sin embargo, para los cálculos de la hoja de estilo, todos los selectores de tipo tienen la misma especificidad, y la regla que aparece en último lugar tiene prioridad. En otras palabras, el color se establece en gray para todos los QAbstractButtons, incluido QPushButtons. Si realmente queremos que QPushButtons tenga texto rojo, siempre podemos reordenar las reglas.
Para determinar la especificidad de una regla, las hojas de estilo Qt siguen la especificación CSS2:
La especificidad de un selector se calcula de la siguiente manera:
- cuenta el número de atributos ID en el selector (= a)
- contar el número de otros atributos y pseudoclases en el selector (= b)
- contar el número de nombres de elementos en el selector (= c)
- ignorar los pseudoelementos [es decir, los subcontroles].
La concatenación de los tres números a-b-c (en un sistema numérico con una base grande) da la especificidad.
Algunos ejemplos:
* {} /* a=0 b=0 c=0 -> specificity = 0 */ LI {} /* a=0 b=0 c=1 -> specificity = 1 */ UL LI {} /* a=0 b=0 c=2 -> specificity = 2 */ UL OL+LI {} /* a=0 b=0 c=3 -> specificity = 3 */ H1 + *[REL=up]{} /* a=0 b=1 c=1 -> specificity = 11 */ UL OL LI.red {} /* a=0 b=1 c=3 -> specificity = 13 */ LI.red.level {} /* a=0 b=2 c=1 -> specificity = 21 */ #x34y {} /* a=1 b=0 c=0 -> specificity = 100 */
En cascada
Las hojas de estilo pueden establecerse en QApplication, en los widgets padre y en los widgets hijos. La hoja de estilo efectiva de un widget arbitrario se obtiene fusionando las hojas de estilo establecidas en los ancestros del widget (padre, abuelo, etc.), así como cualquier hoja de estilo establecida en QApplication.
Cuando surgen conflictos, siempre se prefiere la hoja de estilo propia del widget a cualquier hoja de estilo heredada, independientemente de la especificidad de las reglas en conflicto. Del mismo modo, la hoja de estilo del widget padre se prefiere a la del abuelo, etc.
Una consecuencia de esto es que establecer una regla de estilo en un widget automáticamente le da precedencia sobre otras reglas especificadas en las hojas de estilo de los widgets antecesores o en la hoja de estilo QApplication. Considere el siguiente ejemplo. En primer lugar, establecemos una hoja de estilo en el widget QApplication:
qApp->setStyleSheet("QPushButton { color: white }");
A continuación, establecemos una hoja de estilo en un objeto QPushButton:
myPushButton->setStyleSheet("* { color: blue }");
La hoja de estilo en QPushButton fuerza a QPushButton (y a cualquier widget hijo) a tener texto azul, a pesar del conjunto de reglas más específicas proporcionadas por la hoja de estilo de toda la aplicación.
El resultado habría sido el mismo si hubiéramos escrito
myPushButton->setStyleSheet("color: blue");
excepto que si QPushButton tuviera hijos (lo que es poco probable), la hoja de estilo no tendría ningún impacto sobre ellos.
La hoja de estilo en cascada es un tema complejo. Consulta la especificación CSS2 para conocer todos los detalles. Tenga en cuenta que Qt actualmente no implementa !important.
Herencia
En CSS clásico, cuando la fuente y el color de un elemento no se establecen explícitamente, se heredan automáticamente del padre. Por defecto, cuando se usan las Hojas de Estilo de Qt, un widget no hereda automáticamente su configuración de fuente y color de su widget padre.
Por ejemplo, considere un QPushButton dentro de un QGroupBox:
qApp->setStyleSheet("QGroupBox { color: red; } ");
El QPushButton no tiene un conjunto de colores explícito. Por lo tanto, en lugar de heredar el color de su padre QGroupBox, tiene el color del sistema. Si queremos establecer el color en un QGroupBox y sus hijos, podemos escribir:
qApp->setStyleSheet("QGroupBox, QGroupBox * { color: red; }");
Por el contrario, establecer una fuente y una paleta usando QWidget::setFont() y QWidget::setPalette() se propaga a los widgets hijos.
Si prefieres que la fuente y la paleta se propaguen a los widgets hijos, puedes establecer la bandera Qt::AA_UseStyleSheetPropagationInWidgetStyles, así:
Uso:
QCoreApplication::setAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles, true);
Cuando se activa la propagación de fuentes y paletas de estilo a widgets, los cambios de fuentes y paletas realizados a través de las Hojas de Estilo Qt se comportarán como si el usuario hubiera llamado manualmente a los métodos QWidget::setPalette() y QWidget::setFont() correspondientes en todos los QWidgets a los que se dirige la hoja de estilo.
- Los cambios realizados por una hoja de estilo se propagan. Son enviados a todos los widgets que coincidan con la hoja de estilo una vez, en el momento en que se realiza el cambio.
- Los cambios realizados llamando a QWidget::setPalette() o QWidget::setFont() se heredan. Son heredados por todos los hijos existentes y futuros, donde el pincel o fuente respectivo no ha sido explícitamente establecido.
Widgets dentro de espacios de nombres C
El selector de tipo puede utilizarse para dar estilo a widgets de un tipo concreto. Por ejemplo,
clase MiPulsador : public QPushButton { // ...};// ...void algunaFunción(){ qApp->setStyleSheet("MyPushButton { background: yellow; }"); //...
La Hoja de Estilo Qt usa QObject::className() del widget para determinar cuándo aplicar el Selector de Tipo. Cuando los widgets personalizados están dentro de namespaces, QObject::className() devuelve <namespace>::<classname>. Esto entra en conflicto con la sintaxis de los subcontroles. Para superar este problema, cuando se utiliza el Selector de Tipo para widgets dentro de espacios de nombres, debemos sustituir :: por --. Por ejemplo,
namespace ns { class MiPulsador : public QPushButton { // ...}; }// ...void someMethod(){ qApp->setStyleSheet("ns--MyPushButton { background: yellow; }"); //...
Establecer propiedades de QObject
A partir de la versión 4.3 y superiores, cualquier Q_PROPERTY diseñable se puede establecer utilizando la sintaxis qproperty-<nombre de propiedad>.
Por ejemplo,
MyLabel { qproperty-pixmap: url(pixmap.png); }
MyGroupBox { qproperty-titleColor: rgb(100, 200, 100); }
QPushButton { qproperty-iconSize: 20px 20px; }Si la propiedad hace referencia a un enum declarado con Q_ENUM, debe hacer referencia a sus constantes por su nombre, no por su valor numérico.
Nota: Utilice la sintaxis qproperty con cuidado, ya que modifica el widget que se está pintando. Además, la sintaxis qproperty sólo se evalúa una vez, que es cuando el widget es pulido por el estilo. Esto significa que cualquier intento de utilizarlas en pseudoestados como QPushButton:hover, no funcionará.
© 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.