「Qt Widget中文示例指南」如何实现一个滑动条(二)

Qt 是目前最先进、最完整的跨平台C++开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。

滑动条示例展示了如何使用Qt中可用的不同类型的滑动条:QSlider, QScrollBarQDial

Qt提供了三种类似滑动条的小部件:QSlider、QScrollBar和QDial,它们都继承了QAbstractSlider的大部分功能,并且理论上可以在应用程序中相互替换,因为差异只涉及它们的外观和样式。这个例子展示了它们是什么样子的,它们是如何工作的,以及如何通过它们的属性来操纵它们的操作和外观。

点击获取Qt Widget组件下载(Q技术交流:166830288)

本示例还演示了如何使用信号和槽来同步两个或多个小部件的操作,以及如何覆盖resizeEvent()来实现响应式布局。

在上文中(点击这里回顾>>),我们主要为大家介绍了Window类定义、Window类实现等,本文将继续介绍SlidersGroup类的定义和实现。

SlidersGroup类定义
cpp 复制代码
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

我们提供了一个valueChanged()信号和一个公共setValue()槽,其功能与QAbstractSlider和QSpinBox中的相同。此外,我们还实现了其他几个公共槽来设置最小值和最大值,并反转滑块小部件的外观以及键绑定,并设置方向。

SlidersGroup类实现
cpp 复制代码
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策略意味着小部件通过tab和click来接受焦点。

cpp 复制代码
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()信号,来将更改的值通知应用程序中的其他小部件(即控件小部件)。

cpp 复制代码
slidersLayout = new QBoxLayout(QBoxLayout::LeftToRight);
slidersLayout->addWidget(slider);
slidersLayout->addWidget(scrollBar);
slidersLayout->addWidget(dial);
setLayout(slidersLayout);
}

最后为组框内的滑块小部件创建布局,从滑块的水平排列开始。

cpp 复制代码
void SlidersGroup::setValue(int value)
{
slider->setValue(value);
}

setValue()槽设置QSlider的值,我们不需要在QScrollBar和QDial小部件上显式地调用setValue(),因为QSlider将在其值发生变化时发出valueChanged()信号,从而触发多米诺骨牌效应。

cpp 复制代码
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小部件的范围。

cpp 复制代码
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()插槽控制子部件的invertedAppearanceinvertedControls属性。

cpp 复制代码
void SlidersGroup::setOrientation(Qt::Orientation orientation)
{
slidersLayout->setDirection(orientation == Qt::Horizontal
? QBoxLayout::TopToBottom
: QBoxLayout::LeftToRight);
scrollBar->setOrientation(orientation);
slider->setOrientation(orientation);
}

setOrientation()插槽控制布局的方向和滑块的方向,在水平组中,滑块具有水平方向,并且彼此堆叠在一起。在垂直组中,滑块具有垂直方向,并且彼此相邻布局。

相关推荐
樱木Plus1 天前
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)
c++
blasit3 天前
笔记:Qt C++建立子线程做一个socket TCP常连接通信
c++·qt·tcp/ip
肆忆_4 天前
# 用 5 个问题学懂 C++ 虚函数(入门级)
c++
不想写代码的星星4 天前
虚函数表:C++ 多态背后的那个男人
c++
端平入洛6 天前
delete又未完全delete
c++
端平入洛7 天前
auto有时不auto
c++
哇哈哈20218 天前
信号量和信号
linux·c++
多恩Stone8 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
蜡笔小马8 天前
21.Boost.Geometry disjoint、distance、envelope、equals、expand和for_each算法接口详解
c++·算法·boost
超级大福宝8 天前
N皇后问题:经典回溯算法的一些分析
数据结构·c++·算法·leetcode