En esta página

Ejemplo de Spin Boxes

El ejemplo de Spin Boxes muestra cómo utilizar los diferentes tipos de spin boxes disponibles en Qt, desde un simple widget QSpinBox hasta editores más complejos como el widget QDateTimeEdit.

Galería de diferentes tipos de cajas giratorias

El ejemplo consiste en una única clase Window que se utiliza para mostrar los diferentes widgets basados en Spin Boxes disponibles con Qt.

Definición de la clase Window

La clase Window hereda de QWidget y contiene dos ranuras que se utilizan para proporcionar funciones interactivas:

class Window : public QWidget
{
    Q_OBJECT

public:
    Window(QWidget *parent = nullptr);

public slots:
    void changePrecision(int decimals);
    void setFormatString(const QString &formatString);

private:
    void createSpinBoxes();
    void createDateTimeEdits();
    void createDoubleSpinBoxes();

    QDateTimeEdit *meetingEdit;
    QDoubleSpinBox *doubleSpinBox;
    QDoubleSpinBox *priceSpinBox;
    QDoubleSpinBox *scaleSpinBox;
    QGroupBox *spinBoxesGroup;
    QGroupBox *editsGroup;
    QGroupBox *doubleSpinBoxesGroup;
    QLabel *meetingLabel;
    QSpinBox *groupSeparatorSpinBox;
    QDoubleSpinBox *groupSeparatorSpinBox_d;
};

Las funciones privadas se utilizan para configurar cada tipo de spin box en la ventana. Utilizamos variables miembro para realizar un seguimiento de los distintos widgets de modo que puedan reconfigurarse cuando sea necesario.

Implementación de la clase Window

El constructor simplemente llama a funciones privadas para configurar los diferentes tipos de cuadro de giro utilizados en el ejemplo, y coloca cada grupo en un diseño:

Window::Window(QWidget *parent)
    : QWidget(parent)
{
    createSpinBoxes();
    createDateTimeEdits();
    createDoubleSpinBoxes();

    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(spinBoxesGroup);
    layout->addWidget(editsGroup);
    layout->addWidget(doubleSpinBoxesGroup);
    setLayout(layout);

    setWindowTitle(tr("Spin Boxes"));
}

Usamos el layout para gestionar la disposición de los widgets hijos de la ventana, y cambiar el título de la ventana.

La función createSpinBoxes() construye un QGroupBox y coloca tres widgets QSpinBox dentro de él con etiquetas descriptivas para indicar los tipos de entrada que esperan.

void Window::createSpinBoxes()
{
    spinBoxesGroup = new QGroupBox(tr("Spinboxes"));

    QLabel *integerLabel = new QLabel(tr("Enter a value between "
        "%1 and %2:").arg(-20).arg(20));
    QSpinBox *integerSpinBox = new QSpinBox;
    integerSpinBox->setRange(-20, 20);
    integerSpinBox->setSingleStep(1);
    integerSpinBox->setValue(0);

El primer cuadro muestra la forma más sencilla de utilizar QSpinBox. Acepta valores de -20 a 20, el valor actual puede aumentarse o reducirse en 1 con los botones de flecha o las teclas Up y Down, y el valor por defecto es 0.

La segunda casilla giratoria utiliza un tamaño de paso mayor y muestra un sufijo para proporcionar más información sobre el tipo de datos que representa el número:

    QLabel *zoomLabel = new QLabel(tr("Enter a zoom value between "
        "%1 and %2:").arg(0).arg(1000));
    QSpinBox *zoomSpinBox = new QSpinBox;
    zoomSpinBox->setRange(0, 1000);
    zoomSpinBox->setSingleStep(10);
    zoomSpinBox->setSuffix("%");
    zoomSpinBox->setSpecialValueText(tr("Automatic"));
    zoomSpinBox->setValue(100);

Esta casilla giratoria también muestra un special value en lugar del valor mínimo definido para ella. Esto significa que nunca mostrará 0%, pero mostrará Automatic cuando se seleccione el valor mínimo.

La tercera casilla muestra cómo se puede utilizar un prefijo:

    QLabel *priceLabel = new QLabel(tr("Enter a price between "
        "%1 and %2:").arg(0).arg(999));
    QSpinBox *priceSpinBox = new QSpinBox;
    priceSpinBox->setRange(0, 999);
    priceSpinBox->setSingleStep(1);
    priceSpinBox->setPrefix("$");
    priceSpinBox->setValue(99);

Para simplificar, mostramos una caja de rotación con un prefijo y sin sufijo. También es posible utilizar ambos al mismo tiempo.

    groupSeparatorSpinBox = new QSpinBox;
    groupSeparatorSpinBox->setRange(-99999999, 99999999);
    groupSeparatorSpinBox->setValue(1000);
    groupSeparatorSpinBox->setGroupSeparatorShown(true);
    QCheckBox *groupSeparatorChkBox = new QCheckBox;
    groupSeparatorChkBox->setText(tr("Show group separator"));
    groupSeparatorChkBox->setChecked(true);
    connect(groupSeparatorChkBox, &QCheckBox::toggled, groupSeparatorSpinBox,
            &QSpinBox::setGroupSeparatorShown);

    QLabel *hexLabel = new QLabel(tr("Enter a value between "
        "%1 and %2:").arg('-' + QString::number(31, 16)).arg(QString::number(31, 16)));
    QSpinBox *hexSpinBox = new QSpinBox;
    hexSpinBox->setRange(-31, 31);
    hexSpinBox->setSingleStep(1);
    hexSpinBox->setValue(0);
    hexSpinBox->setDisplayIntegerBase(16);

    QVBoxLayout *spinBoxLayout = new QVBoxLayout;
    spinBoxLayout->addWidget(integerLabel);
    spinBoxLayout->addWidget(integerSpinBox);
    spinBoxLayout->addWidget(zoomLabel);
    spinBoxLayout->addWidget(zoomSpinBox);
    spinBoxLayout->addWidget(priceLabel);
    spinBoxLayout->addWidget(priceSpinBox);
    spinBoxLayout->addWidget(hexLabel);
    spinBoxLayout->addWidget(hexSpinBox);
    spinBoxLayout->addWidget(groupSeparatorChkBox);
    spinBoxLayout->addWidget(groupSeparatorSpinBox);
    spinBoxesGroup->setLayout(spinBoxLayout);
}

