En esta página

Estilos y widgets con estilo

Los estilos (clases que heredan de QStyle) dibujan en nombre de los widgets y encapsulan el aspecto de una interfaz gráfica de usuario. La clase QStyle es una clase base abstracta que encapsula la apariencia de una GUI. Los widgets incorporados de Qt la utilizan para realizar casi todos sus dibujos, asegurando que se vean exactamente como los widgets nativos equivalentes.

Qt viene con una selección de estilos incorporados. Algunos estilos sólo están disponibles en plataformas específicas. Los estilos personalizados están disponibles como plugins o creando una instancia de una clase de estilo específica con QStyleFactory::create() y estableciéndola con QApplication::setStyle().

Personalizar un estilo

Para personalizar un estilo existente, herede QProxyStyle y reimplemente los métodos virtuales deseados. QProxyStyle permite especificar un estilo base determinado, o utilizará automáticamente el estilo de la aplicación cuando el estilo base se deje sin especificar. El primero proporciona un control total sobre el estilo base y funciona mejor si la personalización espera un cierto comportamiento del estilo, mientras que el segundo proporciona una forma agnóstica de la plataforma para personalizar el estilo de la aplicación que por defecto es el estilo nativo de la plataforma.

Implementación de un estilo personalizado

QCommonStyle proporciona una base práctica para la implementación completa de estilos personalizados. El enfoque es el mismo que con QProxyStyle, pero heredando QCommonStyle y reimplementando los métodos virtuales apropiados. Implementar un estilo personalizado completo es algo complicado, por lo que ofrecemos esta descripción general. Damos un paso a paso de cómo dar estilo a los Qt Widgets individuales. Examinaremos las funciones virtuales, variables miembro y enumeraciones de QStyle.

La parte de este documento que no se refiere al estilo de los widgets individuales debe leerse secuencialmente porque las secciones posteriores tienden a depender de las anteriores. La descripción de los widgets puede utilizarse como referencia mientras se implementa un estilo. Sin embargo, en algunos casos puede ser necesario consultar el código fuente de Qt. La secuencia en el proceso de estilización debería quedar clara después de leer este documento, lo que le ayudará a localizar el código relevante.

Para desarrollar widgets conscientes del estilo (es decir, widgets que se ajustan al estilo en el que se dibujan), necesitas dibujarlos usando el estilo actual. Este documento muestra cómo se dibujan los widgets y qué posibilidades les da el estilo.

Clases para el estilo de los widgets

Estas clases se utilizan para personalizar la apariencia y el estilo de una aplicación.

QColor

Colores basados en valores RGB, HSV o CMYK

QColorSpace

Abstracción del espacio de color

QColorTransform

Transformación entre espacios de color

QCommonStyle

Encapsula la apariencia común de una interfaz gráfica de usuario.

QCursor

Cursor del ratón con una forma arbitraria

QFont

Especifica una consulta para una fuente utilizada para dibujar texto

QFontDatabase

Información sobre los tipos de letra disponibles en el sistema de ventanas subyacente.

QFontInfo

Información general sobre los tipos de letra

QGraphicsAnchor

Representa un ancla entre dos elementos en un QGraphicsAnchorLayout

QGraphicsAnchorLayout

Disposición donde se pueden anclar widgets en una Vista Gráfica

QPalette

Contiene grupos de colores para cada estado de widget

QStyle

Clase base abstracta que encapsula la apariencia de una GUI

QStyleFactory

Crea objetos QStyle

QStyleHintReturn

Sugerencias de estilo que devuelven más que tipos de datos básicos

QStyleHintReturnMask

Sugerencias de estilo que devuelven un QRegion

QStyleHintReturnVariant

Sugerencias de estilo que devuelven una QVariant

QStyleOption

Almacena los parámetros utilizados por las funciones QStyle

QStylePainter

Clase de conveniencia para dibujar elementos QStyle dentro de un widget

La implementación de QStyle

La API de QStyle contiene funciones que dibujan los widgets, funciones estáticas de ayuda para realizar tareas comunes y difíciles (por ejemplo, calcular la posición de los tiradores deslizantes) y funciones para realizar los diversos cálculos necesarios mientras se dibujan (por ejemplo, para que los widgets calculen sus sugerencias de tamaño). El estilo también ayuda a algunos widgets con la disposición de sus contenidos. Además, crea un QPalette que contiene QBrushes para dibujar.

QStyle dibuja elementos gráficos; un elemento es un widget o una parte de un widget como el bisel de un botón, el marco de una ventana o una barra de desplazamiento. La mayoría de las funciones de dibujo toman ahora cuatro argumentos:

  • un valor enum que especifica qué elemento gráfico dibujar
  • un QStyleOption que especifica cómo y dónde renderizar ese elemento
  • un QPainter que debe utilizarse para dibujar el elemento
  • un QWidget sobre el que se realiza el dibujo (opcional)

Cuando un widget pide a un estilo que dibuje un elemento, proporciona al estilo un QStyleOption, que es una clase que contiene la información necesaria para el dibujo. Gracias a QStyleOption, es posible hacer que QStyle dibuje widgets sin vincular ningún código para el widget. Esto permite utilizar las funciones de dibujo de QStyle en cualquier dispositivo de pintura, es decir, se puede dibujar un combobox en cualquier widget, no sólo en QComboBox.

El widget se pasa como último argumento en caso de que el estilo lo necesite para realizar efectos especiales (como botones animados por defecto en macOS), pero no es obligatorio.

A lo largo de esta sección, veremos los elementos de estilo, las opciones de estilo y las funciones de QStyle. Por último, describiremos cómo se utiliza la paleta.

Los elementos de las vistas de elementos se dibujan mediante delegados en Qt. Las cabeceras de las vistas de elementos siguen siendo dibujadas por el estilo. El delegado por defecto de Qt, QStyledItemDelegate, dibuja sus elementos parcialmente a través del estilo actual; dibuja los indicadores de las casillas de verificación y calcula los rectángulos delimitadores de los elementos que componen el elemento. En este documento, sólo describimos cómo implementar una subclase de QStyle. Si desea añadir soporte para otros tipos de datos distintos de los soportados por QStyledItemDelegate, deberá implementar un delegado personalizado. Ten en cuenta que los delegados deben establecerse mediante programación para cada widget individual (es decir, los delegados predeterminados no pueden proporcionarse como plugins).

Los elementos de estilo

Un elemento de estilo es una parte gráfica de una interfaz gráfica de usuario. Un widget consiste en una jerarquía (o árbol) de elementos de estilo. Por ejemplo, cuando un estilo recibe una petición para dibujar un botón pulsador (de QPushButton, por ejemplo), dibuja una etiqueta (texto e icono), un bisel de botón y un marco de enfoque. El bisel del botón, a su vez, consta de un marco alrededor del bisel y otros dos elementos, que veremos más adelante. A continuación se muestra una ilustración conceptual del árbol de elementos del botón pulsador. Veremos el árbol real para QPushButton cuando pasemos por los widgets individuales.

Árbol y elementos de estilo pulsador

Los widgets no se dibujan necesariamente pidiendo al estilo que dibuje un solo elemento. Los widgets pueden hacer varias llamadas al estilo para dibujar diferentes elementos. Un ejemplo es QTabWidget, que dibuja sus pestañas y marco individualmente.

Hay tres tipos de elementos: elementos primitivos, elementos de control y elementos de control complejos. Los elementos están definidos por los enums ComplexControl, ControlElement, y PrimitiveElement. Los valores de cada enum de elemento tienen un prefijo para identificar su tipo: CC_ para elementos complejos, CE_ para elementos de control y PE_ para elementos primitivos. En las tres secciones siguientes veremos qué definen los distintos elementos y veremos ejemplos de widgets que los utilizan.

La descripción de la clase QStyle contiene una lista de estos elementos y sus funciones en el estilo de los widgets. Veremos cómo se utilizan cuando estilizamos widgets individuales.

Elementos primitivos

Los elementos primitivos son elementos GUI que son comunes y a menudo utilizados por varios widgets. Algunos ejemplos son los marcos, los biseles de los botones y las flechas de los cuadros giratorios, las barras de desplazamiento y los cuadros combinados. Los elementos primitivos no pueden existir por sí solos: siempre forman parte de una construcción mayor. No participan en la interacción con el usuario, sino que son decoraciones pasivas en la interfaz gráfica de usuario.

Elementos de control

Un elemento de control realiza una acción o muestra información al usuario. Ejemplos de elementos de control son los botones, las casillas de verificación y las secciones de encabezado en tablas y vistas en árbol. Los elementos de control no son necesariamente widgets completos, como los botones pulsadores, sino que también pueden ser partes de widgets, como las pestañas de la barra de pestañas y los controles deslizantes de la barra de desplazamiento. Se diferencian de los elementos primitivos en que no son pasivos, sino que cumplen una función en la interacción con el usuario. Los controles que constan de varios elementos suelen utilizar el estilo para calcular los rectángulos delimitadores de los elementos. Los subelementos disponibles están definidos por el enum SubElement. Este enum sólo se utiliza para calcular los rectángulos delimitadores; los subelementos no son elementos gráficos que deban dibujarse como los elementos primitivos, de control y complejos.

Elementos de control complejos

Los elementos de control complejos contienen subcontroles. Los controles complejos se comportan de forma diferente dependiendo de dónde los maneje el usuario con el ratón y qué teclas del teclado se pulsen. Esto depende del subcontrol (si lo hay) sobre el que se sitúe o pulse el ratón. Ejemplos de controles complejos son las barras de desplazamiento y los cuadros combinados. Con una barra de desplazamiento, puede utilizar el ratón para mover el control deslizante y pulsar los botones de línea arriba y línea abajo. Los subcontroles disponibles están definidos por el enum SubControl.

Además de dibujar, el estilo debe proporcionar a los widgets información sobre el subcontrol (si lo hay) en el que se ha pulsado el ratón. Por ejemplo, un QScrollBar necesita saber si el usuario pulsó el deslizador, la ranura del deslizador o uno de los botones.

