En esta página

Ejemplo de indicadores de ventana

El ejemplo Window Flags muestra cómo utilizar los indicadores de ventana disponibles en Qt.

Un indicador de ventana puede ser un tipo o una sugerencia. Un tipo se utiliza para especificar varias propiedades del sistema de ventanas para el widget. Un widget sólo puede tener un tipo, y el predeterminado es Qt::Widget. Sin embargo, un widget puede tener cero o más sugerencias. Las sugerencias se utilizan para personalizar la apariencia de las ventanas de nivel superior.

Los indicadores de un widget se almacenan en un tipo Qt::WindowFlags que almacena una combinación OR de los indicadores.

Ventana del controlador y ventana de vista previa

Captura de pantalla del ejemplo Banderas de ventana

El ejemplo consta de dos clases:

  • ControllerWindow es el widget principal de la aplicación que permite al usuario elegir entre los indicadores de ventana disponibles, y muestra el efecto en una ventana de vista previa separada.
  • PreviewWindow es un widget personalizado que muestra el nombre de sus banderas de ventana actualmente configuradas en un editor de texto de sólo lectura.

Empezaremos revisando la clase ControllerWindow, después echaremos un vistazo a la clase PreviewWindow.

Definición de la clase ControllerWindow

class ControllerWindow : public QWidget
{
    Q_OBJECT

public:
    ControllerWindow(QWidget *parent = nullptr);

private slots:
    void updatePreview();

private:
    void createTypeGroupBox();
    void createHintsGroupBox();
    QCheckBox *createCheckBox(const QString &text);
    QRadioButton *createRadioButton(const QString &text);

    PreviewWindow *previewWindow;

    QGroupBox *typeGroupBox;
    QGroupBox *hintsGroupBox;
    QPushButton *quitButton;

    QRadioButton *windowRadioButton;
    QRadioButton *dialogRadioButton;
    QRadioButton *sheetRadioButton;
    QRadioButton *drawerRadioButton;
    QRadioButton *popupRadioButton;
    QRadioButton *toolRadioButton;
    QRadioButton *toolTipRadioButton;
    QRadioButton *splashScreenRadioButton;

    QCheckBox *msWindowsFixedSizeDialogCheckBox;
    QCheckBox *x11BypassWindowManagerCheckBox;
    QCheckBox *framelessWindowCheckBox;
    QCheckBox *windowNoShadowCheckBox;
    QCheckBox *windowTitleCheckBox;
    QCheckBox *windowSystemMenuCheckBox;
    QCheckBox *windowMinimizeButtonCheckBox;
    QCheckBox *windowMaximizeButtonCheckBox;
    QCheckBox *windowCloseButtonCheckBox;
    QCheckBox *windowContextHelpButtonCheckBox;
    QCheckBox *windowShadeButtonCheckBox;
    QCheckBox *windowStaysOnTopCheckBox;
    QCheckBox *windowStaysOnBottomCheckBox;
    QCheckBox *customizeWindowHintCheckBox;
};

La clase ControllerWindow hereda de QWidget. El widget permite al usuario elegir entre las banderas de ventana disponibles, y muestra el efecto en una ventana de previsualización separada.

Declaramos una ranura privada updatePreview() para refrescar la ventana de previsualización cada vez que el usuario cambia los indicadores de ventana.

También declaramos varias funciones privadas para simplificar el constructor: Llamamos a la función createTypeGroupBox() para crear un botón de opción para cada tipo de ventana disponible, utilizando la función privada createButton(), y los reunimos dentro de un cuadro de grupo. De forma similar utilizamos la función createHintsGroupBox() para crear una casilla de verificación para cada pista disponible, utilizando la función privada createCheckBox().

Además de los distintos botones de opción y casillas de verificación, necesitamos un PreviewWindow asociado para mostrar el efecto de los indicadores de ventana elegidos en ese momento.

Ventana del controlador con los diferentes tipos de banderas y sugerencias

Implementación de la clase ControllerWindow

