Auf dieser Seite

Beispiel für Spin-Boxen

Das Beispiel „Spin-Boxen“ zeigt, wie die vielen verschiedenen Arten von Spin-Boxen verwendet werden, die in Qt verfügbar sind – vom einfachen Widget „ QSpinBox “ bis hin zu komplexeren Editoren wie dem Widget „ QDateTimeEdit “.

Galerie mit verschiedenen Arten von Drehfeldern

Das Beispiel besteht aus einer einzigen „ Window “-Klasse, die zur Darstellung der verschiedenen in Qt verfügbaren, auf Spin-Boxen basierenden Widgets verwendet wird.

Definition der Fensterklasse

Die Klasse „ Window “ erbt von „ QWidget “ und enthält zwei Slots, die zur Bereitstellung interaktiver Funktionen dienen:

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;
};

Die privaten Funktionen dienen dazu, die einzelnen Spin-Box-Typen im Fenster einzurichten. Wir verwenden Membervariablen, um verschiedene Widgets zu verwalten, damit diese bei Bedarf neu konfiguriert werden können.

Implementierung der Fensterklasse

Der Konstruktor ruft lediglich private Funktionen auf, um die verschiedenen im Beispiel verwendeten Spinbox-Typen einzurichten, und ordnet jede Gruppe einem Layout zu:

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"));
}

Wir verwenden das Layout, um die Anordnung der untergeordneten Widgets des Fensters zu verwalten und den Fenstertitel zu ändern.

Die Funktion „ createSpinBoxes() “ erstellt ein „ QGroupBox “ und platziert darin drei „ QSpinBox “-Widgets mit beschreibenden Beschriftungen, die die erwarteten Eingabetypen angeben.

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);

Das erste Drehfeld zeigt die einfachste Art der Verwendung von ` QSpinBox`. Es akzeptiert Werte von -20 bis 20; der aktuelle Wert kann entweder über die Pfeiltasten oder die Tasten ` Up ` und ` Down ` um 1 erhöht oder verringert werden, und der Standardwert ist 0.

Das zweite Eingabefeld verwendet eine größere Schrittweite und zeigt ein Suffix an, um mehr Informationen über den Datentyp der Zahl zu liefern:

    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);

Dieses Drehfeld zeigt zudem „ special value “ anstelle des dafür definierten Mindestwerts an. Das bedeutet, dass es niemals „ 0% “ anzeigt, sondern „ Automatic “, wenn der Mindestwert ausgewählt wird.

Das dritte Drehfeld zeigt, wie ein Präfix verwendet werden kann:

    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);

Der Einfachheit halber zeigen wir ein Drehfeld mit einem Präfix und ohne Suffix. Es ist auch möglich, beides gleichzeitig zu verwenden.

    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);
}

Der Rest der Funktion richtet ein Layout für die Gruppenbox ein und platziert die einzelnen Widgets darin.

Die Funktion „ createDateTimeEdits() “ erstellt eine weitere Gruppenbox mit einer Auswahl an Drehfeldern, die zur Bearbeitung von Datums- und Zeitangaben dienen.

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)));

Das erste Drehfeld ist ein „ QDateEdit “-Widget, das Datumsangaben innerhalb eines bestimmten Bereichs akzeptieren kann, der mithilfe von „ QDate “-Werten festgelegt wird. Die Pfeiltasten sowie die Tasten „ Up “ und „ Down “ können verwendet werden, um die Werte für Jahr, Monat und Tag zu erhöhen bzw. zu verringern, wenn sich der Cursor im entsprechenden Abschnitt befindet.

Das zweite Drehfeld ist ein „ QTimeEdit “-Widget:

    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)));

Zulässige Werte für die Uhrzeit werden mithilfe von „ QTime “-Werten definiert.

Das dritte Drehfeld ist ein „ QDateTimeEdit “-Widget, das sowohl Datums- als auch Zeitwerte anzeigen kann; darüber platzieren wir eine Beschriftung, um den zulässigen Zeitbereich für ein Meeting anzugeben. Diese Widgets werden aktualisiert, sobald der Benutzer eine Formatzeichenfolge ändert.

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

Die für den Datums- und Zeit-Editor verwendete Formatzeichenfolge, die auch in der vom Label angezeigten Zeichenfolge erscheint, wird aus einer Reihe von Zeichenfolgen in einer Combobox ausgewählt:

    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);

Ein Signal dieser Combobox ist mit einem Slot in der Klasse „ Window “ verbunden (wird später gezeigt).

    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);
}

Jedes untergeordnete Widget des Gruppenfelds wird in einem Layout platziert.

Der Slot „ setFormatString() “ wird aufgerufen, sobald der Benutzer eine neue Formatzeichenfolge in der Combobox auswählt. Das Anzeigeformat für das „ QDateTimeEdit “-Widget wird mithilfe der vom Signal übergebenen Rohzeichenfolge festgelegt:

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

Je nach den im Widget sichtbaren Abschnitten legen wir einen neuen Datums- oder Zeitbereich fest und aktualisieren die zugehörige Beschriftung, um dem Benutzer relevante Informationen bereitzustellen:

    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)));
    }
}

Wenn die Formatzeichenfolge geändert wird, stehen ein entsprechendes Beschriftungsfeld und ein Eingabefeld für Datumsangaben, Uhrzeiten oder beide Eingabetypen zur Verfügung.

Die Funktion „ createDoubleSpinBoxes() “ erstellt drei Spin-Boxen, die zur Eingabe von Gleitkommazahlen mit doppelter Genauigkeit dienen:

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);

Bevor die „ QDoubleSpinBox “-Widgets erstellt werden, erstellen wir ein Drehfeld, um zu steuern, wie viele Dezimalstellen angezeigt werden. Standardmäßig werden in den folgenden Drehfeldern nur zwei Dezimalstellen angezeigt; jedes davon entspricht einem Drehfeld in der durch die Funktion „ createSpinBoxes() “ erstellten Gruppe.

Das erste „double“-Spin-Feld zeigt ein einfaches Spin-Feld mit doppelter Genauigkeit, dessen Bereich, Schrittweite und Standardwert mit denen des ersten Spin-Feldes in der Funktion „ createSpinBoxes() “ übereinstimmen:

    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);

Dieses Drehfeld ermöglicht jedoch auch die Eingabe von nicht ganzzahligen Werten.

Das zweite Drehfeld zeigt ein Suffix an und stellt anstelle des Mindestwerts einen speziellen Wert dar:

    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);

Das dritte Drehfeld zeigt anstelle eines Suffixes ein Präfix an:

    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,

Wir verbinden das Widget „ QSpinBox “, das die Genauigkeit festlegt, mit einem Slot in der Klasse „ 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);
}

Der Rest der Funktion ordnet jedes der Widgets in ein Layout für die Gruppenbox ein.

Der Slot „ changePrecision() “ wird aufgerufen, wenn der Benutzer den Wert im Spin-Feld „precision“ ändert:

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

Diese Funktion verwendet einfach die vom Signal übergebene Ganzzahl, um die Anzahl der Dezimalstellen in jedem der „ QDoubleSpinBox “-Widgets festzulegen. Jedes dieser Widgets wird automatisch aktualisiert, sobald sich seine „ decimals “-Eigenschaft ändert.

Beispielprojekt @ 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.