Tenga en cuenta que los subcontroles no son lo mismo que los elementos de control descritos en la sección anterior. No puede utilizar el estilo para dibujar un subcontrol; el estilo sólo calculará el rectángulo delimitador en el que debe dibujarse el subcontrol. Es común, sin embargo, que los elementos complejos utilicen elementos de control y primitivos para dibujar sus subcontroles, que es un enfoque que utilizan frecuentemente los estilos incorporados en Qt y también el estilo Java. Por ejemplo, el estilo Java utiliza PE_IndicatorCheckBox para dibujar la casilla de verificación en los cuadros de grupo (que es un subcontrol de CC_GroupBox). Algunos subcontroles tienen un elemento de control equivalente, por ejemplo, el deslizador de la barra de desplazamiento (SC_SCrollBarSlider y CE_ScrollBarSlider).

Otras tareas de QStyle

Los elementos de estilo y los widgets, como se ha mencionado, utilizan el estilo para calcular los rectángulos delimitadores de los subelementos y los subcontroles. Las métricas de píxel, que son tamaños dependientes del estilo en píxeles de pantalla, también se utilizan para mediciones al dibujar. Los rectángulos y métricas de píxeles disponibles están representados por tres enums en QStyle: SubElement, SubControl, y PixelMetric. Los valores de los enums pueden identificarse fácilmente, ya que empiezan por SE_, SC_ y PM_.

El estilo también contiene un conjunto de sugerencias de estilo, que se representan como valores en el enum StyleHint. No todos los widgets tienen la misma funcionalidad y aspecto en los diferentes estilos. Por ejemplo, cuando los elementos de un menú no caben en una sola columna en la pantalla, algunos estilos admiten el desplazamiento, mientras que otros dibujan más de una columna para que quepan todos los elementos.

Un estilo suele tener un conjunto de imágenes estándar (como una advertencia, una pregunta y una imagen de error) para cuadros de mensaje, cuadros de diálogo de archivo, etc. QStyle proporciona el enum StandardPixmap. Sus valores representan las imágenes estándar. Los widgets de Qt las utilizan, así que cuando implementes un estilo personalizado debes proporcionar las imágenes utilizadas por el estilo que se está implementando.

El estilo calcula el espaciado entre widgets en los diseños. Hay dos maneras en que el estilo puede manejar estos cálculos. Puedes establecer PM_LayoutHorizontalSpacing y PM_LayoutVerticalSpacing, que es la forma en que lo hace el estilo Java (a través de QCommonStyle). Alternativamente, puedes implementar QStyle::layoutSpacing() y QStyle::layoutSpacingImplementation() si necesitas más control sobre esta parte del layout. En estas funciones puedes calcular el espaciado basándote en los tipos de control (QSizePolicy::ControlType) para diferentes políticas de tamaño (QSizePolicy::Policy) y también la opción de estilo para el widget en cuestión.

Opciones de estilo

Las subclases de QStyleOption contienen toda la información necesaria para dar estilo a los elementos individuales. Las opciones de estilo se instancian -normalmente en la pila- y son rellenadas por quien llama a la función QStyle. Dependiendo de lo que se dibuje, el estilo esperará una clase de opción de estilo diferente. Por ejemplo, el elemento QStyle::PE_FrameFocusRect espera un argumento QStyleOptionFocusRect, y es posible crear subclases personalizadas que un estilo personalizado puede utilizar. Las opciones de estilo mantienen variables públicas por razones de rendimiento.

Los widgets pueden estar en un número de estados diferentes, que son definidos por el enum State. Algunas de las banderas de estado tienen diferentes significados dependiendo del widget, pero otras son comunes para todos los widgets como State_Disabled. Es QStyleOption el que establece los estados comunes con QStyleOption::initFrom(); el resto de los estados son establecidos por los widgets individuales.

En particular, las opciones de estilo contienen la paleta y los rectángulos delimitadores de los widgets que se van a dibujar. La mayoría de los widgets tienen opciones de estilo especializadas. QPushButton y QCheckBox, por ejemplo, utilizan QStyleOptionButton como opción de estilo, que contiene el texto, el icono y el tamaño de su icono. El contenido exacto de todas las opciones se describe cuando revisamos los widgets individuales.

Cuando se reimplementan funciones QStyle que toman un parámetro QStyleOption, a menudo es necesario convertir QStyleOption a una subclase (por ejemplo, QStyleOptionFocusRect). Por seguridad, puede utilizar qstyleoption_cast() para asegurarse de que el tipo del puntero es correcto. Si el objeto no es del tipo correcto, qstyleoption_cast() devuelve nullptr. Por ejemplo:

const QStyleOptionFocusRect *focusRectOption =
        qstyleoption_cast<const QStyleOptionFocusRect *>(option);
if (focusRectOption) {
    //...
}

El siguiente fragmento de código ilustra cómo utilizar QStyle para dibujar el rectángulo de enfoque desde paintEvent() de un widget personalizado:

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    //...

    QStyleOptionFocusRect option;
    option.initFrom(this);
    option.backgroundColor = palette().color(QPalette::Window);

    style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter,
                          this);
}

El siguiente ejemplo muestra cómo derivar de un estilo existente para personalizar el aspecto de un elemento gráfico:

class CustomStyle : public QProxyStyle
{
    Q_OBJECT

public:
    explicit CustomStyle(const QWidget *widget = nullptr);
    ~CustomStyle() {}

    void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                       QPainter *painter, const QWidget *widget) const override;
};

void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                QPainter *painter, const QWidget *widget) const
{
    if (element == PE_IndicatorSpinUp || element == PE_IndicatorSpinDown) {
        QPolygon points(3);
        int x = option->rect.x();
        int y = option->rect.y();
        int w = option->rect.width() / 2;
        int h = option->rect.height() / 2;
        x += (option->rect.width() - w) / 2;
        y += (option->rect.height() - h) / 2;

        if (element == PE_IndicatorSpinUp) {
            points[0] = QPoint(x, y + h);
            points[1] = QPoint(x + w, y + h);
            points[2] = QPoint(x + w / 2, y);
        } else { // PE_SpinBoxDown
            points[0] = QPoint(x, y);
            points[1] = QPoint(x + w, y);
            points[2] = QPoint(x + w / 2, y + h);
        }

        if (option->state & State_Enabled) {
            painter->setPen(option->palette.mid().color());
            painter->setBrush(option->palette.buttonText());
        } else {
            painter->setPen(option->palette.buttonText().color());
            painter->setBrush(option->palette.mid());
        }
        painter->drawPolygon(points);
    } else {
        QProxyStyle::drawPrimitive(element, option, painter, widget);
    }
}

Funciones QStyle

La clase QStyle define tres funciones para dibujar los elementos primitivos, de control y complejos: drawPrimitive(), drawControl(), y drawComplexControl(). Las funciones toman los siguientes parámetros

  • el valor enum del elemento a dibujar.
  • un QStyleOption que contiene la información necesaria para dibujar el elemento.
  • un QPainter con el que dibujar el elemento.
  • un puntero a un QWidget, normalmente el widget sobre el que se pinta el elemento.

No todos los widgets envían un puntero a sí mismos. Si la opción de estilo enviada a la función no contiene la información que necesitas, deberías comprobar la implementación del widget para ver si envía un puntero a sí mismo.

La clase QStyle también proporciona funciones de ayuda que se utilizan al dibujar los elementos. La función drawItemText() dibuja texto dentro de un rectángulo especificado, tomando un QPalette como parámetro. La función drawItemPixmap() ayuda a alinear un pixmap dentro de un rectángulo delimitador especificado.

Otras funciones de QStyle realizan diversos cálculos para las funciones que dibujan. Los widgets también utilizan estas funciones para calcular sugerencias de tamaño y rectángulos delimitadores si dibujan ellos mismos varios elementos de estilo. Al igual que las funciones que dibujan elementos, las funciones de ayuda suelen tomar los mismos argumentos.

  • La función subElementRect() toma un valor del enum SubElement y calcula un rectángulo delimitador para un subelemento. El estilo utiliza esta función para saber dónde dibujar las diferentes partes de un elemento. Esto se hace principalmente para la reutilización; si se crea un nuevo estilo, se puede utilizar la misma ubicación de los subelementos que la superclase.
  • La función subControlRect() se utiliza para calcular rectángulos delimitadores para subcontroles en controles complejos. Cuando implementas un nuevo estilo, reimplementas subControlRect() y calculas los rectángulos que son diferentes de la superclase.
  • La función pixelMetric() devuelve una métrica de píxeles, que es un tamaño dependiente del estilo dado en píxeles de pantalla. Toma un valor del enum PixelMetric y devuelve la medida correcta. Tenga en cuenta que las métricas de píxeles no tienen por qué ser medidas estáticas, sino que pueden calcularse, por ejemplo, con la opción de estilo.
  • La función hitTestComplexControl() devuelve el subcontrol sobre el que se encuentra el puntero del ratón en un control complejo. Normalmente, se trata simplemente de utilizar subControlRect() para obtener los rectángulos delimitadores de los subcontroles, y luego ver qué rectángulo contiene la posición del cursor.

QStyle también tiene las funciones polish() y unpolish(). Todos los widgets son enviados a la función polish() antes de ser mostrados y a unpolish() cuando son ocultados. Puedes usar estas funciones para establecer atributos en los widgets o hacer otro trabajo que requiera tu estilo. Por ejemplo, si necesitas saber cuándo el ratón pasa por encima del widget, debes establecer el atributo de widget WA_Hover. El indicador de estado State_MouseOver se establecerá en las opciones de estilo del widget.

QStyle tiene unas cuantas funciones estáticas de ayuda que realizan algunas tareas comunes y difíciles. Pueden calcular la posición de un control deslizante a partir del valor del control deslizante y transformar rectángulos y dibujar texto teniendo en cuenta diseños inversos; consulte la documentación de la clase QStyle para obtener más detalles.