El resto de la función establece un diseño para la caja de grupo y coloca cada uno de los widgets dentro de ella.

La función createDateTimeEdits() construye otro cuadro de grupo con una selección de cuadros giratorios utilizados para editar fechas y horas.

void Window::createDateTimeEdits()
{
    editsGroup = new QGroupBox(tr("Date and time spin boxes"));

    QLabel *dateLabel = new QLabel;
    QDateEdit *dateEdit = new QDateEdit(QDate::currentDate());
    dateEdit->setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31));
    dateLabel->setText(tr("Appointment date (between %0 and %1):")
                       .arg(dateEdit->minimumDate().toString(Qt::ISODate))
                       .arg(dateEdit->maximumDate().toString(Qt::ISODate)));

La primera caja giratoria es un widget QDateEdit capaz de aceptar fechas dentro de un rango determinado especificado mediante valores QDate. Los botones de flecha y las teclas Up y Down pueden utilizarse para aumentar y disminuir los valores de año, mes y día cuando el cursor se encuentra en la sección correspondiente.

El segundo cuadro giratorio es un widget QTimeEdit:

    QLabel *timeLabel = new QLabel;
    QTimeEdit *timeEdit = new QTimeEdit(QTime::currentTime());
    timeEdit->setTimeRange(QTime(9, 0, 0, 0), QTime(16, 30, 0, 0));
    timeLabel->setText(tr("Appointment time (between %0 and %1):")
                       .arg(timeEdit->minimumTime().toString(Qt::ISODate))
                       .arg(timeEdit->maximumTime().toString(Qt::ISODate)));

Los valores aceptables para la hora se definen utilizando los valores de QTime.

El tercer cuadro giratorio es un widget QDateTimeEdit que puede mostrar tanto valores de fecha como de hora, y colocamos una etiqueta encima para indicar el rango de horas permitidas para una reunión. Estos widgets se actualizarán cuando el usuario cambie una cadena de formato.

    meetingLabel = new QLabel;
    meetingEdit = new QDateTimeEdit(QDateTime::currentDateTime());

La cadena de formato utilizada para el editor de fecha y hora, que también aparece en la cadena que muestra la etiqueta, se elige de entre un conjunto de cadenas de un combobox:

    QLabel *formatLabel = new QLabel(tr("Format string for the meeting date "
                                        "and time:"));
    QComboBox *formatComboBox = new QComboBox;
    formatComboBox->addItem("yyyy-MM-dd hh:mm:ss (zzz 'ms')");
    formatComboBox->addItem("hh:mm:ss MM/dd/yyyy");
    formatComboBox->addItem("hh:mm:ss dd/MM/yyyy");
    formatComboBox->addItem("hh:mm:ss");
    formatComboBox->addItem("hh:mm ap");

    connect(formatComboBox, &QComboBox::textActivated,
            this, &Window::setFormatString);

Una señal de este combobox se conecta a una ranura de la clase Window (que se muestra más adelante).

    QVBoxLayout *editsLayout = new QVBoxLayout;
    editsLayout->addWidget(dateLabel);
    editsLayout->addWidget(dateEdit);
    editsLayout->addWidget(timeLabel);
    editsLayout->addWidget(timeEdit);
    editsLayout->addWidget(meetingLabel);
    editsLayout->addWidget(meetingEdit);
    editsLayout->addWidget(formatLabel);
    editsLayout->addWidget(formatComboBox);
    editsGroup->setLayout(editsLayout);
}

Cada widget hijo del cuadro de grupo se coloca en un diseño.

La ranura setFormatString() es llamada cada vez que el usuario selecciona una nueva cadena de formato en el combobox. El formato de visualización para el widget QDateTimeEdit se establece utilizando la cadena sin procesar pasada por la señal:

