1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\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.
*/
|