El enfoque habitual cuando uno reimplementa las funciones virtuales de QStyle es hacer el trabajo en elementos que son diferentes de la superclase; para todos los demás elementos, puede simplemente utilizar la implementación de la superclase.

La paleta

Cada estilo proporciona una paleta de colores - es decir, QBrush - que debe utilizarse para dibujar los widgets. Hay un conjunto de colores para los diferentes estados de los widgets (QPalette::ColorGroup): activo (widgets en la ventana que tienen el foco del teclado), inactivo (widgets usados para otras ventanas), y desactivado (widgets que están desactivados). Los estados se pueden encontrar consultando las banderas de estado State_Active y State_Enabled. Cada conjunto contiene ciertos roles de color dados por el enum QPalette::ColorRole. Los roles describen en qué situaciones deben utilizarse los colores (por ejemplo, para pintar fondos de widgets, texto o botones).

El uso de los roles de color depende del estilo. Por ejemplo, si el estilo utiliza degradados, se puede utilizar un color de la paleta y oscurecerlo o aclararlo con QColor::darker() y QColor::lighter() para crear el degradado. En general, si necesita un pincel que no proporciona la paleta, debe intentar derivarlo de una.

QPalette, que proporciona la paleta, almacena colores para diferentes estados del widget y roles de color. La paleta para un estilo es devuelta por standardPalette(). La paleta estándar no se instala automáticamente cuando se establece un nuevo estilo en la aplicación (QApplication::setStyle()) o widget (QWidget::setStyle()), por lo que debe establecer la paleta usted mismo con (QApplication::setPalette()) o (QWidget::setPalette()).

No se recomienda codificar los colores, ya que las aplicaciones y widgets individuales pueden establecer su propia paleta y también utilizar la paleta de su estilo para dibujar. Ten en cuenta que ninguno de los widgets de Qt establece su propia paleta. El estilo Java codifica algunos colores, pero sólo por decisión del autor; no es aconsejable. Por supuesto, no se pretende que el estilo se vea bien con cualquier paleta.

Cuestiones de implementación

A la hora de implementar estilos, hay varias cuestiones a tener en cuenta. Aquí daremos algunas pistas y consejos sobre la implementación.

Cuando se implementan estilos, es necesario revisar el código de los widgets y el código de la clase base y sus ancestros. Esto se debe a que los widgets utilizan el estilo de forma diferente, ya que la implementación en las funciones virtuales de los diferentes estilos puede afectar al estado del dibujo (por ejemplo, alterando el estado de QPainter sin restaurarlo y dibujando algunos elementos sin utilizar la métrica de píxeles y los subelementos adecuados).

Se recomienda que los estilos no alteren el tamaño propuesto de los widgets con la función QStyle::sizeFromContents(), sino que dejen que la implementación de QCommonStyle se encargue de ello. Si es necesario hacer cambios, debe intentar que sean pequeños; el desarrollo de la aplicación puede resultar difícil si la disposición de los widgets tiene un aspecto considerablemente diferente en los distintos estilos.

Estilo Java

Hemos implementado un estilo que se asemeja al aspecto por defecto de Java (anteriormente conocido como Metal). Hemos hecho esto porque es relativamente sencillo de implementar y queríamos crear un estilo para este documento de resumen. Para mantenerlo simple y no demasiado extenso, hemos simplificado un poco el estilo, pero Qt es perfectamente capaz de hacer una copia exacta del estilo. Sin embargo, no hay planes concretos para implementar el estilo como parte de Qt.

En esta sección echaremos un vistazo a algunas cuestiones de implementación. Finalmente, veremos un ejemplo completo sobre el estilo de un widget Java. Seguiremos utilizando el estilo Java a lo largo de todo el documento para los ejemplos y las imágenes de los widgets. La implementación en sí es algo complicada, y no se pretende que la leas detenidamente.

Diseño e implementación

El primer paso en el diseño del estilo fue seleccionar la clase base. Elegimos la subclase QCommonStyle. Esta clase implementa la mayor parte de la funcionalidad que necesitamos, aparte de realizar el dibujo real.

El estilo se implementa en una sola clase. Hemos hecho esto porque nos parece conveniente mantener todo el código en un solo archivo. Además, es una ventaja con respecto a la optimización, ya que instanciamos menos objetos. También mantenemos el número de funciones al mínimo utilizando conmutadores para identificar qué elemento dibujar en las funciones. Esto resulta en funciones grandes, pero como dividimos el código para cada elemento en los switches, el código debería seguir siendo fácil de leer.

Limitaciones y diferencias con Java

No hemos implementado completamente cada elemento en el estilo Java. De esta forma, hemos reducido la cantidad y complejidad del código. En general, el estilo fue pensado como un ejemplo práctico para este documento de resumen de estilo, y no para ser una parte de Qt en sí mismo.

No todos los widgets tienen todos los estados implementados. Esto va para los estados que son comunes, por ejemplo, State_Disabled. Sin embargo, cada estado está implementado para al menos un widget.

Sólo hemos implementado los ticks debajo del deslizador. También se han omitido los pulsadores planos. No tratamos el caso en el que las barras de título y los títulos de las ventanas acoplables se hacen demasiado pequeños para su contenido, sino que simplemente dibujamos subcontroles unos sobre otros.

No hemos intentado emular las fuentes de Java. Java y Qt utilizan motores de fuentes muy diferentes, por lo que no consideramos que merezca la pena el esfuerzo, ya que sólo utilizamos el estilo como ejemplo para esta visión general.

Hemos codificado los colores (no usamos QPalette) para los degradados lineales, que se usan, por ejemplo, para los biseles de los botones, las barras de herramientas y las casillas de verificación. Esto se debe a que la paleta de Java no puede producir estos colores. De todas formas, Java no cambia estos colores en función del grupo de color o rol del widget (no dependen de la paleta), por lo que no supone un problema en ningún caso.

Son los widgets de Qt los que tienen estilo. Algunos widgets no existen en absoluto en Java, por ejemplo, QToolBox. Otros contienen elementos que los widgets de Java no contienen. El widget de árbol es un ejemplo de esto último en el que el JTree de Java no tiene cabecera.

El estilo no maneja disposiciones inversas. Asumimos que la dirección de la disposición es de izquierda a derecha. QCommonStyle maneja widgets inversos; si implementáramos disposiciones inversas, los widgets que cambiamos la posición de los subelementos, o manejamos la alineación del texto en las etiquetas nosotros mismos necesitarían ser actualizados.

Estilización de las casillas de verificación de Java

Como ejemplo, examinaremos el estilo de las casillas de verificación en el estilo Java. Describimos el proceso completo e imprimimos todo el código tanto en el estilo Java como en las clases Qt implicadas. En el resto de este documento, no examinaremos el código fuente de los widgets individuales. Esperamos que esto le dé una idea de cómo buscar en el código si necesita comprobar detalles específicos de la implementación; la mayoría de los widgets siguen la misma estructura que las casillas de verificación. Hemos editado un poco el código de QCommonStyle para eliminar el código que no es directamente relevante para el estilo de las casillas de verificación.

Empezaremos viendo cómo QCheckBox construye su opción de estilo, que es QStyleOptionButton para las casillas de verificación:

    opt.initFrom(q);
    if (down)
        opt.state |= QStyle::State_Sunken;
    if (tristate && noChange)
        opt.state |= QStyle::State_NoChange;
    else
        opt.state |= checked ? QStyle::State_On : QStyle::State_Off;
    if (q->testAttribute(Qt::WA_Hover) && q->underMouse()) {
        if (hovering)
            opt.state |= QStyle::State_MouseOver;
        else
            opt.state &= ~QStyle::State_MouseOver;
    }
    opt.text = text;
    opt.icon = icon;
    opt.iconSize = q->size();

Primero dejamos que QStyleOption configure la opción con la información que es común para todos los widgets con initFrom(). Veremos esto en breve.

QStyleOptionLa variable down de es true cuando el usuario presiona la casilla hacia abajo; esto es cierto para la casilla de verificación tanto si la casilla está marcada como si no. El estado State_NoChange se establece cuando tenemos una casilla de verificación tri-estado y está parcialmente marcada. Tiene State_On si la casilla está marcada y State_Off si está desmarcada. State_MouseOver se establece si el ratón pasa por encima de la casilla de verificación y el widget tiene el atributo Qt::WA_Hover establecido - esto se establece en QStyle::polish(). Además, la opción de estilo también contiene el texto, el icono y el tamaño del icono del botón.

initFrom() configura la opción de estilo con los atributos que son comunes para todos los widgets. Imprimimos aquí su implementación:

    state = QStyle::State_None;
    if (widget->isEnabled())
        state |= QStyle::State_Enabled;
    if (widget->hasFocus())
        state |= QStyle::State_HasFocus;
    if (widget->window()->testAttribute(Qt::WA_KeyboardFocusChange))
        state |= QStyle::State_KeyboardFocusChange;
    if (widget->underMouse())
        state |= QStyle::State_MouseOver;
    if (widget->window()->isActiveWindow())
        state |= QStyle::State_Active;
#ifdef QT_KEYPAD_NAVIGATION
    if (widget->hasEditFocus())
        state |= QStyle::State_HasEditFocus;
#endif

    direction = widget->layoutDirection();
    rect = widget->rect();
    palette = widget->palette();
    fontMetrics = widget->fontMetrics();

El State_Enabled se establece cuando el widget está activado. Cuando el widget tiene foco se activa la bandera State_HasFocus. Igualmente, la bandera State_Active se establece cuando el widget es hijo de la ventana activa. State_MouseOver sólo se activará si el widget tiene activada la opción WA_HoverEnabled. Ten en cuenta que la navegación por teclado debe estar activada en Qt para que se incluya State_HasEditFocus; no se incluye por defecto.

