summaryrefslogtreecommitdiffstats
path: root/examples/widgets
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-12-18 16:39:34 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-12-19 06:06:14 +0100
commitf3fb89ba298e1741320d8bfac9cbd0d503373bff (patch)
tree86d73060497357f6edea58ebcb26a8b74919f4dc /examples/widgets
parent4a19e97f70994bc8bb67e26533d18266b8a615bc (diff)
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. Pick-to: 6.7 6.6 Fixes: QTBUG-119977 Change-Id: I73a1bb215c956fa283291ebf0ea45ff9a975c727 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Diffstat (limited to 'examples/widgets')
-rw-r--r--examples/widgets/doc/src/sliders.qdoc88
-rw-r--r--examples/widgets/widgets/sliders/slidersgroup.cpp34
-rw-r--r--examples/widgets/widgets/sliders/slidersgroup.h6
-rw-r--r--examples/widgets/widgets/sliders/window.cpp97
-rw-r--r--examples/widgets/widgets/sliders/window.h8
5 files changed, 97 insertions, 136 deletions
diff --git a/examples/widgets/doc/src/sliders.qdoc b/examples/widgets/doc/src/sliders.qdoc
index 871adf0049..9bfb4abdc4 100644
--- a/examples/widgets/doc/src/sliders.qdoc
+++ b/examples/widgets/doc/src/sliders.qdoc
@@ -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.
*/
diff --git a/examples/widgets/widgets/sliders/slidersgroup.cpp b/examples/widgets/widgets/sliders/slidersgroup.cpp
index c5d01cdb37..87841c43f9 100644
--- a/examples/widgets/widgets/sliders/slidersgroup.cpp
+++ b/examples/widgets/widgets/sliders/slidersgroup.cpp
@@ -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]
diff --git a/examples/widgets/widgets/sliders/slidersgroup.h b/examples/widgets/widgets/sliders/slidersgroup.h
index 66821ca558..7e7d887018 100644
--- a/examples/widgets/widgets/sliders/slidersgroup.h
+++ b/examples/widgets/widgets/sliders/slidersgroup.h
@@ -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]
diff --git a/examples/widgets/widgets/sliders/window.cpp b/examples/widgets/widgets/sliders/window.cpp
index a2c2fe89eb..c62c3b83f5 100644
--- a/examples/widgets/widgets/sliders/window.cpp
+++ b/examples/widgets/widgets/sliders/window.cpp
@@ -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);
- connect(minimumSpinBox, &QSpinBox::valueChanged,
- horizontalSliders, &SlidersGroup::setMinimum);
+//! [5] //! [6]
+ connect(slidersGroup, &SlidersGroup::valueChanged,
+ valueSpinBox, &QSpinBox::setValue);
+ connect(valueSpinBox, &QSpinBox::valueChanged,
+ slidersGroup, &SlidersGroup::setValue);
connect(minimumSpinBox, &QSpinBox::valueChanged,
- verticalSliders, &SlidersGroup::setMinimum);
- connect(maximumSpinBox, &QSpinBox::valueChanged,
- horizontalSliders, &SlidersGroup::setMaximum);
+ slidersGroup, &SlidersGroup::setMinimum);
connect(maximumSpinBox, &QSpinBox::valueChanged,
- verticalSliders, &SlidersGroup::setMaximum);
+ slidersGroup, &SlidersGroup::setMaximum);
connect(invertedAppearance, &QCheckBox::toggled,
- horizontalSliders, &SlidersGroup::invertAppearance);
- connect(invertedAppearance, &QCheckBox::toggled,
- verticalSliders, &SlidersGroup::invertAppearance);
- connect(invertedKeyBindings, &QCheckBox::toggled,
- horizontalSliders, &SlidersGroup::invertKeyBindings);
+ slidersGroup, &SlidersGroup::invertAppearance);
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());
-
- if ((aspectRatio < 1.0) && (oldAspectRatio > 1.0)) {
- layout->removeWidget(controlsGroup);
- layout->removeWidget(stackedWidget);
+ const double aspectRatio = double(width()) / double(height());
- 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]
diff --git a/examples/widgets/widgets/sliders/window.h b/examples/widgets/widgets/sliders/window.h
index fa627eabd3..8d7338f27c 100644
--- a/examples/widgets/widgets/sliders/window.h
+++ b/examples/widgets/widgets/sliders/window.h
@@ -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]