ControladorWindow::ControladorWindow(QWidget *parent) : QWidget(parent) { previewWindow = new PreviewWindow(this); createTypeGroupBox(); createHintsGroupBox(); quitButton = new QPushButton(tr("&Salir")); connect(quitButton, &QPushButton::pulsado,            qApp, &QCoreApplication::quit);

    QHBoxLayout *bottomLayout = nuevo QHBoxLayoutbottomLayout->addStretch();  bottomLayout->addWidget(quitButton);    QHBoxLayout *mainLayout = nuevo QHBoxLayoutmainLayout->addWidget(typeGroupBox);  mainLayout->addWidget(hintsGroupBox);  mainLayout->addLayout(bottomLayout); setLayout(mainLayout); setWindowTitle(tr("Window Flags")); updatePreview(); }

En el constructor creamos primero la ventana de previsualización. Después creamos los cuadros de grupo que contienen las banderas de ventana disponibles utilizando las funciones privadas createTypeGroupBox() y createHintsGroupBox(). Además creamos un botón Quit. Colocamos el botón y un espacio estirable en un diseño separado para hacer que el botón aparezca en la esquina inferior derecha del widget WindowFlag.

Por último, añadimos el diseño del botón y las dos cajas de grupo a QVBoxLayout, establecemos el título de la ventana y refrescamos la ventana de vista previa utilizando la ranura updatePreview().

void ControllerWindow::updatePreview()
{
    Qt::WindowFlags flags;

    if (windowRadioButton->isChecked())
        flags = Qt::Window;
    else if (dialogRadioButton->isChecked())
        flags = Qt::Dialog;
    else if (sheetRadioButton->isChecked())
        flags = Qt::Sheet;
    else if (drawerRadioButton->isChecked())
        flags = Qt::Drawer;
    else if (popupRadioButton->isChecked())
        flags = Qt::Popup;
    else if (toolRadioButton->isChecked())
        flags = Qt::Tool;
    else if (toolTipRadioButton->isChecked())
        flags = Qt::ToolTip;
    else if (splashScreenRadioButton->isChecked())
        flags = Qt::SplashScreen;

La ranura updatePreview() es llamada cada vez que el usuario cambia cualquiera de las banderas de la ventana. Primero creamos un Qt::WindowFlags vacío flags, luego determinamos cuál de los tipos que está marcado y lo añadimos a flags.

    if (msWindowsFixedSizeDialogCheckBox->isChecked())
        flags |= Qt::MSWindowsFixedSizeDialogHint;
    if (x11BypassWindowManagerCheckBox->isChecked())
        flags |= Qt::X11BypassWindowManagerHint;
    if (framelessWindowCheckBox->isChecked())
        flags |= Qt::FramelessWindowHint;
    if (windowNoShadowCheckBox->isChecked())
        flags |= Qt::NoDropShadowWindowHint;
    if (windowTitleCheckBox->isChecked())
        flags |= Qt::WindowTitleHint;
    if (windowSystemMenuCheckBox->isChecked())
        flags |= Qt::WindowSystemMenuHint;
    if (windowMinimizeButtonCheckBox->isChecked())
        flags |= Qt::WindowMinimizeButtonHint;
    if (windowMaximizeButtonCheckBox->isChecked())
        flags |= Qt::WindowMaximizeButtonHint;
    if (windowCloseButtonCheckBox->isChecked())
        flags |= Qt::WindowCloseButtonHint;
    if (windowContextHelpButtonCheckBox->isChecked())
        flags |= Qt::WindowContextHelpButtonHint;
    if (windowShadeButtonCheckBox->isChecked())
        flags |= Qt::WindowShadeButtonHint;
    if (windowStaysOnTopCheckBox->isChecked())
        flags |= Qt::WindowStaysOnTopHint;
    if (windowStaysOnBottomCheckBox->isChecked())
        flags |= Qt::WindowStaysOnBottomHint;
    if (customizeWindowHintCheckBox->isChecked())
        flags |= Qt::CustomizeWindowHint;

    previewWindow->setWindowFlags(flags);

También determinamos cuál de las pistas está marcada y la añadimos a flags utilizando un operador OR. Usamos flags para establecer los indicadores de ventana para la ventana de vista previa.

    QPoint pos = previewWindow->pos();
    if (pos.x() < 0)
        pos.setX(0);
    if (pos.y() < 0)
        pos.setY(0);
    previewWindow->move(pos);
    previewWindow->showNormal();
}