Además de establecer las banderas de estado el QStyleOption contiene otra información sobre el widget: direction es la dirección de diseño del layout, rect es el rectángulo delimitador del widget (el área en la que dibujar), palette es el QPalette que debería usarse para dibujar el widget, y fontMetrics es la métrica de la fuente que usa el widget.

Damos una imagen de una casilla de verificación y la opción de estilo para que coincida con ella.

Casilla de verificación con estilo Java

El checkbox anterior tendrá las siguientes banderas de estado en su opción de estilo:

Bandera de estadoEstablecer
State_Sunken
State_NoChangeNo
State_On
State_OffNo
State_MouseOver
State_Enabled
State_HasFocus
State_KeyboardFocusChangeNo
State_Active

El QCheckBox se pinta en QWidget::paintEvent() con opción de estilo opt y QStylePainter p . La clase QStylePainter es una clase de conveniencia para dibujar elementos de estilo. En particular, envuelve los métodos de QStyle utilizados para pintar. La clase QCheckBox se dibuja a sí misma de la siguiente manera:

    QStylePainter p;
    QStyleOptionButton opt;
    initStyleOption(&opt);
    p.drawControl(QStyle::CE_CheckBox, opt);

QCommonStyle maneja el elemento CE_CheckBox. El QCheckBox tiene dos subelementos: SE_CheckBoxIndicator (el indicador de marcado) y SE_CheckBoxContents (el contenido, que se utiliza para la etiqueta de la casilla de verificación). QCommonStyle también implementa estos rectángulos delimitadores de los subelementos. A continuación, echaremos un vistazo al código de QCommonStyle:

    QStyleOptionButton subopt = *btn;
    subopt.rect = subElementRect(QStyle::SE_CheckBoxIndicator, btn, widget);
    drawPrimitive(QStyle::PE_IndicatorCheckBox, &subopt, p, widget);
    subopt.rect = subElementRect(QStyle::SE_CheckBoxContents, btn, widget);
    drawControl(QStyle::CE_CheckBoxLabel, &subopt, p, widget);
    if (btn->state & State_HasFocus) {
        QStyleOptionFocusRect fropt;
        fropt.QStyleOption::operator=(*btn);
        fropt.rect = subElementRect(QStyle::SE_CheckBoxFocusRect, btn, widget);
        drawPrimitive(QStyle::PE_FrameFocusRect, &fropt, p, widget);
    }

Como puede verse en el extracto de código, el estilo común obtiene los rectángulos delimitadores de los dos subelementos de CE_CheckBox, y luego los dibuja. Si la casilla de verificación tiene foco, también se dibuja el marco de foco.

El estilo Java dibuja CE_CheckBoxIndicator, mientras que QCommonStyle se encarga de CE_CheckboxLabel. Examinaremos cada implementación y empezaremos con CE_CheckBoxLabel:

    const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(opt);
    uint alignment = visualAlignment(btn->direction, Qt::AlignLeft | Qt::AlignVCenter);
    if (!styleHint(SH_UnderlineShortcut, btn, widget))
        alignment |= Qt::TextHideMnemonic;
    QPixmap pix;
    QRect textRect = btn->rect;
    if (!btn->icon.isNull()) {
        const auto dpr = p->device()->devicePixelRatio();
        pix = btn->icon.pixmap(btn->iconSize, dpr,
                                btn->state & State_Enabled ? QIcon::Normal : QIcon::Disabled);
        drawItemPixmap(p, btn->rect, alignment, pix);
        if (btn->direction == Qt::RightToLeft)
            textRect.setRight(textRect.right() - btn->iconSize.width() - 4);
        else
            textRect.setLeft(textRect.left() + btn->iconSize.width() + 4);
    }
    if (!btn->text.isEmpty()){
        drawItemText(p, textRect, alignment | Qt::TextShowMnemonic,
            btn->palette, btn->state & State_Enabled, btn->text, QPalette::WindowText);
    }

visualAlignment() ajusta la alineación del texto según la dirección del diseño. Luego dibujamos un icono si existe, y ajustamos el espacio dejado para el texto. drawItemText() dibuja el texto, teniendo en cuenta la alineación, la dirección del diseño y el mnemónico. También utiliza la paleta para dibujar el texto en el color correcto.

El dibujo de etiquetas suele ser algo complicado. Por suerte, normalmente puede ser manejado por la clase base. El estilo Java implementa su propia etiqueta de botón, ya que Java centra el contenido del botón también cuando éste tiene un icono. Puede examinar esa implementación si necesita un ejemplo de reimplementación del dibujo de etiquetas.

