滑动条示例
滑动条示例展示了如何在Qt中使用各种类型的滑动条:QSlider、QScrollBar 和 QDial。
Qt提供了三种类型的类似滑动条的控件:QSlider、QScrollBar 和 QDial。它们大多数功能都继承自 QAbstractSlider,在理论上,可以在应用程序中相互替换,因为它们之间的区别仅限于外观和感觉。本例展示了它们的外观、工作原理以及如何通过其属性来操作其行为和外观。
示例还演示了如何使用信号和槽同步两个或多个控件的行为,以及如何覆盖 resizeEvent() 实现响应式布局。
滑动条示例截图
滑动条示例由两个类组成
SlidersGroup
是一个自定义控件。它将一个 QSlider、一个 QScrollBar 和一个 QDial 结合在一起。Window
是主控件,结合了一个 QGroupBox 和一个 SlidersGroup。该 QGroupBox 包含了几个控件,用于控制类似滑动条的控件的行为。
首先我们将回顾 Window
类,然后我们将看看 SlidersGroup
类。
窗口类定义
class Window : public QWidget { Q_OBJECT public: Window(QWidget *parent = nullptr); private: void createControls(const QString &title); void resizeEvent(QResizeEvent *e); SlidersGroup *slidersGroup; QGroupBox *controlsGroup; QLabel *minimumLabel; QLabel *maximumLabel; QLabel *valueLabel; QCheckBox *invertedAppearance; QCheckBox *invertedKeyBindings; QSpinBox *minimumSpinBox; QSpinBox *maximumSpinBox; QSpinBox *valueSpinBox; QBoxLayout *layout; };
Window
类从 QWidget 继承。它显示滑动条控件,并允许用户设置它们的最大、最小和当前值,可以自定义它们的外观、键盘绑定和方向。我们使用一个私有的 createControls()
函数来创建控件,这提供控制机制并将它们连接到滑动条控件。
窗口类实现
Window::Window(QWidget *parent) : QWidget(parent) { slidersGroup = new SlidersGroup(tr("Sliders")); createControls(tr("Controls"));
在构造函数中,我们首先创建了一个 SlidersGroup
控件,用于显示滑动条控件。通过 createControls()
创建控制控件,并将它们连接到滑动条。
layout = new QBoxLayout(QBoxLayout::LeftToRight); layout->addWidget(controlsGroup); layout->addWidget(slidersGroup); setLayout(layout); minimumSpinBox->setValue(0); maximumSpinBox->setValue(20); valueSpinBox->setValue(5); setWindowTitle(tr("Sliders")); }
在初始化最大、最小和当前值之前,我们将控件组的控件和滑动条放入一个水平布局中。当前值的初始化将通过我们在 valueSpinBox
和 SlidersGroup
控件之间建立的连接传播到滑动条控件。最小和最大值的传播将通过 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"));
在私有的 createControls()
函数中,我们允许一个 QGroupBox (controlsGroup
)显示控制小部件。组合框可以提供框架、标题和键盘快捷键,并在其内部显示各种其他小部件。控制小部件的组由两个复选框和三个带有标签的微调框组成。
创建标签后,我们创建了两个复选框。复选框通常用于表示应用程序中可以启用或禁用的功能。当 invertedAppearance
被启用时,滑块值被反转。下表显示了不同滑块类似小部件的外观
QSlider | QScrollBar | QDial | ||||
---|---|---|---|---|---|---|
正常 | 反转 | 正常 | 反转 | 正常 | 反转 | |
Qt::Horizontal | 从左到右 | 从右到左 | 从左到右 | 从右到左 | 顺时针 | 逆时针 |
Qt::Vertical | 从下到上 | 从上到下 | 从上到下 | 从下到上 | 顺时针 | 逆时针 |
通常反转垂直 QSlider 的外观。例如,控制音量的垂直滑块将通常从底部到顶部(非反转外观),而控制屏幕上对象位置的水平滑块可能会从顶部到底部,因为屏幕坐标从顶部到底部。
当 invertedKeyBindings
选项被启用(对应于 QAbstractSlider::invertedControls 属性)时,滑块的小轮和键盘事件被反转。正常按键绑定意味着滚动鼠标滚轮 "向上" 或使用 PageUp 等键将增加滑块的当前值。反转后,相同的鼠标滚轮和键盘事件将值移动到滑块的最小值。这可以很有用,如果滑块的 外观 被反转:一些用户可能期望键对值仍然按相同的方式工作,而其他用户可能期望 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);
然后我们创建微调框。 QSpinBox 允许用户通过单击上下按钮或按键盘上的 Up 和 Down 键来选择值,以修改当前显示的值。用户还可以手动输入值。微调框控制 QSlider、QScrollBar 和 QDial 小部件的最小、最大和当前值。
connect(slidersGroup, &SlidersGroup::valueChanged, valueSpinBox, &QSpinBox::setValue); connect(valueSpinBox, &QSpinBox::valueChanged, slidersGroup, &SlidersGroup::setValue); connect(minimumSpinBox, &QSpinBox::valueChanged, slidersGroup, &SlidersGroup::setMinimum); connect(maximumSpinBox, &QSpinBox::valueChanged, slidersGroup, &SlidersGroup::setMaximum); connect(invertedAppearance, &QCheckBox::toggled, slidersGroup, &SlidersGroup::invertAppearance); connect(invertedKeyBindings, &QCheckBox::toggled, slidersGroup, &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); controlsGroup->setLayout(controlsLayout); }
然后我们将 slidersGroup
和 valueSpinBox
相互连接,这样当其中一个的当前值变化时,滑块小部件和控制小部件的行为将会同步。valueChanged()
信号被带新值的参数发射。setValue()
插槽将小部件的当前值设置为新值,如果新值与旧值不同,则发射 valueChanged()
。
我们通过信号和插槽同步控制小部件和滑块小部件的行为。我们将每个控制小部件连接到水平和垂直滑块小部件组。我们还将 orientationCombo
连接到 QStackedWidget,以便显示正确的 "页面"。最后,我们在组合框 controlsGroup
内部的 QGridLayout 中排列控制小部件。
void Window::resizeEvent(QResizeEvent *) { if (width() == 0 || height() == 0) return; const double aspectRatio = double(width()) / double(height()); if (aspectRatio < 1.0) { layout->setDirection(QBoxLayout::TopToBottom); slidersGroup->setOrientation(Qt::Horizontal); } else if (aspectRatio > 1.0) { layout->setDirection(QBoxLayout::LeftToRight); slidersGroup->setOrientation(Qt::Vertical); } }
最后,我们从 QWidget 中重写了 resizeEvent() 函数。我们防止了除以零的错误,并计算了小部件的宽高比。如果窗口是纵向格式,则将布局设置为垂直组织控制小部件和滑动条的组,并给滑动条一个水平方向。如果窗口是横向格式,则将布局改为显示滑动条和控制小部件并排,并给滑动条一个垂直方向。
SlidersGroup 类定义
class SlidersGroup : public QGroupBox { Q_OBJECT public: SlidersGroup(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); void setOrientation(Qt::Orientation orientation); private: QSlider *slider; QScrollBar *scrollBar; QDial *dial; QBoxLayout *slidersLayout; };
SlidersGroup
类继承自 QGroupBox。它提供了一个框架和一个标题,并包含一个 QSlider,一个 QScrollBar 和一个 QDial。
我们提供了一个与 QAbstractSlider 和 QSpinBox 中的功能相等的 valueChanged()
信号和一个公共的 setValue()
槽。此外,我们还实现了几个其他公共槽来设置最小值和最大值,以及翻转滑动小部件的外观以及按键绑定,并设置方向。
SlidersGroup 类实现
SlidersGroup::SlidersGroup(const QString &title, QWidget *parent) : QGroupBox(title, parent) { slider = new QSlider; slider->setFocusPolicy(Qt::StrongFocus); slider->setTickPosition(QSlider::TicksBothSides); slider->setTickInterval(10); slider->setSingleStep(1); scrollBar = new QScrollBar; scrollBar->setFocusPolicy(Qt::StrongFocus); dial = new QDial; dial->setFocusPolicy(Qt::StrongFocus);
首先,我们创建了具有适当属性的类似滑动条的控件。特别是,我们为每个控件设置了焦点策略。Qt::FocusPolicy 是一个枚举类型,定义了控件可以具有的各种与获取键盘焦点相关的策略。Qt::StrongFocus 策略表示控件可以通过制表符键和点击来接受焦点。
connect(slider, &QSlider::valueChanged, scrollBar, &QScrollBar::setValue); connect(scrollBar, &QScrollBar::valueChanged, dial, &QDial::setValue); connect(dial, &QDial::valueChanged, slider, &QSlider::setValue); connect(dial, &QDial::valueChanged, this, &SlidersGroup::valueChanged);
然后,我们连接了这些控件,以便在它们的当前值变化时它们将保持同步。
我们将 dial
的 valueChanged()
信号连接到 SlidersGroup
的 valueChanged()
信号,以通知应用程序中的其他控件(即控制控件)已更改的值。
slidersLayout = new QBoxLayout(QBoxLayout::LeftToRight); slidersLayout->addWidget(slider); slidersLayout->addWidget(scrollBar); slidersLayout->addWidget(dial); setLayout(slidersLayout); }
最后,我们在组合框内部创建了滑动小部件的布局。我们从滑动条的横向排列开始。
void SlidersGroup::setValue(int value) { slider->setValue(value); }
setValue()
槽设置 QSlider 的值。我们不需要显式地调用 setValue() 函数,因为在 QSlider 的值变化时,它将发出 valueChanged() 信号,从而触发连锁反应。
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); }
setMinimum()
和 setMaximum()
槽由 Window
类用于设置 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); }
invertAppearance()
和 invertKeyBindings()
槽控制子控件的 invertedAppearance 和 invertedControls 属性。
void SlidersGroup::setOrientation(Qt::Orientation orientation) { slidersLayout->setDirection(orientation == Qt::Horizontal ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); scrollBar->setOrientation(orientation); slider->setOrientation(orientation); }
setOrientation()
槽控制布局的方向和滑动条的方向。在水平组中,滑动条有水平方向,堆叠在一起。在垂直组中,滑动条有垂直方向,并并列排放。
© 2024 Qt 公司有限。包含在本处的文档贡献是各自所有者的版权。本处提供的文档是在自由软件基金会发布、 GNU 自由文档许可第 1.3 版的条款下许可的。Qt 和相应的标志是芬兰的 The Qt Company Ltd. 和/或世界其他国家的商标。所有其他商标均为各自所有者的财产。