Ajustamos la posición de la ventana de previsualización. La razón por la que hacemos esto, es que jugar con el marco de la ventana puede causar en algunas plataformas que la posición de la ventana cambie a nuestras espaldas. Si una ventana está situada en la esquina superior izquierda de la pantalla, partes de la ventana pueden no ser visibles. Así que ajustamos la posición del widget para asegurarnos de que, si esto ocurre, la ventana se mueve dentro de los límites de la pantalla. Por último, llamamos a QWidget::show() para asegurarnos de que la ventana de previsualización es visible.

void ControllerWindow::createTypeGroupBox()
{
    typeGroupBox = new QGroupBox(tr("Type"));

    windowRadioButton = createRadioButton(tr("Window"));
    dialogRadioButton = createRadioButton(tr("Dialog"));
    sheetRadioButton = createRadioButton(tr("Sheet"));
    drawerRadioButton = createRadioButton(tr("Drawer"));
    popupRadioButton = createRadioButton(tr("Popup"));
    toolRadioButton = createRadioButton(tr("Tool"));
    toolTipRadioButton = createRadioButton(tr("Tooltip"));
    splashScreenRadioButton = createRadioButton(tr("Splash screen"));
    windowRadioButton->setChecked(true);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(windowRadioButton, 0, 0);
    layout->addWidget(dialogRadioButton, 1, 0);
    layout->addWidget(sheetRadioButton, 2, 0);
    layout->addWidget(drawerRadioButton, 3, 0);
    layout->addWidget(popupRadioButton, 0, 1);
    layout->addWidget(toolRadioButton, 1, 1);
    layout->addWidget(toolTipRadioButton, 2, 1);
    layout->addWidget(splashScreenRadioButton, 3, 1);
    typeGroupBox->setLayout(layout);
}

La función privada createTypeGroupBox() se llama desde el constructor.

Primero creamos una caja de grupo, y luego creamos un botón de radio (usando la función privada createRadioButton() ) para cada uno de los tipos disponibles entre las banderas de la ventana. Hacemos que Qt::Window sea el tipo aplicado inicialmente. Colocamos los botones de opción en QGridLayout e instalamos el diseño en la caja de grupo.

No incluimos el tipo por defecto Qt::Widget. La razón es que se comporta de forma algo diferente a los otros tipos. Si no se especifica el tipo para un widget, y no tiene padre, el widget es una ventana. Sin embargo, si tiene un padre, es un widget hijo estándar. Los otros tipos son todos ventanas de nivel superior, y como las sugerencias sólo afectan a las ventanas de nivel superior, abandonamos el tipo Qt::Widget.

