| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example widgets/sliders |
| \title Sliders Example |
| \ingroup examples-widgets |
| \brief The Sliders example shows how to use the different types of sliders |
| available in Qt: QSlider, QScrollBar and QDial. |
| |
| Qt provides three types of slider-like widgets: QSlider, |
| QScrollBar and QDial. They all inherit most of their |
| functionality from QAbstractSlider, and can in theory replace |
| each other in an application since the differences only concern |
| their look and feel. This example shows what they look like, how |
| they work and how their behavior and appearance can be |
| manipulated through their properties. |
| |
| The example also demonstrates how signals and slots can be used to |
| synchronize the behavior of two or more widgets. |
| |
| \borderedimage sliders-example.png |
| \caption Screenshot of the Sliders example |
| |
| The Sliders example consists of two classes: |
| |
| \list |
| |
| \li \c SlidersGroup is a custom widget. It combines a QSlider, a |
| 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. |
| |
| \endlist |
| |
| First we will review the \c Window class, then we |
| will take a look at the \c SlidersGroup class. |
| |
| \section1 Window Class Definition |
| |
| \snippet widgets/sliders/window.h 0 |
| |
| The \c Window class inherits from QWidget. It displays the slider |
| widgets and allows the user to set their minimum, maximum and |
| current values and to customize their appearance, key bindings |
| and orientation. We use a private \c createControls() function to |
| create the widgets that provide these controlling mechanisms and |
| to connect them to the slider widgets. |
| |
| \section1 Window Class Implementation |
| |
| \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. |
| |
| \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 |
| 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 |
| between \c valueSpinBox and the \c SlidersGroup widgets. The |
| minimum and maximum values propagate through the connections we |
| created with \c createControls(). |
| |
| \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. |
| |
| After creating the labels, we create the two checkboxes. |
| Checkboxes are typically used to represent features in an |
| application that can be enabled or disabled. When \c |
| invertedAppearance is enabled, the slider values are inverted. |
| The table below shows the appearance for the different |
| slider-like widgets: |
| |
| \table |
| \header \li \li{2,1} QSlider \li{2,1} QScrollBar \li{2,1} QDial |
| \header \li \li Normal \li Inverted \li Normal \li Inverted \li Normal \li Inverted |
| \row \li Qt::Horizontal \li Left to right \li Right to left \li Left to right \li Right to left \li Clockwise \li Counterclockwise |
| \row \li Qt::Vertical \li Bottom to top \li Top to bottom \li Top to bottom \li Bottom to top \li Clockwise \li Counterclockwise |
| \endtable |
| |
| It is common to invert the appearance of a vertical QSlider. A |
| vertical slider that controls volume, for example, will typically |
| go from bottom to top (the non-inverted appearance), whereas a |
| vertical slider that controls the position of an object on screen |
| might go from top to bottom, because screen coordinates go from |
| top to bottom. |
| |
| When the \c invertedKeyBindings option is enabled (corresponding |
| to the QAbstractSlider::invertedControls property), the slider's |
| wheel and key events are inverted. The normal key bindings mean |
| that scrolling the mouse wheel "up" or using keys like page up |
| will increase the slider's current value towards its maximum. |
| Inverted, the same wheel and key events will move the value |
| toward the slider's minimum. This can be useful if the \e |
| appearance of a slider is inverted: Some users might expect the |
| keys to still work the same way on the value, whereas others |
| might expect \uicontrol PageUp to mean "up" on the screen. |
| |
| Note that for horizontal and vertical scroll bars, the key |
| bindings are inverted by default: \uicontrol PageDown increases the |
| current value, and \uicontrol PageUp decreases it. |
| |
| \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 |
| Up and \uicontrol Down keys on the keyboard to modify the value |
| currently displayed. The user can also type in the value |
| 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 7 |
| \snippet widgets/sliders/window.cpp 8 |
| |
| We synchronize the behavior of the control widgets and the slider |
| widgets through their signals and slots. We connect each control |
| widget to both the horizontal and vertical group of slider |
| widgets. We also connect \c orientationCombo to the |
| QStackedWidget, so that the correct "page" is shown. Finally, we |
| lay out the control widgets in a QGridLayout within the \c |
| controlsGroup group box. |
| |
| \section1 SlidersGroup Class Definition |
| |
| \snippet widgets/sliders/slidersgroup.h 0 |
| |
| The \c SlidersGroup class inherits from QGroupBox. It provides a |
| frame and a title, and contains a QSlider, a QScrollBar and a |
| QDial. |
| |
| We provide a \c valueChanged() signal and a public \c setValue() |
| 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. |
| |
| \section1 SlidersGroup Class Implementation |
| |
| \snippet widgets/sliders/slidersgroup.cpp 0 |
| |
| First we create the slider-like widgets with the appropriate |
| properties. In particular we set the focus policy for each |
| widget. Qt::FocusPolicy is an enum type that defines the various |
| policies a widget can have with respect to acquiring keyboard |
| focus. The Qt::StrongFocus policy means that the widget accepts |
| focus by both tabbing and clicking. |
| |
| 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. |
| |
| \snippet widgets/sliders/slidersgroup.cpp 5 |
| \snippet widgets/sliders/slidersgroup.cpp 6 |
| |
| The \c setValue() slot sets the value of the QSlider. We don't |
| need to explicitly call |
| \l{QAbstractSlider::setValue()}{setValue()} on the QScrollBar and |
| QDial widgets, since QSlider will emit the |
| \l{QAbstractSlider::valueChanged()}{valueChanged()} signal when |
| its value changes, triggering a domino effect. |
| |
| \snippet widgets/sliders/slidersgroup.cpp 7 |
| \snippet widgets/sliders/slidersgroup.cpp 8 |
| \codeline |
| \snippet widgets/sliders/slidersgroup.cpp 9 |
| \snippet widgets/sliders/slidersgroup.cpp 10 |
| |
| The \c setMinimum() and \c setMaximum() slots are used by the \c |
| Window class to set the range of the QSlider, QScrollBar, and |
| QDial widgets. |
| |
| \snippet widgets/sliders/slidersgroup.cpp 11 |
| \snippet widgets/sliders/slidersgroup.cpp 12 |
| \codeline |
| \snippet widgets/sliders/slidersgroup.cpp 13 |
| \snippet widgets/sliders/slidersgroup.cpp 14 |
| |
| The \c invertAppearance() and \c invertKeyBindings() slots |
| control the child widgets' |
| \l{QAbstractSlider::invertedAppearance}{invertedAppearance} and |
| \l{QAbstractSlider::invertedControls}{invertedControls} |
| properties. |
| */ |