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
qquickdoublespinbox.cpp
Go to the documentation of this file.
1
// Copyright (C) 2025 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
"qquickdoublespinbox_p.h"
6
7
#
include
<
private
/
qquickcontrol_p_p
.
h
>
8
#
include
<
private
/
qquickindicatorbutton_p
.
h
>
9
#
include
<
private
/
qquicktextinput_p
.
h
>
10
11
#
include
<
private
/
qqmlengine_p
.
h
>
12
13
#
include
<
QtQml
/
qqmlinfo
.
h
>
14
15
QT_BEGIN_NAMESPACE
16
17
/*!
18
\qmltype DoubleSpinBox
19
\inherits Control
20
//! \nativetype QQuickDoubleSpinBox
21
\inqmlmodule QtQuick.Controls
22
\ingroup qtquickcontrols-input
23
\ingroup qtquickcontrols-focusscopes
24
\since 6.11
25
\brief Allows the user to select from a set of preset floating-point
26
values.
27
28
\image qtquickcontrols-doublespinbox.png
29
{Spin box displaying decimal values}
30
31
DoubleSpinBox is similar to \l SpinBox, except that it supports double
32
values rather than integer. The user can choose a value by clicking the up
33
or down indicator buttons, or by pressing up or down on the keyboard.
34
Optionally, DoubleSpinBox can be also made \l editable, so the user can
35
enter a text value in the input field.
36
37
By default, DoubleSpinBox provides discrete values in the range of
38
\c [0.00-99.99] with a \l stepSize of \c 1.0.
39
40
\snippet qtquickcontrols-doublespinbox.qml 1
41
42
\sa SpinBox, Tumbler, {Customizing DoubleSpinBox},
43
{Focus Management in Qt Quick Controls}
44
*/
45
46
/*!
47
\include qquickspinbox.qdocinc {valueModified} {DoubleSpinBox}
48
*/
49
50
class
QQuickDoubleSpinBoxPrivate
51
:
public
QQuickAbstractSpinBox
<
QQuickDoubleSpinBox
,
double
>::
QQuickAbstractSpinBoxPrivate
52
{
53
Q_DECLARE_PUBLIC(QQuickDoubleSpinBox)
54
55
public
:
56
QQuickDoubleSpinBoxPrivate
();
57
58
bool
setValue
(
double
newValue,
bool
wrap, ValueStatus modified)
override
;
59
60
void
updateValue
()
override
;
61
void
updateDisplayText
()
override
;
62
63
void
contentItemTextChanged
();
64
65
QString
evaluateTextFromValue
(
double
val,
int
decimals)
const
;
66
double
evaluateValueFromText
(
const
QString &text)
const
;
67
68
double
round
(
double
input)
const
;
69
70
int
decimals
= 2;
71
72
private
:
73
friend
class
QQuickAbstractSpinBox
<
QQuickDoubleSpinBox
,
double
>::
QQuickAbstractSpinBoxPrivate
;
74
};
75
76
QQuickDoubleSpinBoxPrivate
::QQuickDoubleSpinBoxPrivate()
77
: QQuickAbstractSpinBox<QQuickDoubleSpinBox,
double
>::QQuickAbstractSpinBoxPrivate()
78
{
79
from = 0.0;
80
to = 99.99;
81
}
82
83
/*!
84
\internal
85
86
modified indicates if the value was modified by the user and not programatically.
87
This is then passed on to updateDisplayText to indicate that the user has modified
88
the value, so it may need to trigger an update of the contentItem's text, too.
89
*/
90
91
bool
QQuickDoubleSpinBoxPrivate
::
setValue
(
double
newValue,
bool
wrap, ValueStatus modified)
92
{
93
Q_Q(QQuickDoubleSpinBox);
94
double
correctedValue = newValue;
95
if
(q->isComponentComplete())
96
correctedValue = boundValue(newValue, wrap);
97
98
if
(modified == ValueStatus::Unmodified && qFuzzyCompare(newValue, correctedValue)
99
&& qFuzzyCompare(newValue, value))
100
return
false
;
101
102
const
bool
emitSignals = (value != correctedValue);
103
value = correctedValue;
104
105
updateDisplayText
(
)
;
106
updateUpEnabled();
107
updateDownEnabled();
108
109
// Only emit the signals if the corrected value is not the same as the
110
// original value to avoid unnecessary updates.
111
if
(emitSignals) {
112
emit q->valueChanged();
113
if
(modified == ValueStatus::Modified)
114
emit q->valueModified();
115
}
116
return
true
;
117
}
118
119
void
QQuickDoubleSpinBoxPrivate
::
updateValue
()
120
{
121
if
(!contentItem)
122
return
;
123
124
const
QVariant text = contentItem->property(
"text"
);
125
if
(text.isValid())
126
setValue(evaluateValueFromText(text.toString()),
false
/* wrap */
, ValueStatus::Modified);
127
}
128
129
void
QQuickDoubleSpinBoxPrivate
::
updateDisplayText
()
130
{
131
setDisplayText(evaluateTextFromValue(value, decimals));
132
}
133
134
void
QQuickDoubleSpinBoxPrivate
::
contentItemTextChanged
()
135
{
136
Q_Q(QQuickDoubleSpinBox);
137
138
QQuickTextInput *inputTextItem = qobject_cast<QQuickTextInput *>(q->contentItem());
139
if
(!inputTextItem)
140
return
;
141
setDisplayText(inputTextItem->text());
142
}
143
144
QString
QQuickDoubleSpinBoxPrivate
::
evaluateTextFromValue
(
double
val,
int
decimals)
const
145
{
146
Q_Q(
const
QQuickDoubleSpinBox);
147
148
QString text;
149
QQmlEngine *engine = qmlEngine(q);
150
if
(engine && textFromValue.isCallable()) {
151
QJSValue loc;
152
#
if
QT_CONFIG
(
qml_locale
)
153
loc = QJSValuePrivate::fromReturnedValue(
154
engine->handle()->fromData(QMetaType::fromType<QLocale>(), &locale));
155
#
endif
156
text = textFromValue.call(QJSValueList() << val << decimals << loc).toString();
157
}
else
{
158
text = locale.toString(val,
'f'
, decimals);
159
}
160
return
text;
161
}
162
163
double
QQuickDoubleSpinBoxPrivate
::
evaluateValueFromText
(
const
QString &text)
const
164
{
165
Q_Q(
const
QQuickDoubleSpinBox);
166
double
value;
167
QQmlEngine *engine = qmlEngine(q);
168
if
(engine && valueFromText.isCallable()) {
169
QJSValue loc;
170
#
if
QT_CONFIG
(
qml_locale
)
171
loc = QJSValuePrivate::fromReturnedValue(
172
engine->handle()->fromData(QMetaType::fromType<QLocale>(), &locale));
173
#
endif
174
value = valueFromText.call(QJSValueList() << text << loc).toNumber();
175
}
else
{
176
value = locale.toDouble(text);
177
}
178
return
value;
179
}
180
181
double
QQuickDoubleSpinBoxPrivate
::
round
(
double
value)
const
182
{
183
return
QString::number(value,
'f'
, decimals).toDouble();
184
}
185
186
QQuickDoubleSpinBox::QQuickDoubleSpinBox(QQuickItem *parent)
187
: QQuickControl(*(
new
QQuickDoubleSpinBoxPrivate), parent),
188
QQuickAbstractSpinBox<QQuickDoubleSpinBox,
double
>()
189
{
190
}
191
192
QQuickDoubleSpinBox::~QQuickDoubleSpinBox() { }
193
194
/*!
195
\include qquickspinbox.qdocinc {from} {double} {DoubleSpinBox} {0.0}
196
*/
197
198
void
QQuickDoubleSpinBox::setFrom(
double
from)
199
{
200
Q_D(QQuickDoubleSpinBox);
201
const
double
newFrom = d->round(from);
202
if
(qFuzzyCompare(d->from, newFrom))
203
return
;
204
205
d->from = newFrom;
206
emit fromChanged();
207
if
(isComponentComplete()) {
208
if
(!d->setValue(d->round(d->value),
false
/* wrap */
,
209
QQuickDoubleSpinBoxPrivate::ValueStatus::Unmodified)) {
210
d->updateUpEnabled();
211
d->updateDownEnabled();
212
}
213
}
214
}
215
216
/*!
217
\include qquickspinbox.qdocinc {to} {double} {DoubleSpinBox} {99.99}
218
*/
219
220
void
QQuickDoubleSpinBox::setTo(
double
to)
221
{
222
Q_D(QQuickDoubleSpinBox);
223
const
double
newTo = d->round(to);
224
if
(qFuzzyCompare(d->to, newTo))
225
return
;
226
227
d->to = newTo;
228
emit toChanged();
229
if
(isComponentComplete()) {
230
if
(!d->setValue(d->round(d->value),
false
/* wrap */
,
231
QQuickDoubleSpinBoxPrivate::ValueStatus::Unmodified)) {
232
d->updateUpEnabled();
233
d->updateDownEnabled();
234
}
235
}
236
}
237
238
/*!
239
\include qquickspinbox.qdocinc {value-prop} {double} {DoubleSpinBox} {0.0}
240
*/
241
242
void
QQuickDoubleSpinBox::setValue(
double
value)
243
{
244
Q_D(QQuickDoubleSpinBox);
245
d->setValue(d->round(value),
false
/* wrap */
,
246
QQuickDoubleSpinBoxPrivate::ValueStatus::Unmodified);
247
}
248
249
/*!
250
\include qquickspinbox.qdocinc {stepSize} {double} {DoubleSpinBox} {1.0}
251
*/
252
253
void
QQuickDoubleSpinBox::setStepSize(
double
step)
254
{
255
Q_D(QQuickDoubleSpinBox);
256
if
(qFuzzyCompare(d->stepSize, step))
257
return
;
258
259
d->stepSize = step;
260
emit stepSizeChanged();
261
}
262
263
/*!
264
\qmlproperty int QtQuick.Controls::DoubleSpinBox::decimals
265
266
This property holds how many decimals the spinbox will use for displaying
267
and interpreting doubles.
268
269
The default value is \c 2.
270
271
Changing the value of this property may affect \l from, \l to and \l value.
272
273
\warning The maximum value for \a decimals is \c {DBL_MAX_10_EXP +
274
DBL_DIG} (\c 323) because of the limitations of the double type.
275
*/
276
277
int
QQuickDoubleSpinBox::decimals()
const
278
{
279
Q_D(
const
QQuickDoubleSpinBox);
280
281
return
d->decimals;
282
}
283
284
void
QQuickDoubleSpinBox::setDecimals(
int
decimals)
285
{
286
Q_D(QQuickDoubleSpinBox);
287
d->decimals = qBound(0, decimals, DBL_MAX_10_EXP + DBL_DIG);
288
289
// Make sure values are rounded.
290
setFrom(from());
291
setTo(to());
292
setValue(value());
293
d->updateValue();
294
emit decimalsChanged();
295
}
296
297
/*!
298
\include qquickspinbox.qdocinc {editable} {DoubleSpinBox}
299
*/
300
301
#
if
QT_CONFIG
(
validator
)
302
/*!
303
\qmlproperty Validator QtQuick.Controls::DoubleSpinBox::validator
304
305
This property holds the input text validator for editable spinboxes. By
306
default, DoubleSpinBox uses \l DoubleValidator to accept input of double numbers.
307
308
\code
309
DoubleSpinBox {
310
id: control
311
validator: DoubleValidator {
312
locale: control.locale.name
313
bottom: Math.min(control.from, control.to)
314
top: Math.max(control.from, control.to)
315
}
316
}
317
\endcode
318
319
\sa editable, textFromValue, valueFromText, {Control::locale}{locale},
320
{Validating Input Text}
321
*/
322
#
endif
323
324
/*!
325
\qmlproperty function QtQuick.Controls::DoubleSpinBox::textFromValue
326
327
This property holds a callback function that is called whenever
328
a double value needs to be converted to display text.
329
330
The default function can be overridden to display custom text for a given
331
value. This applies to both editable and non-editable spinboxes;
332
for example, when using the up and down buttons or a mouse wheel to
333
increment and decrement the value, the new value is converted to display
334
text using this function.
335
336
The callback function signature is \c {string function(value, decimals, locale)}.
337
The function can have two or three arguments, where the first argument
338
is the value to be converted, the second argument is the number of decimals,
339
and the optional third argument is the locale that should be used for
340
the conversion, if applicable.
341
342
The default implementation does the conversion using
343
\l {string Number::toLocaleString(locale, format, precision)}{Number.toLocaleString}():
344
345
\code
346
textFromValue: function(value, decimals, locale) {
347
return Number(value).toLocaleString(locale, 'f', decimals);
348
}
349
\endcode
350
351
\note When applying a custom \c textFromValue implementation for editable
352
spinboxes, a matching \l valueFromText implementation must be provided
353
to be able to convert the custom text back to a double value.
354
355
\sa valueFromText, validator, {Control::locale}{locale}
356
*/
357
QJSValue QQuickDoubleSpinBox::textFromValue()
const
358
{
359
Q_D(
const
QQuickDoubleSpinBox);
360
if
(!d->textFromValue.isCallable()) {
361
QQmlEngine *engine = qmlEngine(
this
);
362
if
(engine) {
363
d->textFromValue = engine->evaluate(
364
QStringLiteral(
"(function(value, decimals, locale) { return "
365
"Number(value).toLocaleString(locale, 'f', decimals); })"
));
366
}
367
}
368
return
d->textFromValue;
369
}
370
371
/*!
372
\qmlproperty function QtQuick.Controls::DoubleSpinBox::valueFromText
373
374
This property holds a callback function that is called whenever
375
input text needs to be converted to a double value.
376
377
This function only needs to be overridden when \l textFromValue
378
is overridden for an editable spinbox.
379
380
The callback function signature is \c {int function(text, locale)}.
381
The function can have one or two arguments, where the first argument
382
is the text to be converted, and the optional second argument is the
383
locale that should be used for the conversion, if applicable.
384
385
The default implementation does the conversion using
386
\l {QtQml::Locale}{Number.fromLocaleString()}:
387
388
\code
389
valueFromText: function(text, locale) { return Number.fromLocaleString(locale, text); }
390
\endcode
391
392
\note When applying a custom \l textFromValue implementation for editable
393
spinboxes, a matching \c valueFromText implementation must be provided
394
to be able to convert the custom text back to a double value.
395
396
\sa textFromValue, validator, {Control::locale}{locale}
397
*/
398
QJSValue QQuickDoubleSpinBox::valueFromText()
const
399
{
400
Q_D(
const
QQuickDoubleSpinBox);
401
if
(!d->valueFromText.isCallable()) {
402
QQmlEngine *engine = qmlEngine(
this
);
403
if
(engine)
404
d->valueFromText = engine->evaluate(QStringLiteral(
405
"(function(text, locale) { return Number.fromLocaleString(locale, text); })"
));
406
}
407
return
d->valueFromText;
408
}
409
410
/*!
411
\include qquickindicatorbutton.qdocinc {properties} {DoubleSpinBox} {up}
412
413
\include qquickspinbox.qdocinc {indicator-enabled} {DoubleSpinBox} {up} {to}
414
415
\sa increase()
416
*/
417
418
/*!
419
\include qquickindicatorbutton.qdocinc {properties} {DoubleSpinBox} {down}
420
421
\include qquickspinbox.qdocinc {indicator-enabled} {DoubleSpinBox} {down} {from}
422
423
\sa decrease()
424
*/
425
426
/*!
427
\include qquickspinbox.qdocinc {inputMethodHints} {DoubleSpinBox}
428
*/
429
430
/*!
431
\include qquickspinbox.qdocinc {inputMethodComposing} {DoubleSpinBox}
432
*/
433
434
/*!
435
\since QtQuick.Controls 2.3 (Qt 5.10)
436
\include qquickspinbox.qdocinc {wrap} {DoubleSpinBox}
437
*/
438
439
void
QQuickDoubleSpinBox::setWrap(
bool
wrap)
440
{
441
Q_D(QQuickDoubleSpinBox);
442
if
(d->wrap == wrap)
443
return
;
444
445
d->wrap = wrap;
446
if
(qFuzzyCompare(d->value, d->from) || qFuzzyCompare(d->value, d->to)) {
447
d->updateUpEnabled();
448
d->updateDownEnabled();
449
}
450
emit wrapChanged();
451
}
452
453
/*!
454
\qmlproperty string QtQuick.Controls::DoubleSpinBox::displayText
455
\readonly
456
457
This property holds the textual value of the spinbox.
458
459
The value of the property is based on \l textFromValue and \l {Control::}
460
{locale}, and equal to:
461
\badcode
462
let text = spinBox.textFromValue(spinBox.value, spinBox.decimals, spinBox.locale)
463
\endcode
464
465
\sa textFromValue
466
*/
467
468
/*!
469
\include qquickspinbox.qdocinc {increase} {DoubleSpinBox}
470
*/
471
472
void
QQuickDoubleSpinBox::increase()
473
{
474
QQuickAbstractSpinBox<QQuickDoubleSpinBox,
double
>::increase();
475
}
476
477
/*!
478
\include qquickspinbox.qdocinc {decrease} {DoubleSpinBox}
479
*/
480
481
void
QQuickDoubleSpinBox::decrease()
482
{
483
QQuickAbstractSpinBox<QQuickDoubleSpinBox,
double
>::decrease();
484
}
485
486
void
QQuickDoubleSpinBox::contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
487
{
488
Q_D(QQuickDoubleSpinBox);
489
if
(QQuickTextInput *oldInput = qobject_cast<QQuickTextInput *>(oldItem)) {
490
disconnect(oldInput, &QQuickTextInput::inputMethodComposingChanged,
this
,
491
&QQuickDoubleSpinBox::inputMethodComposingChanged);
492
QObjectPrivate::disconnect(oldInput, &QQuickTextInput::textChanged, d,
493
&QQuickDoubleSpinBoxPrivate::contentItemTextChanged);
494
}
495
496
if
(newItem) {
497
newItem->setActiveFocusOnTab(
true
);
498
if
(d->activeFocus)
499
newItem->forceActiveFocus(
static_cast
<Qt::FocusReason>(d->focusReason));
500
#
if
QT_CONFIG
(
cursor
)
501
if
(d->editable)
502
newItem->setCursor(Qt::IBeamCursor);
503
#
endif
504
505
if
(QQuickTextInput *newInput = qobject_cast<QQuickTextInput *>(newItem)) {
506
connect(newInput, &QQuickTextInput::inputMethodComposingChanged,
this
,
507
&QQuickDoubleSpinBox::inputMethodComposingChanged);
508
QObjectPrivate::connect(newInput, &QQuickTextInput::textChanged, d,
509
&QQuickDoubleSpinBoxPrivate::contentItemTextChanged);
510
}
511
}
512
}
513
514
QQuickControlPrivate *QQuickDoubleSpinBox::d_base_func()
515
{
516
Q_D(QQuickDoubleSpinBox);
517
return
d;
518
}
519
const
QQuickControlPrivate *QQuickDoubleSpinBox::d_base_func()
const
520
{
521
Q_D(
const
QQuickDoubleSpinBox);
522
return
d;
523
}
524
525
QT_END_NAMESPACE
526
527
#
include
"moc_qquickdoublespinbox_p.cpp"
QQuickDoubleSpinBoxPrivate
Allows the user to select from a set of preset floating-point values.
Definition
qquickdoublespinbox.cpp:52
QQuickDoubleSpinBoxPrivate::updateDisplayText
void updateDisplayText() override
Definition
qquickdoublespinbox.cpp:129
QQuickDoubleSpinBoxPrivate::contentItemTextChanged
void contentItemTextChanged()
Definition
qquickdoublespinbox.cpp:134
QQuickDoubleSpinBoxPrivate::setValue
bool setValue(double newValue, bool wrap, ValueStatus modified) override
Definition
qquickdoublespinbox.cpp:91
QQuickDoubleSpinBoxPrivate::evaluateTextFromValue
QString evaluateTextFromValue(double val, int decimals) const
Definition
qquickdoublespinbox.cpp:144
QQuickDoubleSpinBoxPrivate::evaluateValueFromText
double evaluateValueFromText(const QString &text) const
Definition
qquickdoublespinbox.cpp:163
QQuickDoubleSpinBoxPrivate::updateValue
void updateValue() override
Definition
qquickdoublespinbox.cpp:119
QQuickDoubleSpinBoxPrivate::decimals
int decimals
Definition
qquickdoublespinbox.cpp:70
QQuickDoubleSpinBoxPrivate::round
double round(double input) const
Definition
qquickdoublespinbox.cpp:181
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
qtdeclarative
src
quicktemplates
qquickdoublespinbox.cpp
Generated on
for Qt by
1.18.0