void Window::setFormatString(const QString &formatString)
{
    meetingEdit->setDisplayFormat(formatString);

Dependiendo de las secciones visibles en el widget, establecemos un nuevo intervalo de fecha u hora, y actualizamos la etiqueta asociada para proporcionar información relevante para el usuario:

    if (meetingEdit->displayedSections() & QDateTimeEdit::DateSections_Mask) {
        meetingEdit->setDateRange(QDate(2004, 11, 1), QDate(2005, 11, 30));
        meetingLabel->setText(tr("Meeting date (between %0 and %1):")
            .arg(meetingEdit->minimumDate().toString(Qt::ISODate))
            .arg(meetingEdit->maximumDate().toString(Qt::ISODate)));
    } else {
        meetingEdit->setTimeRange(QTime(0, 7, 20, 0), QTime(21, 0, 0, 0));
        meetingLabel->setText(tr("Meeting time (between %0 and %1):")
            .arg(meetingEdit->minimumTime().toString(Qt::ISODate))
            .arg(meetingEdit->maximumTime().toString(Qt::ISODate)));
    }
}

Cuando se cambie la cadena de formato, habrá una etiqueta y un widget de entrada apropiados para fechas, horas o ambos tipos de entrada.

La función createDoubleSpinBoxes() construye tres cuadros giratorios que se utilizan para introducir números de coma flotante de doble precisión:

void Window::createDoubleSpinBoxes()
{
    doubleSpinBoxesGroup = new QGroupBox(tr("Double precision spinboxes"));

    QLabel *precisionLabel = new QLabel(tr("Number of decimal places "
                                           "to show:"));
    QSpinBox *precisionSpinBox = new QSpinBox;
    precisionSpinBox->setRange(0, 100);
    precisionSpinBox->setValue(2);

Antes de construir los widgets QDoubleSpinBox, creamos un cuadro de giro para controlar cuántos decimales muestran. Por defecto, sólo se muestran dos decimales en las siguientes casillas, cada una de las cuales equivale a una casilla del grupo creado por la función createSpinBoxes().

La primera casilla doble muestra una casilla básica de doble precisión con el mismo rango, tamaño de paso y valor por defecto que la primera casilla de la función createSpinBoxes():

    QLabel *doubleLabel = new QLabel(tr("Enter a value between "
        "%1 and %2:").arg(-20).arg(20));
    doubleSpinBox = new QDoubleSpinBox;
    doubleSpinBox->setRange(-20.0, 20.0);
    doubleSpinBox->setSingleStep(1.0);
    doubleSpinBox->setValue(0.0);

Sin embargo, esta casilla también permite introducir valores no enteros.

La segunda casilla muestra un sufijo y un valor especial en lugar del valor mínimo:

    QLabel *scaleLabel = new QLabel(tr("Enter a scale factor between "
        "%1 and %2:").arg(0).arg(1000.0));
    scaleSpinBox = new QDoubleSpinBox;
    scaleSpinBox->setRange(0.0, 1000.0);
    scaleSpinBox->setSingleStep(10.0);
    scaleSpinBox->setSuffix("%");
    scaleSpinBox->setSpecialValueText(tr("No scaling"));
    scaleSpinBox->setValue(100.0);

La tercera casilla muestra un prefijo en lugar de un sufijo:

    QLabel *priceLabel = new QLabel(tr("Enter a price between "
        "%1 and %2:").arg(0).arg(1000));
    priceSpinBox = new QDoubleSpinBox;
    priceSpinBox->setRange(0.0, 1000.0);
    priceSpinBox->setSingleStep(1.0);
    priceSpinBox->setPrefix("$");
    priceSpinBox->setValue(99.99);

    connect(precisionSpinBox, &QSpinBox::valueChanged,

Conectamos el widget QSpinBox que especifica la precisión a una ranura de la clase Window.

    QVBoxLayout *spinBoxLayout = new QVBoxLayout;
    spinBoxLayout->addWidget(precisionLabel);
    spinBoxLayout->addWidget(precisionSpinBox);
    spinBoxLayout->addWidget(doubleLabel);
    spinBoxLayout->addWidget(doubleSpinBox);
    spinBoxLayout->addWidget(scaleLabel);
    spinBoxLayout->addWidget(scaleSpinBox);
    spinBoxLayout->addWidget(priceLabel);
    spinBoxLayout->addWidget(priceSpinBox);
    spinBoxLayout->addWidget(groupSeparatorChkBox);
    spinBoxLayout->addWidget(groupSeparatorSpinBox_d);
    doubleSpinBoxesGroup->setLayout(spinBoxLayout);
}

El resto de la función coloca cada uno de los widgets en un diseño para la caja de grupo.

La ranura changePrecision() es llamada cuando el usuario cambia el valor en la casilla de precisión:

void Window::changePrecision(int decimals)
{
    doubleSpinBox->setDecimals(decimals);
    scaleSpinBox->setDecimals(decimals);
    priceSpinBox->setDecimals(decimals);
}

Esta función simplemente utiliza el entero suministrado por la señal para especificar el número de decimales en cada uno de los widgets QDoubleSpinBox. Cada uno de ellos se actualizará automáticamente cuando se modifique su propiedad decimals.

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.