旋转框示例
“旋转框示例”演示了如何使用 Qt 中提供的多种不同类型的旋转框,从简单的 `QSpinBox ` 控件到更复杂的编辑器(如 `QDateTimeEdit ` 控件)。

该示例包含一个Window 类,用于展示Qt中可用的各种基于旋转框的小部件。
窗口类定义
Window 类继承自QWidget ,并包含两个用于提供交互功能的槽:
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;
};私有函数用于在窗口中设置每种类型的旋转框。我们使用成员变量来跟踪各种控件,以便在需要时对其进行重新配置。
窗口类实现
构造函数仅调用私有函数来设置示例中使用的不同类型的旋转框,并将每个组放置在布局中:
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"));
}我们使用布局来管理窗口子控件的排列,并修改窗口标题。
createSpinBoxes() 函数构建一个QGroupBox ,并在其中放置三个QSpinBox 控件,并配有描述性标签以指示它们期望的输入类型。
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);第一个旋转框展示了使用QSpinBox 的最简单方法。它接受-20到20之间的值,当前值可通过箭头按钮或Up 和Down 键以1为增量增减,默认值为0。
第二个旋转框采用更大的步长,并显示一个后缀以提供更多关于该数字所代表数据类型的信息:
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);该旋转框还会显示special value ,而非其定义的最小值。这意味着它永远不会显示0% ,但在选中最小值时会显示Automatic 。
第三个旋转框展示了如何使用前缀:
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);为简化起见,我们展示了一个带有前缀但没有后缀的旋转框。当然,也可以同时使用前缀和后缀。
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);
}该函数的其余部分用于设置组框的布局,并将各个控件放置其中。
createDateTimeEdits() 函数构建了另一个组框,其中包含用于编辑日期和时间的旋转框。
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)));第一个旋转框是一个QDateEdit 控件,能够接受使用QDate 值指定的给定范围内的日期。当光标位于相关区域时,可使用箭头按钮以及Up 和Down 键来增减年、月和日的数值。
第二个旋转框是一个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)));时间的可接受值通过QTime 的数值进行定义。
第三个旋转框是一个QDateTimeEdit 控件,可同时显示日期和时间值,我们在其上方放置了一个标签,用于标明会议允许的时间范围。当用户更改格式字符串时,这些控件将随之更新。
meetingLabel = new QLabel;
meetingEdit = new QDateTimeEdit(QDateTime::currentDateTime());用于日期时间编辑器的格式字符串(该字符串也显示在标签上)是从下拉列表中的一组字符串中选择的:
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);该下拉列表发出的信号连接到了Window 类中的一个槽(稍后将展示)。
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);
}组框中的每个子控件都放置在一个布局中。
每当用户在下拉列表中选择新的格式字符串时,都会调用setFormatString() 的槽函数。QDateTimeEdit 控件的显示格式通过信号传递的原始字符串进行设置:
void Window::setFormatString(const QString &formatString)
{
meetingEdit->setDisplayFormat(formatString);根据控件中可见的部分,我们会设置新的日期或时间范围,并更新相关的标签以向用户提供相关信息:
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)));
}
}当格式字符串发生变化时,系统会根据输入类型(日期、时间或两者兼有)自动提供相应的标签和输入控件。
createDoubleSpinBoxes() 函数构建了三个用于输入双精度浮点数的旋转框:
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);在构建 `QDoubleSpinBox ` 控件之前,我们会先创建一个旋转框,用于控制它们显示的小数位数。默认情况下,以下旋转框仅显示两位小数,每个旋转框都相当于由 `createSpinBoxes() ` 函数创建的组中的一个旋转框。
第一个双精度旋转框展示了一个基本的双精度旋转框,其范围、步长和默认值与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);不过,此旋转框也允许输入非整数值。
第二个旋转框显示了一个后缀,并显示了一个特殊值,而不是最小值:
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);第三个旋转框显示前缀而非后缀:
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,我们将指定精度的QSpinBox 控件连接到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);
}函数的其余部分将每个控件放置到组框的布局中。
当用户更改精度旋转框中的值时,会调用changePrecision() 槽:
void Window::changePrecision(int decimals)
{
doubleSpinBox->setDecimals(decimals);
scaleSpinBox->setDecimals(decimals);
priceSpinBox->setDecimals(decimals);
}该函数仅使用信号提供的整数值来指定每个QDoubleSpinBox 控件的小数位数。当这些控件的decimals 属性发生变化时,它们将自动更新。
© 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.