Spin Boxes Beispiel

Das Spin Boxes Beispiel zeigt, wie die vielen verschiedenen Arten von Spin Boxes, die in Qt verfügbar sind, verwendet werden können, von einem einfachen QSpinBox Widget bis hin zu komplexeren Editoren wie dem QDateTimeEdit Widget.

Das Beispiel besteht aus einer einzigen Window Klasse, die verwendet wird, um die verschiedenen Spin-Box-basierten Widgets anzuzeigen, die in Qt verfügbar sind.

Definition der Fensterklasse

Die Klasse Window erbt von QWidget und enthält zwei Slots, die für die Bereitstellung interaktiver Funktionen verwendet werden:

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 werden verwendet, um jeden Typ von Spin-Box im Fenster einzurichten. Wir verwenden Mitgliedsvariablen, um die verschiedenen Widgets im Auge zu behalten, so dass sie bei Bedarf neu konfiguriert werden können.

Implementierung der Fensterklasse

Der Konstruktor ruft einfach private Funktionen auf, um die verschiedenen Arten von Spinnboxen einzurichten, die in diesem Beispiel verwendet werden, und platziert jede Gruppe in einem Layout:

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() konstruiert ein QGroupBox und platziert darin drei QSpinBox Widgets mit beschreibenden Bezeichnungen, um die Arten von Eingaben anzuzeigen, die sie erwarten.

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

Der erste Drehkasten zeigt die einfachste Art, QSpinBox zu verwenden. Es akzeptiert Werte von -20 bis 20, der aktuelle Wert kann entweder mit den Pfeiltasten oder den Tasten Up und Down um 1 erhöht oder verringert werden, und der Standardwert ist 0.

Das zweite Drehfeld verwendet eine größere Schrittweite und zeigt ein Suffix an, um weitere Informationen über die Art der Daten zu liefern, die die Zahl repräsentiert:

    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 auch special value anstelle des dafür definierten Mindestwerts an. Das bedeutet, dass es niemals 0% anzeigt, sondern Automatic, wenn der Mindestwert ausgewählt wird.

Der dritte Spinnkasten 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 einen Spinnkasten mit einem Präfix und ohne Suffix. Es ist auch möglich, beide 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 den Gruppenrahmen ein und platziert jedes der Widgets darin.

Die Funktion createDateTimeEdits() konstruiert einen weiteren Gruppenrahmen mit einer Auswahl von Drehkästen, die für die Bearbeitung von Daten und Zeiten verwendet werden.

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 annehmen kann, der mit QDate -Werten angegeben wird. Mit den Pfeiltasten und den Tasten Up und Down können Sie die Werte für Jahr, Monat und Tag erhöhen und verringern, wenn sich der Cursor im entsprechenden Bereich 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)));

Die zulässigen Werte für die Uhrzeit werden mit den Werten von QTime definiert.

Das dritte Drehfeld ist ein QDateTimeEdit -Widget, das sowohl Datums- als auch Zeitwerte anzeigen kann, und wir platzieren ein Etikett darüber, um den Bereich der zulässigen Zeiten für eine Besprechung anzugeben. Diese Widgets werden aktualisiert, wenn der Benutzer eine Formatzeichenfolge ändert.

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

Die für den Datums-Zeit-Editor verwendete Formatzeichenkette, die auch in der vom Label angezeigten Zeichenkette enthalten ist, wird aus einer Reihe von Zeichenketten 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 aus dieser Combobox ist mit einem Slot in der Klasse Window verbunden (siehe später).

    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 Gruppenrahmens wird in einem Layout platziert.

Der Slot setFormatString() wird immer dann aufgerufen, wenn der Benutzer eine neue Formatzeichenfolge in der Combobox auswählt. Das Anzeigeformat für das Widget QDateTimeEdit wird mit Hilfe der vom Signal übergebenen Rohzeichenkette festgelegt:

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

Abhängig von den sichtbaren Abschnitten im Widget wird ein neuer Datums- oder Zeitbereich festgelegt und die zugehörige Beschriftung aktualisiert, um dem Benutzer relevante Informationen zu liefern:

    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, gibt es eine entsprechende Beschriftung und ein Eingabewidget für Datums- oder Zeitangaben oder für beide Arten von Eingaben.

Die Funktion createDoubleSpinBoxes() konstruiert drei Spinboxen, die zur Eingabe von doppelpräzisen Fließkommazahlen verwendet werden:

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 konstruiert werden, erstellen wir eine Spinbox, um zu steuern, wie viele Nachkommastellen sie anzeigen. Standardmäßig werden in den folgenden Spinboxen nur zwei Nachkommastellen angezeigt. Jede dieser Spinboxen entspricht einer Spinbox in der Gruppe, die mit der Funktion createSpinBoxes() erstellt wurde.

Der erste Doppelspinrahmen zeigt einen einfachen Doppelpräzisionsspinrahmen mit demselben Bereich, derselben Schrittweite und demselben Standardwert wie der erste Spinrahmen in der Funktion 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);

In diesem Drehfeld können jedoch auch nicht ganzzahlige Werte eingegeben werden.

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

    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 ein Präfix anstelle eines Suffixes 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 angibt, 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 platziert jedes der Widgets in einem Layout für den Gruppenrahmen.

Der Slot changePrecision() wird aufgerufen, wenn der Benutzer den Wert im Präzisionsdrehfeld ändert:

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

Diese Funktion verwendet einfach die vom Signal gelieferte Ganzzahl, um die Anzahl der Dezimalstellen in jedem der QDoubleSpinBox Widgets anzugeben. Jedes dieser Widgets wird automatisch aktualisiert, wenn seine decimals Eigenschaft geändert wird.

Beispielprojekt @ code.qt.io

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