void ControllerWindow::createHintsGroupBox()
{
    hintsGroupBox = new QGroupBox(tr("Hints"));

    msWindowsFixedSizeDialogCheckBox =
            createCheckBox(tr("MS Windows fixed size dialog"));
    x11BypassWindowManagerCheckBox =
            createCheckBox(tr("X11 bypass window manager"));
    framelessWindowCheckBox = createCheckBox(tr("Frameless window"));
    windowNoShadowCheckBox = createCheckBox(tr("No drop shadow"));
    windowTitleCheckBox = createCheckBox(tr("Window title"));
    windowSystemMenuCheckBox = createCheckBox(tr("Window system menu"));
    windowMinimizeButtonCheckBox = createCheckBox(tr("Window minimize button"));
    windowMaximizeButtonCheckBox = createCheckBox(tr("Window maximize button"));
    windowCloseButtonCheckBox = createCheckBox(tr("Window close button"));
    windowContextHelpButtonCheckBox =
            createCheckBox(tr("Window context help button"));
    windowShadeButtonCheckBox = createCheckBox(tr("Window shade button"));
    windowStaysOnTopCheckBox = createCheckBox(tr("Window stays on top"));
    windowStaysOnBottomCheckBox = createCheckBox(tr("Window stays on bottom"));
    customizeWindowHintCheckBox= createCheckBox(tr("Customize window"));

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(msWindowsFixedSizeDialogCheckBox, 0, 0);
    layout->addWidget(x11BypassWindowManagerCheckBox, 1, 0);
    layout->addWidget(framelessWindowCheckBox, 2, 0);
    layout->addWidget(windowNoShadowCheckBox, 3, 0);
    layout->addWidget(windowTitleCheckBox, 4, 0);
    layout->addWidget(windowSystemMenuCheckBox, 5, 0);
    layout->addWidget(customizeWindowHintCheckBox, 6, 0);
    layout->addWidget(windowMinimizeButtonCheckBox, 0, 1);
    layout->addWidget(windowMaximizeButtonCheckBox, 1, 1);
    layout->addWidget(windowCloseButtonCheckBox, 2, 1);
    layout->addWidget(windowContextHelpButtonCheckBox, 3, 1);
    layout->addWidget(windowShadeButtonCheckBox, 4, 1);
    layout->addWidget(windowStaysOnTopCheckBox, 5, 1);
    layout->addWidget(windowStaysOnBottomCheckBox, 6, 1);
    hintsGroupBox->setLayout(layout);
}

La función privada createHintsGroupBox() también se llama desde el constructor.

De nuevo, lo primero que hacemos es crear un cuadro de grupo. Luego creamos una casilla de verificación, usando la función privada createCheckBox(), para cada una de las pistas disponibles entre las banderas de la ventana. Colocamos las casillas de verificación en un QGridLayout e instalamos el diseño en la caja de grupo.

QCheckBox *ControllerWindow::createCheckBox(const QString &text)
{
    QCheckBox *checkBox = new QCheckBox(text);
    connect(checkBox, &QCheckBox::clicked,
            this, &ControllerWindow::updatePreview);
    return checkBox;
}

La función privada createCheckBox() se llama desde createHintsGroupBox().

Simplemente creamos un QCheckBox con el texto proporcionado, lo conectamos a la ranura privada updatePreview() y devolvemos un puntero a la casilla de verificación.

QRadioButton *ControllerWindow::createRadioButton(const QString &text)
{
    QRadioButton *button = new QRadioButton(text);
    connect(button, &QRadioButton::clicked,
            this, &ControllerWindow::updatePreview);
    return button;
}

En la función privada createRadioButton() es un QRadioButton que creamos con el texto proporcionado, y lo conectamos a la ranura privada updatePreview(). La función es llamada desde createTypeGroupBox(), y devuelve un puntero al botón.

Definición de la Clase PreviewWindow

class PreviewWindow : public QWidget
{
    Q_OBJECT

public:
    PreviewWindow(QWidget *parent = nullptr);

    void setWindowFlags(Qt::WindowFlags flags);

private:
    QTextEdit *textEdit;
    QPushButton *closeButton;
};

La clase PreviewWindow hereda de QWidget. Es un widget personalizado que muestra los nombres de sus banderas de ventana actualmente configuradas en un editor de texto de sólo lectura. También está provisto de un QPushbutton que cierra la ventana.

Reimplementamos el constructor para crear el botón Close y el editor de texto, y la función QWidget::setWindowFlags() para mostrar los nombres de las banderas de ventana.

Ventana de vista previa con banderas

Implementación de la clase PreviewWindow

