/****************************************************************************+ −
**+ −
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the documentation of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
/*!+ −
\example widgets/sliders+ −
\title Sliders Example+ −
+ −
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.+ −
+ −
\image sliders-example.png Screenshot of the Sliders example+ −
+ −
The Sliders example consists of two classes:+ −
+ −
\list+ −
+ −
\o \c SlidersGroup is a custom widget. It combines a QSlider, a+ −
QScrollBar and a QDial.+ −
+ −
\o \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 examples/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 examples/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 examples/widgets/sliders/window.cpp 1+ −
\snippet examples/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 examples/widgets/sliders/window.cpp 3+ −
\snippet examples/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 \o \o{2,1} QSlider \o{2,1} QScrollBar \o{2,1} QDial+ −
\header \o \o Normal \o Inverted \o Normal \o Inverted \o Normal \o Inverted+ −
\row \o Qt::Horizontal \o Left to right \o Right to left \o Left to right \o Right to left \o Clockwise \o Counterclockwise+ −
\row \o Qt::Vertical \o Bottom to top \o Top to bottom \o Top to bottom \o Bottom to top \o Clockwise \o 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 \key PageUp to mean "up" on the screen.+ −
+ −
Note that for horizontal and vertical scroll bars, the key+ −
bindings are inverted by default: \key PageDown increases the+ −
current value, and \key PageUp decreases it.+ −
+ −
\snippet examples/widgets/sliders/window.cpp 5+ −
\snippet examples/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 \key+ −
Up and \key 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 examples/widgets/sliders/window.cpp 7+ −
\snippet examples/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 examples/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 examples/widgets/sliders/slidersgroup.cpp 0+ −
+ −
First we create the slider-like widgets with the appropiate+ −
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 examples/widgets/sliders/slidersgroup.cpp 1+ −
\snippet examples/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 examples/widgets/sliders/slidersgroup.cpp 3+ −
\codeline+ −
\snippet examples/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 examples/widgets/sliders/slidersgroup.cpp 5+ −
\snippet examples/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 examples/widgets/sliders/slidersgroup.cpp 7+ −
\snippet examples/widgets/sliders/slidersgroup.cpp 8+ −
\codeline+ −
\snippet examples/widgets/sliders/slidersgroup.cpp 9+ −
\snippet examples/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 examples/widgets/sliders/slidersgroup.cpp 11+ −
\snippet examples/widgets/sliders/slidersgroup.cpp 12+ −
\codeline+ −
\snippet examples/widgets/sliders/slidersgroup.cpp 13+ −
\snippet examples/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.+ −
*/+ −