Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qdial.cpp
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#
include
"qdial.h"
6
7
#
include
<
qapplication
.
h
>
8
#
include
<
qbitmap
.
h
>
9
#
include
<
qcolor
.
h
>
10
#
include
<
qevent
.
h
>
11
#
include
<
qpainter
.
h
>
12
#
include
<
qpolygon
.
h
>
13
#
include
<
qregion
.
h
>
14
#
include
<
qstyle
.
h
>
15
#
include
<
qstylepainter
.
h
>
16
#
include
<
qstyleoption
.
h
>
17
#
include
<
qslider
.
h
>
18
#
include
<
private
/
qabstractslider_p
.
h
>
19
#
include
<
private
/
qmath_p
.
h
>
20
#
if
QT_CONFIG
(
accessibility
)
21
#
include
"qaccessible.h"
22
#
endif
23
#
include
<
qmath
.
h
>
24
25
QT_BEGIN_NAMESPACE
26
27
class
QDialPrivate
:
public
QAbstractSliderPrivate
28
{
29
Q_DECLARE_PUBLIC(QDial)
30
public
:
31
QDialPrivate
()
32
{
33
wrapping
=
false
;
34
tracking
=
true
;
35
doNotEmit
=
false
;
36
target
=
qreal
(3.7);
37
}
38
39
qreal
target
;
40
uint
showNotches
: 1;
41
uint
wrapping
: 1;
42
uint
doNotEmit
: 1;
43
44
int
valueFromPoint
(
const
QPointF &)
const
;
45
double
angle
(
const
QPoint &,
const
QPoint &)
const
;
46
void
init
();
47
virtual
int
bound
(
int
val)
const
override
;
48
};
49
50
void
QDialPrivate
::
init
()
51
{
52
Q_Q(QDial);
53
showNotches
=
false
;
54
q->setFocusPolicy(Qt::WheelFocus);
55
}
56
57
int
QDialPrivate
::
bound
(
int
val)
const
58
{
59
if
(
wrapping
) {
60
if
((val >= minimum) && (val <= maximum))
61
return
val;
62
if
(minimum == maximum)
63
return
minimum;
64
val = minimum + ((val - minimum) % (maximum - minimum));
65
if
(val < minimum)
66
val += maximum - minimum;
67
return
val;
68
}
else
{
69
return
QAbstractSliderPrivate::bound(val);
70
}
71
}
72
73
/*!
74
Initialize \a option with the values from this QDial. This method
75
is useful for subclasses when they need a QStyleOptionSlider, but don't want
76
to fill in all the information themselves.
77
78
\sa QStyleOption::initFrom()
79
*/
80
void
QDial::initStyleOption(QStyleOptionSlider *option)
const
81
{
82
if
(!option)
83
return
;
84
85
Q_D(
const
QDial);
86
option->initFrom(
this
);
87
option->minimum = d->minimum;
88
option->maximum = d->maximum;
89
option->sliderPosition = d->position;
90
option->sliderValue = d->value;
91
option->singleStep = d->singleStep;
92
option->pageStep = d->pageStep;
93
option->upsideDown = !d->invertedAppearance;
94
option->notchTarget = d->target;
95
option->dialWrapping = d->wrapping;
96
option->subControls = QStyle::SC_All;
97
option->activeSubControls = QStyle::SC_None;
98
if
(!d->showNotches) {
99
option->subControls &= ~QStyle::SC_DialTickmarks;
100
option->tickPosition = QSlider::TicksAbove;
101
}
else
{
102
option->tickPosition = QSlider::NoTicks;
103
}
104
option->tickInterval = notchSize();
105
}
106
107
int
QDialPrivate
::
valueFromPoint
(
const
QPointF &p)
const
108
{
109
Q_Q(
const
QDial);
110
double
yy = q->height()/2.0 - p.y();
111
double
xx = p.x() - q->width()/2.0;
112
double
a = (xx || yy) ?
std
::atan2(yy, xx) : 0;
113
114
if
(a < Q_PI / -2)
115
a = a + Q_PI * 2;
116
117
int
dist = 0;
118
int
minv = minimum, maxv = maximum;
119
120
if
(minimum < 0) {
121
dist = -minimum;
122
minv = 0;
123
maxv = maximum + dist;
124
}
125
126
int
r = maxv - minv;
127
int
v;
128
if
(
wrapping
)
129
v = (
int
)(0.5 + minv + r * (Q_PI * 3 / 2 - a) / (2 * Q_PI));
130
else
131
v = (
int
)(0.5 + minv + r* (Q_PI * 4 / 3 - a) / (Q_PI * 10 / 6));
132
133
if
(dist > 0)
134
v -= dist;
135
136
return
!invertedAppearance ? bound(v) : maximum - bound(v);
137
}
138
139
/*!
140
\class QDial
141
142
\brief The QDial class provides a rounded range control (like a speedometer or potentiometer).
143
144
\ingroup basicwidgets
145
\inmodule QtWidgets
146
147
\image fusion-dial.png {Round dial with notches}
148
149
QDial is used when the user needs to control a value within a
150
program-definable range, and the range either wraps around
151
(for example, with angles measured from 0 to 359 degrees) or the
152
dialog layout needs a square widget.
153
154
Since QDial inherits from QAbstractSlider, the dial behaves in
155
a similar way to a \l{QSlider}{slider}. When wrapping() is false
156
(the default setting) there is no real difference between a slider
157
and a dial. They both share the same signals, slots and member
158
functions. Which one you use depends on the expectations of
159
your users and on the type of application.
160
161
The dial initially emits valueChanged() signals continuously while
162
the slider is being moved; you can make it emit the signal less
163
often by disabling the \l{QAbstractSlider::tracking} {tracking}
164
property. The sliderMoved() signal is emitted continuously even
165
when tracking is disabled.
166
167
The dial also emits sliderPressed() and sliderReleased() signals
168
when the mouse button is pressed and released. Note that the
169
dial's value can change without these signals being emitted since
170
the keyboard and wheel can also be used to change the value.
171
172
Unlike the slider, QDial attempts to draw a "nice" number of
173
notches rather than one per line step. If possible, the number of
174
notches drawn is one per line step, but if there aren't enough pixels
175
to draw every one, QDial will skip notches to try and draw a uniform
176
set (e.g. by drawing every second or third notch).
177
178
Like the slider, the dial makes the QAbstractSlider function setValue()
179
available as a slot.
180
181
The dial's keyboard interface is fairly simple: The
182
\uicontrol{left}/\uicontrol{up} and \uicontrol{right}/\uicontrol{down} arrow keys adjust
183
the dial's \l {QAbstractSlider::value} {value} by the defined
184
\l {QAbstractSlider::singleStep} {singleStep}, \uicontrol{Page Up} and
185
\uicontrol{Page Down} by the defined \l {QAbstractSlider::pageStep}
186
{pageStep}, and the \uicontrol Home and \uicontrol End keys set the value to
187
the defined \l {QAbstractSlider::minimum} {minimum} and
188
\l {QAbstractSlider::maximum} {maximum} values.
189
190
If you are using the mouse wheel to adjust the dial, the increment
191
value is determined by the lesser value of
192
\l{QApplication::wheelScrollLines()} {wheelScrollLines} multiplied
193
by \l {QAbstractSlider::singleStep} {singleStep}, and
194
\l {QAbstractSlider::pageStep} {pageStep}.
195
196
\sa QScrollBar, QSpinBox, QSlider, {Sliders Example}
197
*/
198
199
/*!
200
Constructs a dial.
201
202
The \a parent argument is sent to the QAbstractSlider constructor.
203
*/
204
QDial::QDial(QWidget *parent)
205
: QAbstractSlider(*
new
QDialPrivate, parent)
206
{
207
Q_D(QDial);
208
d->init();
209
}
210
211
/*!
212
Destroys the dial.
213
*/
214
QDial::~QDial()
215
{
216
}
217
218
/*! \reimp */
219
void
QDial::resizeEvent(QResizeEvent *e)
220
{
221
QWidget::resizeEvent(e);
222
}
223
224
/*!
225
\reimp
226
*/
227
228
void
QDial::paintEvent(QPaintEvent *)
229
{
230
QStylePainter p(
this
);
231
QStyleOptionSlider option;
232
initStyleOption(&option);
233
p.drawComplexControl(QStyle::CC_Dial, option);
234
}
235
236
/*!
237
\reimp
238
*/
239
240
void
QDial::mousePressEvent(QMouseEvent *e)
241
{
242
Q_D(QDial);
243
if
(d->maximum == d->minimum ||
244
(e->button() != Qt::LeftButton) ||
245
(e->buttons() ^ e->button())) {
246
e->ignore();
247
return
;
248
}
249
e->accept();
250
setSliderPosition(d->valueFromPoint(e->position()));
251
// ### This isn't quite right,
252
// we should be doing a hit test and only setting this if it's
253
// the actual dial thingie (similar to what QSlider does), but we have no
254
// subControls for QDial.
255
setSliderDown(
true
);
256
}
257
258
259
/*!
260
\reimp
261
*/
262
263
void
QDial::mouseReleaseEvent(QMouseEvent * e)
264
{
265
Q_D(QDial);
266
if
(e->buttons() & (~e->button()) ||
267
(e->button() != Qt::LeftButton)) {
268
e->ignore();
269
return
;
270
}
271
e->accept();
272
setValue(d->valueFromPoint(e->position()));
273
setSliderDown(
false
);
274
}
275
276
277
/*!
278
\reimp
279
*/
280
281
void
QDial::mouseMoveEvent(QMouseEvent * e)
282
{
283
Q_D(QDial);
284
if
(!(e->buttons() & Qt::LeftButton)) {
285
e->ignore();
286
return
;
287
}
288
e->accept();
289
d->doNotEmit =
true
;
290
setSliderPosition(d->valueFromPoint(e->position()));
291
d->doNotEmit =
false
;
292
}
293
294
295
/*!
296
\reimp
297
*/
298
299
void
QDial::sliderChange(SliderChange change)
300
{
301
QAbstractSlider::sliderChange(change);
302
}
303
304
void
QDial::setWrapping(
bool
enable)
305
{
306
Q_D(QDial);
307
if
(d->wrapping == enable)
308
return
;
309
d->wrapping = enable;
310
update();
311
}
312
313
314
/*!
315
\property QDial::wrapping
316
\brief whether wrapping is enabled
317
318
If true, wrapping is enabled; otherwise some space is inserted at the bottom
319
of the dial to separate the ends of the range of valid values.
320
321
If enabled, the arrow can be oriented at any angle on the dial. If disabled,
322
the arrow will be restricted to the upper part of the dial; if it is rotated
323
into the space at the bottom of the dial, it will be clamped to the closest
324
end of the valid range of values.
325
326
By default this property is \c false.
327
*/
328
329
bool
QDial::wrapping()
const
330
{
331
Q_D(
const
QDial);
332
return
d->wrapping;
333
}
334
335
336
/*!
337
\property QDial::notchSize
338
\brief the current notch size
339
340
The notch size is in range control units, not pixels, and is
341
calculated to be a multiple of singleStep() that results in an
342
on-screen notch size near notchTarget().
343
344
\sa notchTarget(), singleStep()
345
*/
346
347
int
QDial::notchSize()
const
348
{
349
Q_D(
const
QDial);
350
// radius of the arc
351
qreal r = qMin(width(), height())/2.0;
352
// length of the whole arc
353
int
l = qRound(r * (d->wrapping ? 6.0 : 5.0) * Q_PI / 6.0);
354
// length of the arc from minValue() to minValue()+pageStep()
355
if
(d->maximum > d->minimum + d->pageStep)
356
l = qRound(l * d->pageStep /
double
(d->maximum - d->minimum));
357
// length of a singleStep arc
358
l = qMax(l * d->singleStep / (d->pageStep ? d->pageStep : 1), 1);
359
// how many times singleStep can be draw in d->target pixels
360
l = qMax(qRound(d->target / l), 1);
361
// we want notchSize() to be a non-zero multiple of singleStep()
362
return
d->singleStep * l;
363
}
364
365
void
QDial::setNotchTarget(
double
target)
366
{
367
Q_D(QDial);
368
d->target = target;
369
update();
370
}
371
372
/*!
373
\property QDial::notchTarget
374
\brief the target number of pixels between notches
375
376
The notch target is the number of pixels QDial attempts to put
377
between each notch.
378
379
The actual size may differ from the target size.
380
381
The default notch target is 3.7 pixels.
382
*/
383
qreal QDial::notchTarget()
const
384
{
385
Q_D(
const
QDial);
386
return
d->target;
387
}
388
389
390
void
QDial::setNotchesVisible(
bool
visible)
391
{
392
Q_D(QDial);
393
d->showNotches = visible;
394
update();
395
}
396
397
/*!
398
\property QDial::notchesVisible
399
\brief whether the notches are shown
400
401
If the property is \c true, a series of notches are drawn around the dial
402
to indicate the range of values available; otherwise no notches are
403
shown.
404
405
By default, this property is disabled.
406
*/
407
bool
QDial::notchesVisible()
const
408
{
409
Q_D(
const
QDial);
410
return
d->showNotches;
411
}
412
413
/*!
414
\reimp
415
*/
416
417
QSize QDial::minimumSizeHint()
const
418
{
419
return
QSize(50, 50);
420
}
421
422
/*!
423
\reimp
424
*/
425
426
QSize QDial::sizeHint()
const
427
{
428
return
QSize(100, 100);
429
}
430
431
/*!
432
\reimp
433
*/
434
bool
QDial::event(QEvent *e)
435
{
436
return
QAbstractSlider::event(e);
437
}
438
439
QT_END_NAMESPACE
440
441
#
include
"moc_qdial.cpp"
QDialPrivate
Definition
qdial.cpp:28
QDialPrivate::wrapping
uint wrapping
Definition
qdial.cpp:41
QDialPrivate::valueFromPoint
int valueFromPoint(const QPointF &) const
Definition
qdial.cpp:107
QDialPrivate::doNotEmit
uint doNotEmit
Definition
qdial.cpp:42
QDialPrivate::bound
virtual int bound(int val) const override
Definition
qdial.cpp:57
QDialPrivate::init
void init()
Definition
qdial.cpp:50
QDialPrivate::showNotches
uint showNotches
Definition
qdial.cpp:40
QDialPrivate::angle
double angle(const QPoint &, const QPoint &) const
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
qtbase
src
widgets
widgets
qdial.cpp
Generated on
for Qt by
1.18.0