PreviewWindow::PreviewWindow(QWidget *parent)
    : QWidget(parent)
{
    textEdit = new QTextEdit;
    textEdit->setReadOnly(true);
    textEdit->setLineWrapMode(QTextEdit::NoWrap);

    closeButton = new QPushButton(tr("&Close"));
    connect(closeButton, &QPushButton::clicked,
            this, &PreviewWindow::close);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(textEdit);
    layout->addWidget(closeButton);
    setLayout(layout);

    setWindowTitle(tr("Preview"));
}

En el constructor, primero creamos un QTextEdit y nos aseguramos de que es de sólo lectura.

También prohibimos cualquier ajuste de línea en el editor de texto utilizando la función QTextEdit::setLineWrapMode(). El resultado es que aparece una barra de desplazamiento horizontal cuando el nombre de una bandera de ventana excede el ancho del editor. Esta es una solución razonable ya que construimos el texto mostrado con saltos de línea incorporados. Si no se garantizaran los saltos de línea, quizás tendría más sentido utilizar otro QTextEdit::LineWrapMode.

Entonces creamos el botón Close, y ponemos ambos widgets en un QVBoxLayout antes de poner el título de la ventana.

void PreviewWindow::setWindowFlags(Qt::WindowFlags flags)
{
    QWidget::setWindowFlags(flags);

    QString text;

    Qt::WindowFlags type = (flags & Qt::WindowType_Mask);
    if (type == Qt::Window)
        text = "Qt::Window";
    else if (type == Qt::Dialog)
        text = "Qt::Dialog";
    else if (type == Qt::Sheet)
        text = "Qt::Sheet";
    else if (type == Qt::Drawer)
        text = "Qt::Drawer";
    else if (type == Qt::Popup)
        text = "Qt::Popup";
    else if (type == Qt::Tool)
        text = "Qt::Tool";
    else if (type == Qt::ToolTip)
        text = "Qt::ToolTip";
    else if (type == Qt::SplashScreen)
        text = "Qt::SplashScreen";

    if (flags & Qt::MSWindowsFixedSizeDialogHint)
        text += "\n| Qt::MSWindowsFixedSizeDialogHint";
    if (flags & Qt::X11BypassWindowManagerHint)
        text += "\n| Qt::X11BypassWindowManagerHint";
    if (flags & Qt::FramelessWindowHint)
        text += "\n| Qt::FramelessWindowHint";
    if (flags & Qt::NoDropShadowWindowHint)
        text += "\n| Qt::NoDropShadowWindowHint";
    if (flags & Qt::WindowTitleHint)
        text += "\n| Qt::WindowTitleHint";
    if (flags & Qt::WindowSystemMenuHint)
        text += "\n| Qt::WindowSystemMenuHint";
    if (flags & Qt::WindowMinimizeButtonHint)
        text += "\n| Qt::WindowMinimizeButtonHint";
    if (flags & Qt::WindowMaximizeButtonHint)
        text += "\n| Qt::WindowMaximizeButtonHint";
    if (flags & Qt::WindowCloseButtonHint)
        text += "\n| Qt::WindowCloseButtonHint";
    if (flags & Qt::WindowContextHelpButtonHint)
        text += "\n| Qt::WindowContextHelpButtonHint";
    if (flags & Qt::WindowShadeButtonHint)
        text += "\n| Qt::WindowShadeButtonHint";
    if (flags & Qt::WindowStaysOnTopHint)
        text += "\n| Qt::WindowStaysOnTopHint";
    if (flags & Qt::WindowStaysOnBottomHint)
        text += "\n| Qt::WindowStaysOnBottomHint";
    if (flags & Qt::CustomizeWindowHint)
        text += "\n| Qt::CustomizeWindowHint";

    textEdit->setPlainText(text);
}

En nuestra reimplementación de la función setWindowFlags(), primero establecemos las banderas de los widgets utilizando la función QWidget::setWindowFlags(). Luego recorremos las banderas de ventana disponibles, creando un texto que contenga los nombres de las banderas que coincidan con el parámetro flags. Por último, mostramos el texto en el editor de texto de widgets.

Proyecto de ejemplo @ code.qt.io

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