滑块示例显示了如何使用Qt中可用的不同类型的滑块:QSlider、QScrollBar和QDial。 Qt提供了三种类型的类似滑块的小部件:QSlider、QScrollBar和QDial。它们都继承了QAbstractSlider的大部分功能,理论上可以在应用程序中相互替换,因为差异只涉及它们的外观和感觉。此示例显示了它们的外观、工作方式以及如何通过其属性操纵它们的行为和外观。 该示例还演示了如何使用信号和插槽来同步两个或多个小部件的行为。

滑块示例由两个类组成:
SlidersGroup是一个自定义小部件。它结合了QSlider、QScrollBar和QDial。
Window是组合QGroupBox和QStackedWidget的主要小部件。在本例中,QStackedWidget提供了两个SliderGroup小部件的堆栈。QGroupBox包含几个控件,它们控制类似滑块的控件的行为。
首先我们将回顾Window类,然后我们将看看SliderGroup类。
Window 类定义
class Window : public QWidget
{
Q_OBJECT
public:
Window(QWidget *parent = nullptr);
private:
void createControls(const QString &title);
SlidersGroup *horizontalSliders;
SlidersGroup *verticalSliders;
QStackedWidget *stackedWidget;
QGroupBox *controlsGroup;
QLabel *minimumLabel;
QLabel *maximumLabel;
QLabel *valueLabel;
QCheckBox *invertedAppearance;
QCheckBox *invertedKeyBindings;
QSpinBox *minimumSpinBox;
QSpinBox *maximumSpinBox;
QSpinBox *valueSpinBox;
QComboBox *orientationCombo;
};
窗口类继承自QWidget。它显示滑块小部件,允许用户设置其最小值、最大值和当前值,并自定义其外观、键绑定和方向。我们使用私有的createControls()函数来创建提供这些控制机制的小部件,并将它们连接到滑块小部件。
Window 类实现
Window::Window(QWidget *parent)
: QWidget(parent)
{
horizontalSliders = new SlidersGroup(Qt::Horizontal, tr("Horizontal"));
verticalSliders = new SlidersGroup(Qt::Vertical, tr("Vertical"));
stackedWidget = new QStackedWidget;
stackedWidget->addWidget(horizontalSliders);
stackedWidget->addWidget(verticalSliders);
createControls(tr("Controls"));
在构造函数中,我们首先创建两个SliderGroup小部件,水平和垂直显示滑块小部件,并将它们添加到QStackedWidget中。QStackedWidget提供了一个只显示顶部小部件的小部件堆栈。通过createControls()我们创建了一个从控制小部件到QStackedWidget的连接,使用户能够在滑块小部件的水平方向和垂直方向之间进行选择。其余的控制机制由相同的函数调用实现。
connect(horizontalSliders, &SlidersGroup::valueChanged,
verticalSliders, &SlidersGroup::setValue);
connect(verticalSliders, &SlidersGroup::valueChanged,
valueSpinBox, &QSpinBox::setValue);
connect(valueSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
horizontalSliders, &SlidersGroup::setValue);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(controlsGroup);
layout->addWidget(stackedWidget);
setLayout(layout);
minimumSpinBox->setValue(0);
maximumSpinBox->setValue(20);
valueSpinBox->setValue(5);
setWindowTitle(tr("Sliders"));
}
然后,我们将水平滑块、垂直滑块和valueSpinBox相互连接,以便当其中一个的当前值更改时,滑块小部件和控制小部件的行为将同步。valueChanged()信号以新值作为参数发出。setValue()槽将小部件的当前值设置为新值,如果新值与旧值不同,则发出valueChanged()。 在初始化最小值、最大值和当前值之前,我们将控制小部件组和堆叠小部件放在水平布局中。当前值的初始化将通过我们在valueSpinBox和SliderGroup小部件之间建立的连接传播到slider小部件。最小值和最大值通过我们使用createControls()创建的连接传播。
void Window::createControls(const QString &title)
{
controlsGroup = new QGroupBox(title);
minimumLabel = new QLabel(tr("Minimum value:"));
maximumLabel = new QLabel(tr("Maximum value:"));
valueLabel = new QLabel(tr("Current value:"));
invertedAppearance = new QCheckBox(tr("Inverted appearance"));
invertedKeyBindings = new QCheckBox(tr("Inverted key bindings"));
在private createControls()函数中,我们让QGroupBox(controlsGroup)显示控件小部件。组框可以提供一个框架、一个标题和一个键盘快捷键,并在其内部显示各种其他小部件。控件小部件组由两个复选框、三个旋转框(带标签)和一个组合框组成。 创建标签后,我们创建两个复选框。复选框通常用于表示应用程序中可以启用或禁用的功能。启用InvertedPearance时,滑块值将反转。下表显示了不同类似滑块的小部件的外观:

通常会反转垂直QSlider的外观。例如,控制体积的垂直滑块通常从下到上(非反转外观),而控制屏幕上对象位置的垂直滑块可能从上到下,因为屏幕坐标从上到下。 启用invertedKeyBindings选项(对应于QAbstractSlider::invertedControls属性)时,滑块的控制盘和关键点事件将反转。正常的键绑定意味着向上滚动鼠标滚轮或使用像page up这样的键会将滑块的当前值增加到最大值。相反,相同的控制盘和关键点事件会将值移向滑块的最小值。如果滑块的外观是反转的,这可能很有用:一些用户可能希望键在值上仍然以相同的方式工作,而另一些用户可能希望PageUp在屏幕上表示“向上”。 请注意,对于水平和垂直滚动条,默认情况下键绑定是反向的:PageDown增加当前值,PageUp减少当前值。
minimumSpinBox = new QSpinBox;
minimumSpinBox->setRange(-100, 100);
minimumSpinBox->setSingleStep(1);
maximumSpinBox = new QSpinBox;
maximumSpinBox->setRange(-100, 100);
maximumSpinBox->setSingleStep(1);
valueSpinBox = new QSpinBox;
valueSpinBox->setRange(-100, 100);
valueSpinBox->setSingleStep(1);
orientationCombo = new QComboBox;
orientationCombo->addItem(tr("Horizontal slider-like widgets"));
orientationCombo->addItem(tr("Vertical slider-like widgets"));
然后我们创建旋转框。QSpinBox允许用户通过单击向上和向下按钮或按键盘上的向上和向下键来选择值,以修改当前显示的值。用户也可以手动键入值。旋转框控制QSlider、QScrollBar和QDial小部件的最小值、最大值和当前值。 我们创建一个QComboBox,允许用户选择滑块小部件的方向。QComboBox小部件是按钮和弹出列表的组合。它提供了一种以占用最少屏幕空间的方式向用户呈现选项列表的方法。
connect(orientationCombo, QOverload<int>::of(&QComboBox::activated), stackedWidget, &QStackedWidget::setCurrentIndex); connect(minimumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), horizontalSliders, &SlidersGroup::setMinimum); connect(minimumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), verticalSliders, &SlidersGroup::setMinimum); connect(maximumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), horizontalSliders, &SlidersGroup::setMaximum); connect(maximumSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), verticalSliders, &SlidersGroup::setMaximum); connect(invertedAppearance, &QCheckBox::toggled, horizontalSliders, &SlidersGroup::invertAppearance); connect(invertedAppearance, &QCheckBox::toggled, verticalSliders, &SlidersGroup::invertAppearance); connect(invertedKeyBindings, &QCheckBox::toggled, horizontalSliders, &SlidersGroup::invertKeyBindings); connect(invertedKeyBindings, &QCheckBox::toggled, verticalSliders, &SlidersGroup::invertKeyBindings); QGridLayout *controlsLayout = new QGridLayout; controlsLayout->addWidget(minimumLabel, 0, 0); controlsLayout->addWidget(maximumLabel, 1, 0); controlsLayout->addWidget(valueLabel, 2, 0); controlsLayout->addWidget(minimumSpinBox, 0, 1); controlsLayout->addWidget(maximumSpinBox, 1, 1); controlsLayout->addWidget(valueSpinBox, 2, 1); controlsLayout->addWidget(invertedAppearance, 0, 2); controlsLayout->addWidget(invertedKeyBindings, 1, 2); controlsLayout->addWidget(orientationCombo, 3, 0, 1, 3); controlsGroup->setLayout(controlsLayout); }
我们通过控制部件和滑块部件的信号和插槽来同步它们的行为。我们将每个控件小部件连接到水平和垂直滑块小部件组。我们还将orientationCombo连接到QStackedWidget,以便显示正确的“页面”。最后,我们在controlsGroup框中的QGridLayout中布局控件小部件。
SlidersGroup 类定义
class SlidersGroup : public QGroupBox
{
Q_OBJECT
public:
SlidersGroup(Qt::Orientation orientation, const QString &title,
QWidget *parent = nullptr);
signals:
void valueChanged(int value);
public slots:
void setValue(int value);
void setMinimum(int value);
void setMaximum(int value);
void invertAppearance(bool invert);
void invertKeyBindings(bool invert);
private:
QSlider *slider;
QScrollBar *scrollBar;
QDial *dial;
};
SliderGroup类继承自QGroupBox。它提供一个框架和一个标题,并包含一个QSlider、一个QScrollBar和一个QDial。 我们提供了一个valueChanged()信号和一个公共setValue()插槽,其功能与QAbstractSlider和QSpinBox中的插槽相同。此外,我们还实现了其他几个公共插槽来设置最小值和最大值,并反转滑块小部件的外观和键绑定。
SlidersGroup 类实现
SlidersGroup::SlidersGroup(Qt::Orientation orientation, const QString &title,
QWidget *parent)
: QGroupBox(title, parent)
{
slider = new QSlider(orientation);
slider->setFocusPolicy(Qt::StrongFocus);
slider->setTickPosition(QSlider::TicksBothSides);
slider->setTickInterval(10);
slider->setSingleStep(1);
scrollBar = new QScrollBar(orientation);
scrollBar->setFocusPolicy(Qt::StrongFocus);
dial = new QDial;
dial->setFocusPolicy(Qt::StrongFocus);
connect(slider, &QSlider::valueChanged, scrollBar, &QScrollBar::setValue);
connect(scrollBar, &QScrollBar::valueChanged, dial, &QDial::setValue);
connect(dial, &QDial::valueChanged, slider, &QSlider::setValue);
首先,我们创建具有适当属性的类似滑块的小部件。我们特别为每个小部件设置焦点策略。FocusPolicy是一种枚举类型,它定义了小部件在获取键盘焦点方面可以拥有的各种策略。strong焦点策略意味着小部件通过选项卡和单击接受焦点。 然后我们将这些小部件彼此连接起来,这样当其中一个小部件的当前值发生变化时,它们将保持同步。
connect(dial, &QDial::valueChanged, this, &SlidersGroup::valueChanged);
我们将dial的valueChanged()信号连接到SliderGroup的valueChanged()信号,以通知应用程序中的其他小部件(即控件小部件)已更改的值。
QBoxLayout::Direction direction; if (orientation == Qt::Horizontal) direction = QBoxLayout::TopToBottom; else direction = QBoxLayout::LeftToRight; QBoxLayout *slidersLayout = new QBoxLayout(direction); slidersLayout->addWidget(slider); slidersLayout->addWidget(scrollBar); slidersLayout->addWidget(dial); setLayout(slidersLayout); }
最后,根据构建时给定的方向,我们选择并创建组框中滑块小部件的布局。
void SlidersGroup::setValue(int value)
{
slider->setValue(value);
}
setValue()插槽设置QSlider的值。我们不需要在QScrollBar和QDial小部件上显式调用setValue(),因为QSlider在其值更改时将发出valueChanged()信号,从而触发domino效应。
void SlidersGroup::setMinimum(int value)
{
slider->setMinimum(value);
scrollBar->setMinimum(value);
dial->setMinimum(value);
}
void SlidersGroup::setMaximum(int value)
{
slider->setMaximum(value);
scrollBar->setMaximum(value);
dial->setMaximum(value);
}
Window类使用setMinimum()和setMaximum()插槽设置QSlider、QScrollBar和QDial小部件的范围。
void SlidersGroup::invertAppearance(bool invert)
{
slider->setInvertedAppearance(invert);
scrollBar->setInvertedAppearance(invert);
dial->setInvertedAppearance(invert);
}
void SlidersGroup::invertKeyBindings(bool invert)
{
slider->setInvertedControls(invert);
scrollBar->setInvertedControls(invert);
dial->setInvertedControls(invert);
}
InverteAppearance()和InverteKeyBindings()插槽控制子窗口小部件的InvertaPearance和InvertdControl属性。
相关资源下载如下网址:
滑动条示例,qt实现,供大家学习一下-C++文档类资源-CSDN下载










