Update Sliders example
Simplify the "responsive layout" implementation. Just use a QBoxLayout with changing direction instead of repopulating a QGridLayout, and change the orientation of one set of sliders instead of creating two sets in a stacked layout. Simplify the resizeEvent() implementation accordingly. Update the documentation snippet text to match the code, and document the resizeEvent() override. Fixes: QTBUG-119977 Change-Id: I73a1bb215c956fa283291ebf0ea45ff9a975c727 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> (cherry picked from commit f3fb89ba298e1741320d8bfac9cbd0d503373bff) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 2d3ee8ac34bdf30ffc14054a8aeb64ba292bb96e)
This commit is contained in:
parent
493c596a6c
commit
b791b19d3d
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 23 KiB |
@ -18,7 +18,8 @@
|
||||
manipulated through their properties.
|
||||
|
||||
The example also demonstrates how signals and slots can be used to
|
||||
synchronize the behavior of two or more widgets.
|
||||
synchronize the behavior of two or more widgets, and how to override
|
||||
\l{QWidget::}{resizeEvent()} to implement a responsive layout.
|
||||
|
||||
\borderedimage sliders-example.png
|
||||
\caption Screenshot of the Sliders example
|
||||
@ -31,10 +32,8 @@
|
||||
QScrollBar and a QDial.
|
||||
|
||||
\li \c Window is the main widget combining a QGroupBox and a
|
||||
QStackedWidget. In this example, the QStackedWidget provides a
|
||||
stack of two \c SlidersGroup widgets. The QGroupBox contain
|
||||
several widgets that control the behavior of the slider-like
|
||||
widgets.
|
||||
SlidersGroup. The QGroupBox contains several widgets that control
|
||||
the behavior of the slider-like widgets.
|
||||
|
||||
\endlist
|
||||
|
||||
@ -56,28 +55,14 @@
|
||||
|
||||
\snippet widgets/sliders/window.cpp 0
|
||||
|
||||
In the constructor we first create the two \c SlidersGroup
|
||||
widgets that display the slider widgets horizontally and
|
||||
vertically, and add them to the QStackedWidget. QStackedWidget
|
||||
provides a stack of widgets where only the top widget is visible.
|
||||
With \c createControls() we create a connection from a
|
||||
controlling widget to the QStackedWidget, making the user able to
|
||||
choose between horizontal and vertical orientation of the slider
|
||||
widgets. The rest of the controlling mechanisms is implemented by
|
||||
the same function call.
|
||||
In the constructor we first create the \c SlidersGroup widget
|
||||
that displays the slider widgets. With \c createControls() we
|
||||
create the controlling widgets, and connect those to to the
|
||||
sliders.
|
||||
|
||||
\snippet widgets/sliders/window.cpp 1
|
||||
\snippet widgets/sliders/window.cpp 2
|
||||
|
||||
Then we connect the \c horizontalSliders, \c verticalSliders and
|
||||
\c valueSpinBox to each other, so that the slider widgets and the
|
||||
control widget will behave synchronized when the current value of
|
||||
one of them changes. The \c valueChanged() signal is emitted with
|
||||
the new value as argument. The \c setValue() slot sets the
|
||||
current value of the widget to the new value, and emits \c
|
||||
valueChanged() if the new value is different from the old one.
|
||||
|
||||
We put the group of control widgets and the stacked widget in a
|
||||
We put the groups of control widgets and the sliders in a
|
||||
horizontal layout before we initialize the minimum, maximum and
|
||||
current values. The initialization of the current value will
|
||||
propagate to the slider widgets through the connection we made
|
||||
@ -85,15 +70,14 @@
|
||||
minimum and maximum values propagate through the connections we
|
||||
created with \c createControls().
|
||||
|
||||
\snippet widgets/sliders/window.cpp 2
|
||||
\snippet widgets/sliders/window.cpp 3
|
||||
\snippet widgets/sliders/window.cpp 4
|
||||
|
||||
In the private \c createControls() function, we let a QGroupBox
|
||||
(\c controlsGroup) display the control widgets. A group box can
|
||||
provide a frame, a title and a keyboard shortcut, and displays
|
||||
various other widgets inside itself. The group of control widgets
|
||||
is composed by two checkboxes, three spin boxes (with labels) and
|
||||
one combobox.
|
||||
is composed by two checkboxes, and three spin boxes with labels.
|
||||
|
||||
After creating the labels, we create the two checkboxes.
|
||||
Checkboxes are typically used to represent features in an
|
||||
@ -131,8 +115,8 @@
|
||||
bindings are inverted by default: \uicontrol PageDown increases the
|
||||
current value, and \uicontrol PageUp decreases it.
|
||||
|
||||
\snippet widgets/sliders/window.cpp 4
|
||||
\snippet widgets/sliders/window.cpp 5
|
||||
\snippet widgets/sliders/window.cpp 6
|
||||
|
||||
Then we create the spin boxes. QSpinBox allows the user to choose
|
||||
a value by clicking the up and down buttons or pressing the \uicontrol
|
||||
@ -141,14 +125,15 @@
|
||||
manually. The spin boxes control the minimum, maximum and current
|
||||
values for the QSlider, QScrollBar, and QDial widgets.
|
||||
|
||||
We create a QComboBox that allows the user to choose the
|
||||
orientation of the slider widgets. The QComboBox widget is a
|
||||
combined button and popup list. It provides a means of presenting
|
||||
a list of options to the user in a way that takes up the minimum
|
||||
amount of screen space.
|
||||
\snippet widgets/sliders/window.cpp 6
|
||||
|
||||
\snippet widgets/sliders/window.cpp 7
|
||||
\snippet widgets/sliders/window.cpp 8
|
||||
Then we connect the \c slidersGroup and the \c valueSpinBox to each
|
||||
other, so that the slider widgets and the control widget will behave
|
||||
synchronized when the current value of one of them changes.
|
||||
The \c valueChanged() signal is emitted with the new value as
|
||||
argument. The \c setValue() slot sets the current value of the
|
||||
widget to the new value, and emits \c valueChanged() if the new
|
||||
value is different from the old one.
|
||||
|
||||
We synchronize the behavior of the control widgets and the slider
|
||||
widgets through their signals and slots. We connect each control
|
||||
@ -158,6 +143,17 @@
|
||||
lay out the control widgets in a QGridLayout within the \c
|
||||
controlsGroup group box.
|
||||
|
||||
\snippet widgets/sliders/window.cpp 7
|
||||
|
||||
Lastly, we override resizeEvent() from QWidget. We guard against
|
||||
dividing by zero, and otherwise compute the aspect ratio of the
|
||||
widget. If the window has a portrait format, then we set the
|
||||
layout to organize the groups of control widgets and sliders
|
||||
vertically, and we give the sliders a horizontal orientation.
|
||||
If the window has a landscape format, then we change the layout
|
||||
to show the sliders and controlling widgets side by side, and
|
||||
give the sliders a vertical orientation.
|
||||
|
||||
\section1 SlidersGroup Class Definition
|
||||
|
||||
\snippet widgets/sliders/slidersgroup.h 0
|
||||
@ -170,7 +166,8 @@
|
||||
slot with equivalent functionality to the ones in QAbstractSlider
|
||||
and QSpinBox. In addition, we implement several other public
|
||||
slots to set the minimum and maximum value, and invert the slider
|
||||
widgets' appearance as well as key bindings.
|
||||
widgets' appearance as well as key bindings, and set the
|
||||
orientation.
|
||||
|
||||
\section1 SlidersGroup Class Implementation
|
||||
|
||||
@ -183,24 +180,21 @@
|
||||
focus. The Qt::StrongFocus policy means that the widget accepts
|
||||
focus by both tabbing and clicking.
|
||||
|
||||
\snippet widgets/sliders/slidersgroup.cpp 1
|
||||
|
||||
Then we connect the widgets with each other, so that they will
|
||||
stay synchronized when the current value of one of them changes.
|
||||
|
||||
\snippet widgets/sliders/slidersgroup.cpp 1
|
||||
\snippet widgets/sliders/slidersgroup.cpp 2
|
||||
|
||||
We connect \c {dial}'s \c valueChanged() signal to the
|
||||
\c{SlidersGroup}'s \c valueChanged() signal, to notify the other
|
||||
widgets in the application (i.e., the control widgets) of the
|
||||
changed value.
|
||||
|
||||
\snippet widgets/sliders/slidersgroup.cpp 3
|
||||
\codeline
|
||||
\snippet widgets/sliders/slidersgroup.cpp 4
|
||||
|
||||
Finally, depending on the \l {Qt::Orientation}{orientation} given
|
||||
at the time of construction, we choose and create the layout for
|
||||
the slider widgets within the group box.
|
||||
Finally, we create the layout for the slider widgets within the
|
||||
group box. We start with a horizontal arrangement of the sliders.
|
||||
|
||||
\snippet widgets/sliders/slidersgroup.cpp 5
|
||||
\snippet widgets/sliders/slidersgroup.cpp 6
|
||||
@ -233,4 +227,12 @@
|
||||
\l{QAbstractSlider::invertedAppearance}{invertedAppearance} and
|
||||
\l{QAbstractSlider::invertedControls}{invertedControls}
|
||||
properties.
|
||||
|
||||
\snippet widgets/sliders/slidersgroup.cpp 15
|
||||
|
||||
The setOrientation() slot controls the direction of the layout
|
||||
and the orientation of the sliders. In a horizontal group, the
|
||||
sliders have a horizontal orientation, and are laid out on top
|
||||
of each other. In a vertical group, the sliders have a vertical
|
||||
orientation, and are laid out next to each other.
|
||||
*/
|
||||
|
@ -9,39 +9,28 @@
|
||||
#include <QSlider>
|
||||
|
||||
//! [0]
|
||||
SlidersGroup::SlidersGroup(Qt::Orientation orientation, const QString &title,
|
||||
QWidget *parent)
|
||||
SlidersGroup::SlidersGroup(const QString &title, QWidget *parent)
|
||||
: QGroupBox(title, parent)
|
||||
{
|
||||
slider = new QSlider(orientation);
|
||||
slider = new QSlider;
|
||||
slider->setFocusPolicy(Qt::StrongFocus);
|
||||
slider->setTickPosition(QSlider::TicksBothSides);
|
||||
slider->setTickInterval(10);
|
||||
slider->setSingleStep(1);
|
||||
|
||||
scrollBar = new QScrollBar(orientation);
|
||||
scrollBar = new QScrollBar;
|
||||
scrollBar->setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
dial = new QDial;
|
||||
dial->setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
//! [0] //! [1]
|
||||
connect(slider, &QSlider::valueChanged, scrollBar, &QScrollBar::setValue);
|
||||
connect(scrollBar, &QScrollBar::valueChanged, dial, &QDial::setValue);
|
||||
connect(dial, &QDial::valueChanged, slider, &QSlider::setValue);
|
||||
//! [0] //! [1]
|
||||
connect(dial, &QDial::valueChanged, this, &SlidersGroup::valueChanged);
|
||||
//! [1] //! [2]
|
||||
|
||||
//! [2] //! [3]
|
||||
QBoxLayout::Direction direction;
|
||||
//! [3] //! [4]
|
||||
|
||||
if (orientation == Qt::Horizontal)
|
||||
direction = QBoxLayout::TopToBottom;
|
||||
else
|
||||
direction = QBoxLayout::LeftToRight;
|
||||
|
||||
QBoxLayout *slidersLayout = new QBoxLayout(direction);
|
||||
//! [1] //! [4]
|
||||
slidersLayout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
slidersLayout->addWidget(slider);
|
||||
slidersLayout->addWidget(scrollBar);
|
||||
slidersLayout->addWidget(dial);
|
||||
@ -96,3 +85,14 @@ void SlidersGroup::invertKeyBindings(bool invert)
|
||||
dial->setInvertedControls(invert);
|
||||
}
|
||||
//! [14]
|
||||
|
||||
//! [15]
|
||||
void SlidersGroup::setOrientation(Qt::Orientation orientation)
|
||||
{
|
||||
slidersLayout->setDirection(orientation == Qt::Horizontal
|
||||
? QBoxLayout::TopToBottom
|
||||
: QBoxLayout::LeftToRight);
|
||||
scrollBar->setOrientation(orientation);
|
||||
slider->setOrientation(orientation);
|
||||
}
|
||||
//! [15]
|
||||
|
@ -10,6 +10,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QDial;
|
||||
class QScrollBar;
|
||||
class QSlider;
|
||||
class QBoxLayout;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
//! [0]
|
||||
@ -18,8 +19,7 @@ class SlidersGroup : public QGroupBox
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SlidersGroup(Qt::Orientation orientation, const QString &title,
|
||||
QWidget *parent = nullptr);
|
||||
SlidersGroup(const QString &title, QWidget *parent = nullptr);
|
||||
|
||||
signals:
|
||||
void valueChanged(int value);
|
||||
@ -30,11 +30,13 @@ public slots:
|
||||
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;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
@ -13,29 +13,15 @@
|
||||
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);
|
||||
slidersGroup = new SlidersGroup(tr("Sliders"));
|
||||
|
||||
createControls(tr("Controls"));
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
connect(horizontalSliders, &SlidersGroup::valueChanged,
|
||||
//! [1] //! [2]
|
||||
verticalSliders, &SlidersGroup::setValue);
|
||||
connect(verticalSliders, &SlidersGroup::valueChanged,
|
||||
valueSpinBox, &QSpinBox::setValue);
|
||||
connect(valueSpinBox, &QSpinBox::valueChanged,
|
||||
horizontalSliders, &SlidersGroup::setValue);
|
||||
|
||||
layout = new QGridLayout;
|
||||
layout->addWidget(stackedWidget, 0, 1);
|
||||
layout->addWidget(controlsGroup, 0, 0);
|
||||
|
||||
layout = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
layout->addWidget(controlsGroup);
|
||||
layout->addWidget(slidersGroup);
|
||||
setLayout(layout);
|
||||
|
||||
minimumSpinBox->setValue(0);
|
||||
@ -44,11 +30,11 @@ Window::Window(QWidget *parent)
|
||||
|
||||
setWindowTitle(tr("Sliders"));
|
||||
}
|
||||
//! [2]
|
||||
//! [1]
|
||||
|
||||
//! [3]
|
||||
//! [2]
|
||||
void Window::createControls(const QString &title)
|
||||
//! [3] //! [4]
|
||||
//! [2] //! [3]
|
||||
{
|
||||
controlsGroup = new QGroupBox(title);
|
||||
|
||||
@ -59,9 +45,9 @@ void Window::createControls(const QString &title)
|
||||
invertedAppearance = new QCheckBox(tr("Inverted appearance"));
|
||||
invertedKeyBindings = new QCheckBox(tr("Inverted key bindings"));
|
||||
|
||||
//! [4] //! [5]
|
||||
//! [3] //! [4]
|
||||
minimumSpinBox = new QSpinBox;
|
||||
//! [5] //! [6]
|
||||
//! [4] //! [5]
|
||||
minimumSpinBox->setRange(-100, 100);
|
||||
minimumSpinBox->setSingleStep(1);
|
||||
|
||||
@ -73,30 +59,19 @@ void Window::createControls(const QString &title)
|
||||
valueSpinBox->setRange(-100, 100);
|
||||
valueSpinBox->setSingleStep(1);
|
||||
|
||||
orientationCombo = new QComboBox;
|
||||
orientationCombo->addItem(tr("Horizontal slider-like widgets"));
|
||||
orientationCombo->addItem(tr("Vertical slider-like widgets"));
|
||||
|
||||
//! [6] //! [7]
|
||||
connect(orientationCombo, &QComboBox::activated,
|
||||
//! [7] //! [8]
|
||||
stackedWidget, &QStackedWidget::setCurrentIndex);
|
||||
//! [5] //! [6]
|
||||
connect(slidersGroup, &SlidersGroup::valueChanged,
|
||||
valueSpinBox, &QSpinBox::setValue);
|
||||
connect(valueSpinBox, &QSpinBox::valueChanged,
|
||||
slidersGroup, &SlidersGroup::setValue);
|
||||
connect(minimumSpinBox, &QSpinBox::valueChanged,
|
||||
horizontalSliders, &SlidersGroup::setMinimum);
|
||||
connect(minimumSpinBox, &QSpinBox::valueChanged,
|
||||
verticalSliders, &SlidersGroup::setMinimum);
|
||||
slidersGroup, &SlidersGroup::setMinimum);
|
||||
connect(maximumSpinBox, &QSpinBox::valueChanged,
|
||||
horizontalSliders, &SlidersGroup::setMaximum);
|
||||
connect(maximumSpinBox, &QSpinBox::valueChanged,
|
||||
verticalSliders, &SlidersGroup::setMaximum);
|
||||
slidersGroup, &SlidersGroup::setMaximum);
|
||||
connect(invertedAppearance, &QCheckBox::toggled,
|
||||
horizontalSliders, &SlidersGroup::invertAppearance);
|
||||
connect(invertedAppearance, &QCheckBox::toggled,
|
||||
verticalSliders, &SlidersGroup::invertAppearance);
|
||||
slidersGroup, &SlidersGroup::invertAppearance);
|
||||
connect(invertedKeyBindings, &QCheckBox::toggled,
|
||||
horizontalSliders, &SlidersGroup::invertKeyBindings);
|
||||
connect(invertedKeyBindings, &QCheckBox::toggled,
|
||||
verticalSliders, &SlidersGroup::invertKeyBindings);
|
||||
slidersGroup, &SlidersGroup::invertKeyBindings);
|
||||
|
||||
QGridLayout *controlsLayout = new QGridLayout;
|
||||
controlsLayout->addWidget(minimumLabel, 0, 0);
|
||||
@ -107,40 +82,26 @@ void Window::createControls(const QString &title)
|
||||
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);
|
||||
|
||||
}
|
||||
//! [8]
|
||||
//! [6]
|
||||
|
||||
|
||||
void Window::resizeEvent(QResizeEvent *e)
|
||||
//! [7]
|
||||
void Window::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
Q_UNUSED(e);
|
||||
if (width() == 0 || height() == 0)
|
||||
return;
|
||||
|
||||
const double aspectRatio = double(width()) / double(height());
|
||||
const double aspectRatio = double(width()) / double(height());
|
||||
|
||||
if ((aspectRatio < 1.0) && (oldAspectRatio > 1.0)) {
|
||||
layout->removeWidget(controlsGroup);
|
||||
layout->removeWidget(stackedWidget);
|
||||
|
||||
layout->addWidget(stackedWidget, 1, 0);
|
||||
layout->addWidget(controlsGroup, 0, 0);
|
||||
|
||||
oldAspectRatio = aspectRatio;
|
||||
}
|
||||
else if ((aspectRatio > 1.0) && (oldAspectRatio < 1.0)) {
|
||||
layout->removeWidget(controlsGroup);
|
||||
layout->removeWidget(stackedWidget);
|
||||
|
||||
layout->addWidget(stackedWidget, 0, 1);
|
||||
layout->addWidget(controlsGroup, 0, 0);
|
||||
|
||||
oldAspectRatio = aspectRatio;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! [7]
|
||||
|
@ -29,9 +29,7 @@ private:
|
||||
void createControls(const QString &title);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
|
||||
SlidersGroup *horizontalSliders;
|
||||
SlidersGroup *verticalSliders;
|
||||
QStackedWidget *stackedWidget;
|
||||
SlidersGroup *slidersGroup;
|
||||
|
||||
QGroupBox *controlsGroup;
|
||||
QLabel *minimumLabel;
|
||||
@ -42,9 +40,7 @@ private:
|
||||
QSpinBox *minimumSpinBox;
|
||||
QSpinBox *maximumSpinBox;
|
||||
QSpinBox *valueSpinBox;
|
||||
QComboBox *orientationCombo;
|
||||
QGridLayout *layout;
|
||||
double oldAspectRatio;
|
||||
QBoxLayout *layout;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user