Ahora echaremos un vistazo a la implementación Java de CE_CheckBoxIndicator en drawControl():

        case PE_IndicatorCheckBox: {
            painter->save();
            drawButtonBackground(option, painter, true);

            if (option->state & State_Enabled &&
                option->state & State_MouseOver &&
                !(option->state & State_Sunken)) {
                painter->setPen(option->palette.color(QPalette::Button));
                QRect rect = option->rect.adjusted(1, 1, -2, -2);
                painter->drawRect(rect);
                rect = rect.adjusted(1, 1, -1, -1);
                painter->drawRect(rect);
            }

            if (option->state & State_On) {
                QImage image(":/images/checkboxchecked.png");
                painter->drawImage(option->rect.topLeft(), image);
            }
            painter->restore();
            break;

Primero guardamos el estado del pintor. Esto no siempre es necesario, pero en este caso QCommonStyle necesita que el pintor esté en el mismo estado en el que estaba cuando se llamó a PE_IndicatorCheckBox (también podríamos establecer el estado con llamadas a funciones, por supuesto). A continuación utilizamos drawButtonBackground() para dibujar el fondo del indicador de la casilla de verificación. Esta es una función de ayuda que dibuja el fondo y también el marco de los botones pulsadores y las casillas de verificación. Echamos un vistazo a esa función más abajo. A continuación comprobamos si el ratón está situado sobre la casilla de verificación. Si lo está, dibujamos el marco que tienen las casillas de verificación de Java cuando la casilla no está pulsada y el ratón está sobre ella. Puedes notar que Java no maneja cajas tri-estado, así que no lo hemos implementado.

Aquí usamos una imagen PNG para nuestro indicador. También podríamos comprobar si el widget está desactivado. Entonces tendríamos que usar otra imagen con el indicador en el color desactivado.

void JavaStyle::drawButtonBackground(const QStyleOption *option,
                                     QPainter *painter, bool isCheckbox) const
{
    QBrush buttonBrush = option->palette.button();
    bool sunken = option->state & State_Sunken;
    bool disabled = !(option->state & State_Enabled);
    bool on = option->state & State_On;

    if (!sunken && !disabled && (!on || isCheckbox))
        buttonBrush = gradientBrush(option->rect);

        painter->fillRect(option->rect, buttonBrush);

        QRect rect = option->rect.adjusted(0, 0, -1, -1);

        if (disabled)
            painter->setPen(option->palette.color(QPalette::Disabled,
                                                  QPalette::WindowText));
        else
            painter->setPen(option->palette.color(QPalette::Mid));

        painter->drawRect(rect);

        if (sunken && !disabled) {
            drawSunkenButtonShadow(painter, rect,
                   option->palette.color(QPalette::Mid),
                   option->direction == Qt::RightToLeft);
    }
}

Hemos visto como las casillas de verificación son estilizadas en el estilo Java desde el momento en que el widget recibe una petición de pintado hasta el momento en que el estilo termina de pintarse. Para conocer en detalle cómo se pinta cada widget, es necesario recorrer el código paso a paso como hemos hecho aquí. Sin embargo, normalmente es suficiente con saber qué elementos de estilo dibujan los widgets. El widget construye una opción de estilo y llama al estilo una o más veces para dibujar los elementos de estilo que lo componen. Normalmente, también es suficiente conocer los estados en los que puede estar un widget y los demás contenidos de la opción de estilo, es decir, lo que enumeramos en la siguiente sección.

Paseo por los widgets

En esta sección, examinaremos cómo se aplica el estilo a la mayoría de los widgets de Qt. Esperamos que esto te ahorre tiempo y esfuerzo a la hora de desarrollar tus propios estilos y widgets. No encontrarás aquí información que no puedas obtener en otro lugar (por ejemplo, examinando el código fuente o las descripciones de las clases relacionadas con el estilo).

Utilizamos principalmente widgets de estilo Java como ejemplos. El estilo Java no dibuja todos los elementos de los árboles de elementos. Esto se debe a que no son visibles para ese widget en el estilo Java. Aún así, nos aseguramos de que todos los elementos estén implementados de forma que se ajusten al estilo Java, ya que los widgets personalizados podrían necesitarlos (aunque esto no excluye dejar las implementaciones a QCommonStyle ).

Para cada widget se proporciona lo siguiente

  • Una tabla con los miembros (variables, etc.) de su opción de estilo.
  • Una tabla con las banderas de estado (QStyle::StateFlag) que se pueden establecer en el widget y cuándo se establecen los estados.
  • Su árbol de elementos (véase la sección Los elementos de estilo).
  • Una imagen del widget en la que se perfilan los elementos.

El árbol de elementos contiene los elementos de estilo primitivos, de control y complejos. Haciendo un recorrido descendente del árbol de elementos, se obtiene la secuencia en la que deben dibujarse los elementos. En los nodos, hemos escrito los subelementos rectángulos, los subelementos de control y las métricas de píxeles que deben tenerse en cuenta al dibujar el elemento del nodo.

Nuestro enfoque sobre el estilo se centra en el dibujo de los widgets. Los cálculos de los subelementos rectángulos, subcontroles y métricas de píxeles utilizados durante el dibujado sólo aparecen como contenidos en los árboles de elementos. Nótese que hay rectángulos y métricas de píxeles que sólo son utilizados por los widgets. Esto deja estos cálculos sin tratar en el tutorial. Por ejemplo, las funciones subControlRect() y sizeFromContents() a menudo llaman a subElementRect() para calcular sus rectángulos delimitadores. También podríamos dibujar árboles para esto. Sin embargo, la forma en que se realizan estos cálculos depende completamente de cada estilo, y no tienen por qué seguir una estructura específica (Qt no impone una estructura específica). No obstante, debes asegurarte de que utilizas la métrica de píxeles adecuada. Para limitar el tamaño del documento, hemos optado por no incluir árboles ni describir los cálculos realizados por el estilo Java (o cualquier otro).

Es posible que no esté seguro de cómo deben utilizarse las diferentes métricas de píxeles, los rectángulos de subelementos y los rectángulos de subcontrol al examinar los árboles. Si tiene dudas después de leer las descripciones del enum QStyle, le sugerimos que examine la implementación QCommonStyle.

Algunos de los rectángulos delimitadores que esbozamos en las imágenes de los widgets son iguales. Esto se debe a que algunos elementos dibujan fondos mientras que otros dibujan marcos y etiquetas. Si tienes dudas, consulta la descripción de cada elemento en QStyle. Además, algunos elementos están ahí para maquetar, es decir, decidir dónde dibujar, otros elementos.

Propiedades comunes de los widgets

Algunos estados y variables son comunes para todos los widgets. Se establecen con QStyleOption::initFrom(). No todos los elementos utilizan esta función; son los widgets los que crean las opciones de estilo, y para algunos elementos la información de initFrom() no es necesaria.

A continuación se muestra una tabla con los estados comunes:

EstadoEstado Establecer Cuando
State_EnabledSe establece si el widget no está deshabilitado (ver QWidget::setEnabled())
State_FocusSe establece si el widget tiene foco (ver QWidget::hasFocus())
State_KeyboardFocusChangeSe establece cuando el usuario cambia el foco con el teclado (ver Qt::WA_KeyboardFocusChange)
State_MouseOverEstablecer si el cursor del ratón está sobre el widget
State_ActiveEstablecer si el widget es hijo de la ventana activa.
State_HasEditFocusEstablecer si el widget tiene el foco de edición

Los otros miembros comunes para los widgets son

MiembroContenido
rectEl rectángulo del elemento a dibujar. Se establece en el rectángulo de contorno del widget (QWidget::rect()).
direcciónLa dirección del diseño; un valor del enum Qt::LayoutDirection.
paletaLa QPalette que se utilizará para dibujar el elemento. Se establece en la paleta del widget (QWidget::palette()).
fontMetricsEl QFontMetrics a utilizar al dibujar texto en el widget.

Las opciones de estilo complejo (clases que heredan de QStyleOptionComplex) utilizadas para los elementos de estilo complejo comparten dos variables: subControls y activeSubControls. Ambas variables son una combinación OR'ed de los valores del enum QStyle::SubControl. Indican de qué subcontroles se compone el control complejo y cuáles de ellos están actualmente activos.

Como se ha mencionado, el estilo calcula el tamaño del contenido del widget, a partir del cual los widgets calculan sus sugerencias de tamaño. Además, los controles complejos también utilizan el estilo para comprobar sobre qué subcontroles se encuentra el ratón.

Referencia del widget

Sin más dilación, presentamos el recorrido de los widgets; cada widget tiene su propia subsección.

Botones pulsadores

A continuación se muestra la estructura de estilos de los botones pulsadores. Haciendo un recorrido descendente del árbol, se obtiene la secuencia en la que deben dibujarse los elementos.

Árbol y elementos de estilo pulsador

La disposición de los botones, con respecto a los límites de los elementos, varía de un estilo a otro. Esto hace difícil mostrar imágenes conceptuales al respecto. Además, los elementos pueden -incluso estar destinados a- tener los mismos límites; el PE_PushButtonBevel, por ejemplo, se utiliza en QCommonStyle para dibujar los elementos que contiene: PE_FrameDefaultButton, PE_FrameButtonBevel, y PE_PanelButtonCommand, todos los cuales tienen los mismos límites en estilo común. PE_PushButtonBevel también es responsable de dibujar el indicador de menú (QCommonStyle dibuja PE_IndicatorArrowDown).

A continuación se muestra una imagen de un botón pulsador en el estilo Java que muestra los rectángulos delimitadores de los elementos. Los colores se utilizan para separar los rectángulos delimitadores en la imagen; no llenan ningún otro propósito. Lo mismo ocurre con imágenes similares para los demás widgets.

Botón etiquetado con sus elementos

El estilo Java, así como el resto de estilos implementados en Qt, no utiliza PE_FrameButtonBevel. Es habitual que un botón con PE_DefaultFrame ajuste el rectángulo de PE_PanelButtonCommand en PM_ButtonDefaultIndicator. El CE_PushButtonLabel se encuentra ajustando el rectángulo en PM_DefaultFrameWidth.

A continuación examinaremos la opción de estilo para botones pulsadores - QStyleOptionButton. A continuación se muestra una tabla con los estados que QPushButton puede establecer en la opción de estilo:

EstadoEstado Establecido Cuando
State_SunkenEl botón está pulsado o se muestra el menú pulsado
State_OnEl botón está marcado
State_RaisedEl botón no está plano y no está pulsado

Otros miembros de QStyleOptionButton son:

MiembroContenido
característicasFlags del enum QStyleOptionButton::ButtonFeatures, que describe varias propiedades de los botones (ver enum)
iconoEl botón QIcon (si existe)
iconSizeEl QSize del icono
textoun QString con el texto de los botones

Botones Check y Radio

Las estructuras de los botones de radio y de verificación son idénticas. Mostramos la estructura utilizando QCheckBox nombres de elementos y métricas de píxeles:

Árbol y elementos de estilo de casillas de verificación y radio

QStyleOptionButton se utiliza como opción de estilo tanto para los botones de verificación como para los de radio. Primero damos una tabla de los estados que se pueden establecer en la opción:

EstadoEstado Se establece cuando
State_sunkenLa casilla está pulsada
State_NoChangeLa casilla está parcialmente marcada (para casillas de verificación triestado.)
State_OnLa casilla está marcada
State_OffLa casilla está desmarcada

Consulte Botones para ver una tabla sobre otros miembros de la clase QStyleOptionButton.

Pestañas

En Qt, QTabBar utiliza el estilo para dibujar sus pestañas. Las pestañas existen ya sea en un QTabWidget, que contiene un QTabBar, o como una barra separada. Si la barra no es parte de un widget de pestaña, dibuja su propia base.

QTabBar Dispone las pestañas, por lo que el estilo no tiene control sobre la colocación de las pestañas. Sin embargo, mientras coloca sus pestañas, la barra pide al estilo PM_TabBarTabHSpace y PM_TabBarTabVSpace, que es la anchura y altura extra sobre el tamaño mínimo de la etiqueta de la pestaña de la barra de pestañas (icono y texto). El estilo también puede influir en el tamaño de la pestaña antes de que se coloque, ya que la barra de pestañas solicita CT_TabBarTab. El rectángulo delimitador de la barra lo decide el widget de la pestaña cuando forma parte del widget (sigue considerando CT_TabBarTab).

La barra de pestañas se encarga de dibujar los botones que aparecen en ella cuando no caben todas las pestañas. Su colocación no está controlada por el estilo, pero los botones son QToolButtons y por lo tanto son dibujados por el estilo.

Esta es la estructura de estilos para QTabWidget y QTabBar:

Árbol de estilos y elementos del widget de pestañas y de la barra de pestañas

Las líneas punteadas indican que QTabWidget contiene una barra de pestañas, pero no dibuja la barra de pestañas en sí. QTabBar sólo dibuja su línea base cuando no forma parte de un widget de pestañas, y mantiene dos botones de herramientas que desplazan la barra cuando no caben todas las pestañas; véase Botones de herramientas para su árbol de elementos. Observe también que como los botones son hijos de la barra de pestañas, se dibujan después de la barra. Los rectángulos que delimitan las pestañas se solapan con la base en PM_TabBarBaseOverlap.

Aquí se muestra un widget de pestaña en el estilo Java:

Widget de pestañas etiquetado con sus elementos

En el estilo Java, la forma de la barra de pestañas y la etiqueta tienen el mismo rectángulo delimitador que CE_TabBarTab. Observe que las pestañas se solapan con el marco del widget de pestañas. La base de la barra de pestañas (si está dibujada) es el área donde se superponen las pestañas y el marco.

La opción de estilo para pestañas (QStyleOptionTab) contiene la información necesaria para dibujar pestañas. La opción contiene la posición de la pestaña en la barra de pestañas, la posición de la pestaña seleccionada, la forma de la pestaña, el texto, el icono y el tamaño del icono.

Como las pestañas del estilo Java no se solapan, también presentamos una imagen de un widget de pestaña del estilo común. Tenga en cuenta que si desea que las pestañas se solapen horizontalmente, debe hacerlo cuando dibuje las pestañas en CE_TabBarTabShape; los rectángulos delimitadores de las pestañas no se verán alterados por la barra de pestañas. Las pestañas se dibujan de izquierda a derecha en forma de barra de pestañas norte, de arriba abajo en forma de barra de pestañas este, etc. La pestaña seleccionada se dibuja en último lugar, para que sea fácil dibujarla sobre las demás pestañas (si se quiere que sea más grande).

Barra de pestañas etiquetada con sus elementos

A continuación se muestra una tabla de los estados que una barra de pestañas puede establecer en sus pestañas:

EstadoEstado Establecido Cuando
State_SunkenSe pulsa la pestaña con el ratón.
State_SelectedSi es la pestaña actual.
State_HasFocusLa barra de pestañas tiene el foco y la pestaña está seleccionada.

Tenga en cuenta que las pestañas individuales pueden estar desactivadas aunque la barra de pestañas no lo esté. La pestaña estará activa si la barra de pestañas está activa.

A continuación se muestra una tabla con los miembros de QStyleOptionTab:

MiembroContenido
cornerWidgetsFlags del enum CornerWidget, que indican si la barra de pestañas tiene widgets de esquina y cuáles son.
iconoEl QIcon de la pestaña.
iconSizeEl QSize del icono.
positionUn valor enum TabPosition que indica la posición de la pestaña en la barra con respecto a las demás pestañas.
filaIndica en qué fila se encuentra la pestaña.
selectedPositionUn valor del enum SelectedPosition que indica si la pestaña seleccionada es adyacente o es la pestaña.
shapeUn valor del enum QTabBar::Shape que indica si la pestaña tiene esquinas redondeadas o triangulares y la orientación de la pestaña.
textoEl texto de la pestaña.

El marco de los widgets de pestaña utiliza QStyleOptionTabWidgetFrame como opción de estilo. Enumeramos aquí sus miembros. No tiene estados establecidos además de las banderas comunes.

Miembrocontenido
leftCornerWidgetSizeEl QSize del widget de la esquina izquierda (si existe).
rightCornerWidgetSizeQSize del widget de la esquina derecha (si existe).
lineWidthMantiene la línea con para dibujar el panel.
midLineWithActualmente este valor es siempre 0.
formaLa forma de las pestañas de la barra de pestañas.
tabBarSizeEl QSize de la barra de pestañas.

Barras de desplazamiento

Esta es la estructura de estilo para las barras de desplazamiento:

Árbol y elementos del estilo de la barra de desplazamiento

QScrollBar simplemente crea su opción de estilo y luego dibuja CC_ScrollBar. Algunos estilos dibujan el fondo de añadir página y subpágina con PE_PanelButtonBevel, y también usan flechas indicadoras para dibujar las flechas en los indicadores de línea siguiente y anterior; no hemos incluido estos en el árbol ya que su uso depende de cada estilo. El estilo PM_MaximumDragDistance es la distancia máxima en píxeles que el ratón puede moverse desde los límites de la barra de desplazamiento y aún así mover el manejador.

A continuación se muestra una imagen de una barra de desplazamiento en el estilo Java:

Barra de desplazamiento etiquetada con sus elementos

Puedes notar que la barra de desplazamiento es ligeramente diferente de la de Java, ya que tiene dos indicadores de alineación. Hemos hecho esto para mostrar que se pueden tener dos rectángulos delimitadores separados para un único subcontrol. La barra de desplazamiento es un ejemplo de widget totalmente implementado por el estilo Java - QCommonStyle no interviene en el dibujo.

Echemos un vistazo a los diferentes estados que una barra de desplazamiento puede establecer en la opción de estilo:

EstadoEstado establecido cuando
State_HorizontalLa barra de desplazamiento es horizontal.

La opción de estilo de QScrollBar es QStyleOptionSlider. Sus miembros se enumeran en la tabla siguiente. La opción es utilizada por todos los QAbstractSliders; aquí sólo describimos los miembros relevantes para las barras de desplazamiento.

MiembroContenido
máximoValor máximo de la barra de desplazamiento.
mínimoEl valor mínimo de la barra de desplazamiento.
notchTargetEl número de píxeles entre muescas.
orientaciónUn valor del enum Qt::Orientation que especifica si la barra de desplazamiento es vertical u horizontal.
pageStepEl número por el que aumentar o disminuir el valor de la barra deslizante (en relación con el tamaño de la barra y su rango de valores) en pasos de página.
singleStepEl número en el que se incrementa o disminuye el valor del deslizador en pasos simples (o de línea).
sliderValueEl valor del deslizador.
sliderPositionLa posición del control deslizante. Es la misma que sliderValue si la barra de desplazamiento es QAbstractSlider::tracking. En caso contrario, la barra de desplazamiento no actualiza su valor antes de que el ratón suelte el tirador.
upsideDownIndica la dirección en la que la barra de desplazamiento aumenta su valor. Se utiliza en lugar de QStyleOption::direction para todos los deslizadores abstractos.

Deslizadores

Cuando se calcula la sugerencia de tamaño del deslizador, PM_SliderThickness y PM_SliderLength se consultan desde el estilo. Al igual que con las barras de desplazamiento, QSlider sólo permite al usuario mover el manejador si el ratón está dentro de PM_MaximumDragDistance de los límites del deslizador. Cuando se dibuja, se crea la opción de estilo y se llama a drawComplexControl() con CC_Slider:

Árbol y elementos de estilo deslizante

También mostramos una imagen de un deslizador en el estilo Java. Mostramos los rectángulos delimitadores de los subelementos, ya que todo el dibujo se realiza en CC_Slider.

Deslizador etiquetado con sus elementos

QSlider utiliza QStyleOptionSlider como todos los QAbstractSliders. Presentamos una tabla con los miembros que afectan a QSlider:

MiembroContenido
máximoEl valor máximo del deslizador.
mínimoEl valor mínimo del deslizador.
notchTargetEs el número de píxeles entre cada muesca.
orientaciónUn valor enum Qt::Orientation que indica si el deslizador es vertical u horizontal.
pageStepEl número por el que aumentar o disminuir el valor del deslizador en pasos de página.
singleStepNúmero con el que se aumenta o disminuye el valor del control deslizante en pasos individuales (o de línea).
sliderValueValor del control deslizante.
sliderPositionLa posición del deslizador dada como valor del deslizador. Será igual a sliderValue si el deslizador es tracking; si no, el valor del deslizador no cambiará hasta que se suelte el mando con el ratón.
upsideDownEste miembro se utiliza en lugar de QStyleOption::direction para todos los deslizadores abstractos.

Debe tener en cuenta que el deslizador no utiliza la dirección para los diseños invertidos; utiliza upsideDown.

Cajas giratorias

Cuando QSpinBox se pinta, crea un QStyleOptionSpinBox y pide al estilo que dibuje CC_SpinBox. El campo de edición es una línea de edición hija de la caja de giro. Las dimensiones del campo son calculadas por el estilo con SC_SpinBoxEditField.

A continuación se muestra el árbol de estilos para las cajas de giro. No es necesario que un estilo utilice la primitiva botonera para pintar los fondos de los indicadores. Puedes ver una imagen debajo del árbol mostrando los subelementos en QSpinBox en el estilo Java.

Árbol y elementos de estilo Spin Box

Caja giratoria etiquetada con sus elementos

El QStyleOptionSpinBox, que es la opción de estilo para las cajas de giro. Puede establecer los siguientes estados en la caja de giro:

EstadoEstado Se establece cuando
State_SunkenSe establece si uno de los subcontroles CC_SpinUp o CC_SpinDown se pulsa con el ratón.

El resto de los miembros de las opciones de estilo de la caja giratoria son:

PropiedadFunción
marcoBooleano que es true si la caja de giro debe dibujar un marco.
buttonSymbolsValor del enum ButtonSymbols que decide el símbolo de los botones arriba/abajo.
stepEnabledValor del enum StepEnabled que indica cuáles de los botones de la caja de giro están pulsados.

Barra de título

El control complejo de la barra de título, CC_TitleBar, se utiliza para dibujar las barras de título de las ventanas internas en QMdiArea. Normalmente consta de un título de ventana y botones de cerrar, minimizar, menú de sistema y maximizar. Algunos estilos también proporcionan botones para sombrear la ventana, así como un botón para la ayuda contextual.

La barra se dibuja en CC_TitleBar sin utilizar ningún subelemento. La forma en que los estilos individuales dibujan sus botones depende de ellos, pero hay mapas de píxeles estándar para los botones que el estilo debe proporcionar.

Árbol de estilos y elementos de la barra de título

En una imagen sobre una barra de título en el estilo Java, mostramos los rectángulos delimitadores de los subelementos soportados por el estilo Java (todos los cuales se dibujan con pixmaps estándar). Es habitual dibujar los fondos de los botones utilizando PE_PanelButtonTool, pero no es obligatorio.

Barra de título etiquetada con sus elementos

La opción de estilo para las barras de título es QStyleOptionTitleBar. Sus miembros son:

MiembroContenido
iconoEl icono de la barra de título.
textoEl texto de la etiqueta de la barra de título.
windowFlagsBanderas del enum Qt::WindowFlag. Las banderas de ventana utilizadas por QMdiArea para la gestión de ventanas.
titleBarStateEs el QWidget::windowState() de la ventana que contiene la barra de título.

Cuadro combinado

Un QComboBox utiliza el estilo para dibujar el botón y la etiqueta de los cuadros no editables con CC_ComboBox y CE_ComboBoxLabel.

La lista que aparece cuando el usuario hace clic en el cuadro combinado es dibujada por un delegado, que no cubrimos en este resumen. Sin embargo, puedes utilizar el estilo para controlar el tamaño y la posición de la lista con el subelemento SC_ComboBoxListBoxPopup. El estilo también decide dónde debe estar el campo de edición de los cuadros editables con SC_ComboBoxEditField; el propio campo es un QLineEdit hijo del cuadro combinado.

Árbol y elementos del estilo de los cuadros combinados

Mostramos una imagen sobre un cuadro combinado de estilo Java en la que hemos delineado sus subelementos y rectángulos de subelementos:

Cuadro combinado etiquetado con sus elementos

Los cuadros combinados Java no utilizan el rectángulo de foco; cambia su color de fondo cuando tiene foco. El campo SC_ComboBoxEdit es utilizado tanto por QComboBox para calcular el tamaño del campo de edición como por el estilo para calcular el tamaño de la etiqueta del cuadro combinado.

La opción de estilo para los cuadros combinados es QStyleOptionComboBox. Puede establecer los siguientes estados:

EstadoEstablecer cuando
State_SelectedEl cuadro no es editable y tiene foco.
State_SunkenSC_ComboBoxArrow está activo.
State_onEl contenedor (lista) del cuadro es visible.

Las opciones de estilo otros miembros son:

MiembroContenido
currentIconEl icono del elemento actual (seleccionado) del cuadro combinado.
currentTextEl texto del elemento actual del cuadro.
editableIndica si el cuadro combinado es editable o no.
marcoIndica si el cuadro combinado tiene marco o no.
iconSizeEl tamaño del icono del ítem actual.
popupRectEl rectángulo que delimita la lista desplegable del cuadro combinado.

Cuadros de grupo

Al calcular la sugerencia de tamaño, QGroupBox obtiene tres métricas de píxeles del estilo: PM_IndicatorWidth, PM_CheckBoxLabelSpacing, y PM_IndicatorHeight. QGroupBox tiene el siguiente árbol de elementos de estilo:

Árbol y elementos de estilo de caja de grupo

Qt no impone restricciones sobre cómo se dibuja la casilla de verificación; el estilo Java la dibuja con CE_IndicatorCheckBox. Ver Check and Radio Buttons para el árbol completo.

También damos una imagen del widget con los subcontroles y rectángulos de subcontrol dibujados:

Caja de grupo etiquetada con sus elementos

La opción de estilo para las cajas de grupo es QStyleOptionGroupBox. En ella se pueden establecer los siguientes estados:

EstadoEstablecer Cuando
State_OnLa casilla de verificación está marcada.
State_SunkenLa casilla de verificación está pulsada.
State_OffLa casilla de verificación está desmarcada (o no hay casilla de verificación).

Los demás miembros de QStyleOptionGroupBox son:

MiembroContenido
característicasBanderas del enum QStyleOptionFrame::FrameFeatures que describen el marco del cuadro de grupo.
lineWidthEl ancho de línea con el que se dibujará el panel. Siempre es 1.
textoEl texto del cuadro de grupo.
textAlignmentLa alineación del título del cuadro de grupo.
textColorEl QColor del texto.

Divisores

Como la estructura de los divisores es simple y no contiene ningún subelemento, no incluimos ninguna imagen de los divisores. CE_Splitter no utiliza ningún otro elemento o métrica.

Para su opción de estilo, el divisor utiliza la clase base QStyleOption. Puede establecer las siguientes banderas de estado en él:

EstadoEstablecer Cuando
State_HorizontalSe establece si es un divisor horizontal.

QSplitter no utiliza initFrom() para establecer su opción; establece las banderas State_MouseOver y State_Disabled por sí mismo.

Barra de progreso

El elemento CE_ProgressBar es utilizado por QProgressBar, y es el único elemento utilizado por este widget. Comenzamos con la estructura de estilo:

Árbol y elementos de la barra de progreso

Aquí tenemos una barra de progreso en el estilo común (los rectángulos delimitadores del estilo Java son iguales):

Barra de progreso etiquetada con sus elementos

La opción de estilo para QProgressBar es QStyleOptionProgressBar. La barra no establece ninguna bandera de estado, pero los otros miembros de la opción sí:

MiembroContenido
mínimoEl valor mínimo de la barra.
máximoEl valor máximo de la barra.
progresoEl valor actual de la barra.
textAlignmentCómo se alinea el texto en la etiqueta.
textVisibleSi se dibuja la etiqueta.
textEl texto de la etiqueta.
orientaciónLas barras de progreso pueden ser verticales u horizontales.
aparienciainvertidaEl progreso está invertido (es decir, de derecha a izquierda en una barra horizontal).
bottomToTopBooleano que, si true, gira 90 grados la etiqueta de las barras de progreso verticales.

Botones de herramientas

Los botones de herramientas existen independientemente o como parte de las barras de herramientas. Se dibujan igual de cualquier forma. El QToolButton sólo dibuja un elemento de estilo: CC_ToolButton.

A continuación se muestra un árbol de la estructura de estilos del widget:

Árbol de estilos y elementos de los botones de herramientas

Observe que PE_FrameButtonTool y PE_IndicatorArrowDown están incluidos en el árbol ya que el estilo Java los dibuja, pero pueden omitirse sin problemas si lo prefiere. La estructura también puede ser diferente. QCommonStyle El estilo Java, por ejemplo, dibuja PE_IndicatorButtonDropDown y PE_IndicatorArrowDown en CE_ToolButton.

También tenemos una imagen de un botón de herramienta en la que hemos delineado los rectángulos delimitadores de los subelementos y los subcontroles.

Botón de herramienta etiquetado con sus elementos

Esta es la tabla de estados para los botones de herramientas:

EstadoEstablecer Cuando
State_AutoRiseEl botón de herramienta tiene activada la propiedad autoRise.
State_RaisedEl botón no está hundido (es decir, al ser marcado o pulsado con el ratón).
State_SunkenEl botón está hundido.
State_OnEl botón es comprobable y está marcado.

QStyleOptionToolButton también contiene los siguientes miembros:

MiembroContenido
arrowTypeUn valor enum Qt::ArrowType, que contiene la dirección de la flecha del botón (si se va a utilizar una flecha en lugar de un icono).
featuresFlags del enum QStyleOptionToolButton::ButtonFeature que describen si el botón tiene una flecha, un menú, y/o tiene un popup-delay.
fuenteEl QFont de la etiqueta del botón.
iconoEl QIcon del botón de la herramienta.
iconSizeEl tamaño del icono del botón.
posLa posición del botón, dada por QWidget::pos()
textEl texto del botón.
toolButtonStyleUn valor enum Qt::ToolButtonStyle que decide si el botón muestra el icono, el texto o ambos.

Barras de herramientas

Las barras de herramientas forman parte de main window framework, y cooperan con el QMainWindow al que pertenecen mientras construye su opción de estilo. Una ventana principal tiene 4 áreas en las que se pueden colocar barras de herramientas. Se sitúan junto a los cuatro lados de la ventana (es decir, norte, sur, este y oeste). Dentro de cada área puede haber más de una línea de barras de herramientas; una línea consiste en barras de herramientas con la misma orientación (vertical u horizontal) colocadas una al lado de la otra.

Toolbars en Qt constan de tres elementos: CE_ToolBar QMainWindowLayout , PE_IndicatorToolBarHandle, y PE_IndicatorToolBarSeparator. Es QMainWindowLayout el que calcula los rectángulos delimitadores (es decir, la posición y el tamaño de las barras de herramientas y su contenido. La ventana principal también utiliza el sizeHint() de los elementos de las barras de herramientas cuando calcula el tamaño de las barras.

He aquí el árbol de elementos de QToolBar:

Árbol de estilos y elementos de la barra de herramientas

Las líneas punteadas indican que QToolBar mantiene una instancia de QToolBarLayout y que QToolBarSeparators son mantenidos por QToolBarLayout. Cuando la barra de herramientas es flotante (es decir, tiene su propia ventana) se dibuja el elemento PE_FrameMenu, de lo contrario QToolBar dibuja CE_ToolBar.

A continuación se muestra una imagen de una barra de herramientas al estilo Java:

Barra de herramientas etiquetada con sus elementos

QToolBarSaparator utiliza QStyleOption para su opción de estilo. Establece la bandera State_Horizontal si la barra de herramientas en la que se encuentra es horizontal. Fuera de eso, usa initFrom().

La opción de estilo para QToolBar es QStyleOptionToolBar. La única bandera de estado establecida (además de las banderas comunes) es State_Horizontal si la barra es horizontal (es decir, en el área norte o sur de la barra de herramientas). Las variables miembro de la opción de estilo son

MiembroContenido
característicasMantiene si la barra es movible en un valor de la ToolBarFeature, que es Movable o None.
lineWidthEl ancho del marco de la barra de herramientas.
midLineWidthEsta variable no se utiliza actualmente y es siempre 0.
positionOfLinePosición de la línea de la barra de herramientas dentro del área de la barra de herramientas a la que pertenece.
positionWithinLinePosición de la barra de herramientas dentro de la línea a la que pertenece.
toolBarAreaEl área de la barra de herramientas en la que se encuentra la barra de herramientas.

Los menús en Qt se implementan en QMenu. QMenu mantiene una lista de acciones, que dibuja como elementos de menú. Cuando QMenu recibe eventos de pintura, calcula el tamaño de cada elemento de menú y los dibuja individualmente con CE_MenuItem. Los elementos del menú no tienen un elemento separado para su etiqueta (contenido), por lo que todo el dibujo se realiza en CE_MenuItem. El menú también dibuja el marco del menú con PE_FrameMenu. También dibuja CE_MenuScroller si el estilo admite el desplazamiento. CE_MenuTearOff se dibuja si el menú es demasiado grande para su rectángulo delimitador.

En el árbol de estructura de estilos, también incluimos QMenu, ya que también realiza tareas relacionadas con el estilo. Los rectángulos delimitadores de los elementos del menú se calculan para la sugerencia de tamaño del menú y cuando el menú se muestra o cambia de tamaño.

Árbol de estilos y elementos del menú

Los elementos CE_MenuScroller y CE_MenuTearOff son manejados por QCommonStyle y no se muestran a menos que el menú sea demasiado grande para caber en la pantalla. PE_FrameMenu sólo se dibuja para los menús emergentes.

QMenu calcula rectángulos basándose en sus acciones y llama a CE_MenuItem y CE_MenuScroller si el estilo lo admite.

También es habitual usar PE_IndicatorCheckBox (en lugar de usar PE_IndicatorMenuCheckMark) y PE_IndicatorRadioButton para dibujar elementos de menú comprobables; no los hemos incluido en el árbol de estilos porque esto es opcional y varía de un estilo a otro.

Menú etiquetado con sus elementos

La opción de estilo para los elementos de menú es QStyleOptionMenuItem. Las siguientes tablas describen sus banderas de estado y otros miembros.

EstadoEstablecer Cuando
State_SelectedEl ratón está sobre la acción y ésta no es un separador.
State_SunkenEl ratón está pulsado sobre el elemento de menú.
State_DownArrowSe establece si el elemento de menú es un desplazador de menú y desplaza el menú hacia abajo.
MiembroContenido
checkTypeUn valor del enum CheckType, que puede ser NotCheckable, Exclusive o NonExclusive.
comprobadoBooleano que es true si el elemento de menú está marcado.
fuenteLa fuente QFont que se utilizará para el texto del elemento de menú.
iconoEl QIcon del elemento de menú.
maxIconWidthLa anchura máxima permitida para el icono.
menuHasCheckableItemsBooleano que es true si al menos un elemento del menú es comprobable.
menuItemTypeTipo del elemento del menú. Se trata de un valor de MenuItemType.
menuRectEl rectángulo que delimita la página QMenu en la que se encuentra el elemento de menú.
tabWidthDistancia entre el texto del elemento de menú y el acceso directo.
textoEl texto del elemento de menú.

La configuración de la opción de estilo para CE_MenuTearOff y CE_MenuScroller también utiliza QStyleOptionMenuItem; sólo establecen la variable menuRect además de los ajustes comunes con QStyleOption's initFrom().

QMenuBar utiliza el estilo para dibujar cada elemento de la barra de menús y el área vacía de la barra de menús. Los propios menús desplegables son QMenus (véase Menús). A continuación se muestra el árbol de elementos de estilo para la barra de menús:

Árbol de estilo y elementos de la barra de menús

El panel y el área vacía se dibujan después de los elementos del menú. El QPainter que QMenuBar envía al estilo tiene los rectángulos delimitadores de los elementos recortados (es decir, la región de recorte), por lo que no tiene que preocuparse de dibujar sobre los elementos. La métrica de píxeles en QMenuBar se utiliza cuando se calculan los rectángulos delimitadores de los elementos de la barra de menú.

Barra de menús etiquetada con sus elementos

QStyleOptionMenuItem se utiliza para los elementos de la barra de menú. Los miembros utilizados por QMenuBar se describen en la siguiente tabla:

MiembroContenido
menuRectEl rectángulo que delimita toda la barra de menús a la que pertenece el elemento.
textoEl texto del elemento.
iconoEl icono del elemento de menú (no es habitual que los estilos dibujen este icono).

QStyleOptionMenuItem también se utiliza para dibujar CE_EmptyMenuBarArea.

QStyleOptionFrame se utiliza para dibujar el marco del panel. El lineWidth se establece en PM_MenuBarPanelWidth. El midLineWidth actualmente siempre se establece en 0.

Encabezados de la vista de elementos

Es el estilo que dibuja las cabeceras de las vistas de elementos de Qt. Las vistas de ítems mantienen las dimensiones en secciones individuales. También hay que tener en cuenta que los delegados pueden usar el estilo para pintar decoraciones y marcos alrededor de los ítems. QItemDelegate Por ejemplo, dibuja PE_FrameFocusRect y PE_IndicatorItemViewItemCheck.

Árbol de estilos y elementos de la cabecera

He aquí un QTableWidget que muestra los recuadros delimitadores de una cabecera Java:

Cabecera etiquetada con sus elementos

QHeaderView utiliza CT_HeaderSection, PM_HeaderMargin y PM_HeaderGripMargin para los cálculos de tamaño y prueba de acierto. El PM_HeaderMarkSize no es utilizado actualmente por Qt. QTableView dibuja el botón en la esquina superior izquierda (es decir, el área donde las cabeceras vertical y horizontal se cruzan) como un CE_Header.

La opción de estilo para las vistas de cabecera es QStyleOptionHeader. La vista pinta una sección de cabecera a la vez, por lo que los datos corresponden a la sección que se está dibujando. Su contenido es:

MiembroContenido
iconoEl icono de la cabecera (para la sección que se está dibujando).
iconAlignmentLa alineación (Qt::Alignment) del icono en la cabecera.
orientaciónUn valor de Qt::Orientation que decide si la cabecera es la cabecera horizontal sobre la vista o la cabecera vertical a la izquierda.
positionUn valor de QStyleOptionHeader::SectionPosition que indica la posición de la sección de cabecera con respecto a las demás secciones.
secciónContiene la sección que se está dibujando.
selectedPositionUn valor de QStyleOptionHeader::SelectedPosition que indica la posición de la sección seleccionada con respecto a la sección que se está pintando.
sortIndicatorUn valor de QStyleOptionHeader::SortIndicator que describe la dirección en la que debe dibujarse el indicador de ordenación de la sección.
textoEl texto de la sección actualmente dibujada.
textAlignmentEl Qt::Alignment del texto dentro de la sección de cabecera.

Indicadores de rama de árbol

Los indicadores de rama en una vista de árbol son dibujados por el estilo con PE_IndicatorBranch. Pensamos en los indicadores aquí como los indicadores que describen la relación de los nodos en el árbol. El genérico QStyleOption se envía al estilo para dibujar estos elementos. Los distintos tipos de ramas se describen mediante estados. Como no existe una opción de estilo específica, nos limitamos a presentar la tabla de estados:

EstadoEstablecer cuando
State_SiblingEl nodo del árbol tiene un hermano (es decir, hay otro nodo en la misma columna).
State_ItemEste indicador de rama tiene un elemento.
State_ChildrenLa rama tiene hijos (es decir, se puede abrir un nuevo subárbol en la rama).
State_OpenEl indicador de rama tiene un subárbol abierto.

La vista de árbol (y el widget de árbol) utilizan el estilo para dibujar las ramas (nodos) del árbol.

QStyleOption se utiliza como el estilo para PE_IndicatorBranch tiene banderas de estado establecidos en función de qué tipo de rama es.

Dado que no existe una estructura de árbol para los indicadores de rama, sólo presentamos una imagen de un árbol en el estilo Java. Cada estado está marcado en la imagen con un rectángulo de un color específico (es decir, los rectángulos no son rectángulos delimitadores). Todas las combinaciones de estados que debe conocer están representadas en la imagen.

Estructura del estilo del indicador de rama y estados de dibujo

Cajas de herramientas

PM_SmallIconSize para sizeHints.

QToolBox es un contenedor que guarda una colección de widgets. Tiene una pestaña para cada widget y muestra uno de ellos a la vez. La caja de herramientas dispone los componentes que muestra (los botones de la caja de herramientas y el widget seleccionado) en un QVBoxLayout. El árbol de estilos de las cajas de herramientas tiene este aspecto:

Árbol de estilos y elementos de la caja de herramientas

Mostramos una imagen de una caja de herramientas en el estilo Plastique:

Caja de herramientas etiquetada con sus elementos

Todos los elementos tienen los mismos rectángulos delimitadores en el estilo Plastique así como en los otros estilos Qt incorporados.

La opción de estilo para las cajas de herramientas es QStyleOptionToolBox. Contiene el texto y el icono del contenido de la caja de herramientas. El único estado establecido por QToolBox es State_Sunken, que se establece cuando el usuario pulsa una pestaña con el ratón. El resto de los miembros de QStyleOptionToolBox son:

MiembroContenido
iconoEl icono de la pestaña de la caja de herramientas.
textoEl texto de la pestaña de la caja de herramientas.

Pinza de tamaño

El agarre de tamaño calcula su sugerencia de tamaño con CT_SizeGrip. La métrica de píxeles PM_SizeGripSize no es utilizada actualmente por Qt. El árbol de elementos para una imagen en el estilo Plastique de QSizeGrip es el siguiente:

Árbol de estilos y elementos de agarre

Agarre de tamaño etiquetado con sus elementos

Mostramos el agarre de tamaño en la esquina inferior derecha de QMainWindow.

La opción de estilo de agarre de tamaño, QStyleOptionSizeGrip, tiene un miembro además de los miembros comunes de QStyleOption:

MiembroContenido
esquinaUn valor de Qt::Corner que describe en qué esquina de una ventana (o equivalente) se encuentra el agarre.

Banda elástica

El árbol de estilos de QRubberBand consta de dos nodos.

Árbol estilo banda elástica y sus elementos

Presentamos una imagen de una ventana de estilo Java siendo movida en un QMdiArea con una banda elástica:

Goma elástica etiquetada con sus elementos

La opción de estilo para las bandas elásticas es QStyleOptionRubberBand. Sus miembros son:

MiembroContenido
opacoBooleano que es true si la banda elástica debe ser dibujada en un estilo opaco (es decir, de color).
formaUn valor enum QRubberBand::Shape que contiene la forma de la banda (que puede ser un rectángulo o una línea).

Widgets acoplables

Cuando el widget acoplable despliega su contenido, pregunta al estilo por estas métricas de píxeles: PM_DockWidgetSeparatorExtent, PM_DockWidgetTitleBarButtonMargin, PM_DockWidgetFrameWidth, y PM_DockWidgetTitleMargin. También calcula los rectángulos delimitadores de los botones flotar y cerrar con SE_DockWidgetCloseButton y SE_DockWidgetFloatButton.

Árbol de estilos y elementos del widget Dock

Las líneas de puntos indican que el remitente mantiene instancias del destinatario de la flecha (es decir, no es un elemento de estilo a dibujar). El widget de acoplamiento sólo dibuja PE_frameDockWidget cuando está desacoplado de su ventana principal (es decir, es una ventana de nivel superior). Si está acoplado, dibuja el indicador de cambio de tamaño del widget acoplable. Mostramos un widget dock tanto en estado acoplado como flotante en el estilo plastique:

Widget del muelle etiquetado con sus elementos

La opción de estilo es QStyleOptionDockWidget:

MiembroContenido
cerrableBooleano que indica si la ventana acoplable puede cerrarse.
flotableBooleano que indica si la ventana acoplable puede flotar (es decir, separarse de la ventana principal en la que se encuentra).
movibleBooleano que indica si la ventana es movible (es decir, se puede mover a otras áreas del widget del dock).
títuloTexto del título de la ventana acoplable.

Para los botones, se utiliza QStyleOptionButton (véase Botones de herramientas para una descripción del contenido). El manejador de redimensionamiento del widget dock tiene un QStyleOption plano.

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