Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qabstractspinbox.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
4#include <qplatformdefs.h>
5#include <private/qabstractspinbox_p.h>
6#include <private/qapplication_p.h>
7#if QT_CONFIG(datetimeparser)
8#include <private/qdatetimeparser_p.h>
9#endif
10#include <private/qlineedit_p.h>
11#include <qabstractspinbox.h>
12
13#include <qapplication.h>
14#include <qstylehints.h>
15#include <qclipboard.h>
16#include <qdatetime.h>
17#include <qevent.h>
18#if QT_CONFIG(menu)
19#include <qmenu.h>
20#endif
21#include <qpainter.h>
22#include <qpalette.h>
23#include <qstylepainter.h>
24#include <qdebug.h>
25#if QT_CONFIG(accessibility)
26# include <qaccessible.h>
27#endif
28
29#include <QtCore/qpointer.h>
30
31//#define QABSTRACTSPINBOX_QSBDEBUG
32#ifdef QABSTRACTSPINBOX_QSBDEBUG
33# define QASBDEBUG qDebug
34#else
35# define QASBDEBUG if (false) qDebug
36#endif
37
39
40using namespace Qt::StringLiterals;
41
117 : QWidget(*new QAbstractSpinBoxPrivate, parent, { })
118{
119 Q_D(QAbstractSpinBox);
120 d->init();
121}
122
127 : QWidget(dd, parent, { })
128{
129 Q_D(QAbstractSpinBox);
130 d->init();
131}
132
140
172{
173 Q_D(const QAbstractSpinBox);
174 return d->buttonSymbols;
175}
176
178{
179 Q_D(QAbstractSpinBox);
180 if (d->buttonSymbols != buttonSymbols) {
181 d->buttonSymbols = buttonSymbols;
182 d->updateEditFieldGeometry();
184 update();
185 }
186}
187
197{
198 return lineEdit()->displayText();
199}
200
201
236{
237 Q_D(const QAbstractSpinBox);
238 return d->specialValueText;
239}
240
242{
243 Q_D(QAbstractSpinBox);
244
245 d->specialValueText = specialValueText;
246 d->cachedSizeHint = QSize(); // minimumSizeHint doesn't care about specialValueText
247 d->clearCache();
248 d->updateEdit();
249}
250
266{
267 Q_D(const QAbstractSpinBox);
268 return d->wrapping;
269}
270
272{
273 Q_D(QAbstractSpinBox);
274 d->wrapping = wrapping;
275}
276
277
293{
294 Q_D(const QAbstractSpinBox);
295 return d->readOnly;
296}
297
299{
300 Q_D(QAbstractSpinBox);
301 d->readOnly = enable;
302 d->edit->setReadOnly(enable);
305 update();
306}
307
329{
330 Q_D(const QAbstractSpinBox);
331 return d->keyboardTracking;
332}
333
335{
336 Q_D(QAbstractSpinBox);
337 d->keyboardTracking = enable;
338}
339
349{
350 Q_D(const QAbstractSpinBox);
351 return d->frame;
352}
353
354
356{
357 Q_D(QAbstractSpinBox);
358 d->frame = enable;
359 update();
360 d->updateEditFieldGeometry();
361}
362
374{
375 Q_D(QAbstractSpinBox);
376 d->accelerate = accelerate;
377
378}
380{
381 Q_D(const QAbstractSpinBox);
382 return d->accelerate;
383}
384
394{
395 Q_D(const QAbstractSpinBox);
396 return d->showGroupSeparator;
397}
398
400{
401 Q_D(QAbstractSpinBox);
402 if (d->showGroupSeparator == shown)
403 return;
404 d->showGroupSeparator = shown;
405 d->setValue(d->value, EmitIfChanged);
407}
408
435{
436 Q_D(QAbstractSpinBox);
437 d->correctionMode = correctionMode;
438
439}
441{
442 Q_D(const QAbstractSpinBox);
443 return d->correctionMode;
444}
445
446
456{
457 Q_D(const QAbstractSpinBox);
458 return d->edit->hasAcceptableInput();
459}
460
475Qt::Alignment QAbstractSpinBox::alignment() const
476{
477 Q_D(const QAbstractSpinBox);
478
479 return (Qt::Alignment)d->edit->alignment();
480}
481
482void QAbstractSpinBox::setAlignment(Qt::Alignment flag)
483{
484 Q_D(QAbstractSpinBox);
485
486 d->edit->setAlignment(flag);
487}
488
494{
495 Q_D(QAbstractSpinBox);
496
497
498 if (!d->specialValue()) {
499 const int tmp = d->edit->displayText().size() - d->suffix.size();
500 d->edit->setSelection(tmp, -(tmp - d->prefix.size()));
501 } else {
502 d->edit->selectAll();
503 }
504}
505
511{
512 Q_D(QAbstractSpinBox);
513
514 d->edit->setText(d->prefix + d->suffix);
515 d->edit->setCursorPosition(d->prefix.size());
516 d->cleared = true;
517}
518
537QAbstractSpinBox::StepEnabled QAbstractSpinBox::stepEnabled() const
538{
539 Q_D(const QAbstractSpinBox);
540 if (d->readOnly || d->type == QMetaType::UnknownType)
541 return StepNone;
542 if (d->wrapping)
543 return StepEnabled(StepUpEnabled | StepDownEnabled);
544 StepEnabled ret = StepNone;
545 if (QAbstractSpinBoxPrivate::variantCompare(d->value, d->maximum) < 0) {
547 }
548 if (QAbstractSpinBoxPrivate::variantCompare(d->value, d->minimum) > 0) {
550 }
551 return ret;
552}
553
561QValidator::State QAbstractSpinBox::validate(QString & /* input */, int & /* pos */) const
562{
564}
565
573void QAbstractSpinBox::fixup(QString & /* input */) const
574{
575}
576
584{
585 stepBy(1);
586}
587
595{
596 stepBy(-1);
597}
613{
614 Q_D(QAbstractSpinBox);
615
616 const QVariant old = d->value;
617 QString tmp = d->edit->displayText();
618 int cursorPos = d->edit->cursorPosition();
619 bool dontstep = false;
621 if (d->pendingEmit) {
622 dontstep = validate(tmp, cursorPos) != QValidator::Acceptable;
623 d->cleared = false;
624 d->interpret(NeverEmit);
625 if (d->value != old)
626 e = AlwaysEmit;
627 }
628 if (!dontstep) {
629 QVariant singleStep;
630 switch (d->stepType) {
632 singleStep = d->calculateAdaptiveDecimalStep(steps);
633 break;
634 default:
635 singleStep = d->singleStep;
636 }
637 d->setValue(d->bound(d->value + (singleStep * steps), old, steps), e);
638 } else if (e == AlwaysEmit) {
639 d->emitSignals(e, old);
640 }
641 if (style()->styleHint(QStyle::SH_SpinBox_SelectOnStep, nullptr, this, nullptr))
642 selectAll();
643}
644
650{
651 Q_D(const QAbstractSpinBox);
652
653 return d->edit;
654}
655
656
670{
671 Q_D(QAbstractSpinBox);
672
673 if (!lineEdit) {
675 return;
676 }
677
678 if (lineEdit == d->edit)
679 return;
680
681 delete d->edit;
682 d->edit = lineEdit;
683 setProperty("_q_spinbox_lineedit", QVariant::fromValue<QWidget *>(d->edit));
684 if (!d->edit->validator())
685 d->edit->setValidator(d->validator);
686
687 if (d->edit->parent() != this)
688 d->edit->setParent(this);
689
690 d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
691 d->edit->setFocusProxy(this);
692 d->edit->setAcceptDrops(false);
693
694 if (d->type != QMetaType::UnknownType) {
700 this, [this]() { updateMicroFocus(); });
701 connect(d->edit->d_func()->control, &QWidgetLineControl::updateMicroFocus,
702 this, [this]() { updateMicroFocus(); });
703 }
704 d->updateEditFieldGeometry();
705 d->edit->setContextMenuPolicy(Qt::NoContextMenu);
706 d->edit->d_func()->control->setAccessibleObject(this);
707
708 if (isVisible())
709 d->edit->show();
710 if (isVisible())
711 d->updateEdit();
712}
713
714
721{
722 Q_D(QAbstractSpinBox);
723 d->interpret(EmitIfChanged);
724}
725
726/*
727 Reimplemented in 4.6, so be careful.
728 */
733{
734 Q_D(const QAbstractSpinBox);
735 const QVariant lineEditValue = d->edit->inputMethodQuery(query);
736 switch (query) {
737 case Qt::ImHints:
738 if (const int hints = inputMethodHints())
739 return QVariant(hints | lineEditValue.toInt());
740 break;
741 default:
742 break;
743 }
744 return lineEditValue;
745}
746
752{
753 Q_D(QAbstractSpinBox);
754 switch (event->type()) {
757 d->cachedSizeHint = d->cachedMinimumSizeHint = QSize();
758 break;
761 d->updateEditFieldGeometry();
762 break;
766 d->updateHoverControl(static_cast<const QHoverEvent *>(event)->position().toPoint());
767 break;
769 if (d->edit->event(event))
770 return true;
771 break;
772#ifdef QT_KEYPAD_NAVIGATION
773 case QEvent::EnterEditFocus:
774 case QEvent::LeaveEditFocus:
775 if (QApplicationPrivate::keypadNavigationEnabled()) {
776 const bool b = d->edit->event(event);
777 d->edit->setSelection(d->edit->displayText().size() - d->suffix.size(),0);
778 if (event->type() == QEvent::LeaveEditFocus)
780 if (b)
781 return true;
782 }
783 break;
784#endif
786 return d->edit->event(event);
787 default:
788 break;
789 }
790 return QWidget::event(event);
791}
792
798{
799 Q_D(QAbstractSpinBox);
800 d->reset();
801
802 if (d->ignoreUpdateEdit) {
803 d->ignoreUpdateEdit = false;
804 } else {
805 d->updateEdit();
806 }
807}
808
814{
815 Q_D(QAbstractSpinBox);
816
817 switch (event->type()) {
819 d->spinClickTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, nullptr, this);
820 d->spinClickThresholdTimerInterval =
822 if (d->edit)
823 d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
824 d->stepModifier = static_cast<Qt::KeyboardModifier>(style()->styleHint(QStyle::SH_SpinBox_StepModifier, nullptr, this));
825 d->reset();
826 d->updateEditFieldGeometry();
827 break;
829 d->updateEdit();
830 break;
832 if (!isEnabled()) {
833 d->reset();
834 }
835 break;
837 if (!isActiveWindow()){
838 d->reset();
839 if (d->pendingEmit) // pendingEmit can be true even if it hasn't changed.
840 d->interpret(EmitIfChanged); // E.g. 10 to 10.0
841 }
842 break;
843 default:
844 break;
845 }
847}
848
854{
855 Q_D(QAbstractSpinBox);
857
858 d->updateEditFieldGeometry();
859 update();
860}
861
867{
868 Q_D(const QAbstractSpinBox);
869 if (d->cachedSizeHint.isEmpty()) {
871
872 const QFontMetrics fm(fontMetrics());
873 int h = d->edit->sizeHint().height();
874 int w = 0;
875 QString s;
876 QString fixedContent = d->prefix + d->suffix + u' ';
877 s = d->textFromValue(d->minimum);
878 s.truncate(18);
879 s += fixedContent;
880 w = qMax(w, fm.horizontalAdvance(s));
881 s = d->textFromValue(d->maximum);
882 s.truncate(18);
883 s += fixedContent;
884 w = qMax(w, fm.horizontalAdvance(s));
885
886 if (d->specialValueText.size()) {
887 s = d->specialValueText;
888 w = qMax(w, fm.horizontalAdvance(s));
889 }
890 w += 2; // cursor blinking space
891
892 QStyleOptionSpinBox opt;
894 QSize hint(w, h);
895 d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
896 }
897 return d->cachedSizeHint;
898}
899
905{
906 Q_D(const QAbstractSpinBox);
907 if (d->cachedMinimumSizeHint.isEmpty()) {
908 //Use the prefix and range to calculate the minimumSizeHint
910
911 const QFontMetrics fm(fontMetrics());
912 int h = d->edit->minimumSizeHint().height();
913 int w = 0;
914
915 QString s;
916 QString fixedContent = d->prefix + u' ';
917 s = d->textFromValue(d->minimum);
918 s.truncate(18);
919 s += fixedContent;
920 w = qMax(w, fm.horizontalAdvance(s));
921 s = d->textFromValue(d->maximum);
922 s.truncate(18);
923 s += fixedContent;
924 w = qMax(w, fm.horizontalAdvance(s));
925
926 if (d->specialValueText.size()) {
927 s = d->specialValueText;
928 w = qMax(w, fm.horizontalAdvance(s));
929 }
930 w += 2; // cursor blinking space
931
932 QStyleOptionSpinBox opt;
934 QSize hint(w, h);
935
936 d->cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this);
937 }
938 return d->cachedMinimumSizeHint;
939}
940
946{
947 QStyleOptionSpinBox opt;
949 QStylePainter p(this);
950 p.drawComplexControl(QStyle::CC_SpinBox, opt);
951}
952
978{
979 Q_D(QAbstractSpinBox);
980
981 d->keyboardModifiers = event->modifiers();
982
983 if (!event->text().isEmpty() && d->edit->cursorPosition() < d->prefix.size())
984 d->edit->setCursorPosition(d->prefix.size());
985
986 int steps = 1;
987 bool isPgUpOrDown = false;
988 switch (event->key()) {
989 case Qt::Key_PageUp:
990 case Qt::Key_PageDown:
991 steps *= 10;
992 isPgUpOrDown = true;
994 case Qt::Key_Up:
995 case Qt::Key_Down: {
996#ifdef QT_KEYPAD_NAVIGATION
997 if (QApplicationPrivate::keypadNavigationEnabled()) {
998 // Reserve up/down for nav - use left/right for edit.
999 if (!hasEditFocus() && (event->key() == Qt::Key_Up
1000 || event->key() == Qt::Key_Down)) {
1001 event->ignore();
1002 return;
1003 }
1004 }
1005#endif
1006 event->accept();
1007 const bool up = (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_Up);
1008 if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled)))
1009 return;
1010 if (!isPgUpOrDown && (event->modifiers() & d->stepModifier))
1011 steps *= 10;
1012 if (!up)
1013 steps *= -1;
1014 if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, nullptr, this)) {
1015 d->buttonState = (Keyboard | (up ? Up : Down));
1016 }
1017 if (d->spinClickTimerId == -1)
1018 stepBy(steps);
1019 if (event->isAutoRepeat() && !isPgUpOrDown) {
1020 if (d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) {
1021 d->updateState(up, true);
1022 }
1023 }
1024#if QT_CONFIG(accessibility)
1025 QAccessibleValueChangeEvent event(this, d->value);
1026 QAccessible::updateAccessibility(&event);
1027#endif
1028 return;
1029 }
1030#ifdef QT_KEYPAD_NAVIGATION
1031 case Qt::Key_Left:
1032 case Qt::Key_Right:
1033 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1034 event->ignore();
1035 return;
1036 }
1037 break;
1038 case Qt::Key_Back:
1039 if (QApplicationPrivate::keypadNavigationEnabled() && !hasEditFocus()) {
1040 event->ignore();
1041 return;
1042 }
1043 break;
1044#endif
1045 case Qt::Key_Enter:
1046 case Qt::Key_Return:
1047 d->edit->d_func()->control->clearUndo();
1048 d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged);
1049 selectAll();
1050 event->ignore();
1052 emit d->edit->returnPressed();
1053 return;
1054
1055#ifdef QT_KEYPAD_NAVIGATION
1056 case Qt::Key_Select:
1057 if (QApplicationPrivate::keypadNavigationEnabled()) {
1058 // Toggles between left/right moving cursor and inc/dec.
1059 setEditFocus(!hasEditFocus());
1060 }
1061 return;
1062#endif
1063
1064 case Qt::Key_U:
1065 if (event->modifiers() & Qt::ControlModifier
1066 && QGuiApplication::platformName() == "xcb"_L1) { // only X11
1067 event->accept();
1068 if (!isReadOnly())
1069 clear();
1070 return;
1071 }
1072 break;
1073
1074 case Qt::Key_End:
1075 case Qt::Key_Home:
1076 if (event->modifiers() & Qt::ShiftModifier) {
1077 int currentPos = d->edit->cursorPosition();
1078 const QString text = d->edit->displayText();
1079 if (event->key() == Qt::Key_End) {
1080 if ((currentPos == 0 && !d->prefix.isEmpty()) || text.size() - d->suffix.size() <= currentPos) {
1081 break; // let lineedit handle this
1082 } else {
1083 d->edit->setSelection(currentPos, text.size() - d->suffix.size() - currentPos);
1084 }
1085 } else {
1086 if ((currentPos == text.size() && !d->suffix.isEmpty()) || currentPos <= d->prefix.size()) {
1087 break; // let lineedit handle this
1088 } else {
1089 d->edit->setSelection(currentPos, d->prefix.size() - currentPos);
1090 }
1091 }
1092 event->accept();
1093 return;
1094 }
1095 break;
1096
1097 default:
1098#ifndef QT_NO_SHORTCUT
1100 selectAll();
1101 event->accept();
1102 return;
1103 }
1104#endif
1105 break;
1106 }
1107
1108 d->edit->event(event);
1109 if (!d->edit->text().isEmpty())
1110 d->cleared = false;
1111 if (!isVisible())
1112 d->ignoreUpdateEdit = true;
1113}
1114
1120{
1121 Q_D(QAbstractSpinBox);
1122
1123 d->keyboardModifiers = event->modifiers();
1124 if (d->buttonState & Keyboard && !event->isAutoRepeat()) {
1125 d->reset();
1126 } else {
1127 d->edit->event(event);
1128 }
1129}
1130
1135#if QT_CONFIG(wheelevent)
1136void QAbstractSpinBox::wheelEvent(QWheelEvent *event)
1137{
1138 Q_D(QAbstractSpinBox);
1139#ifdef Q_OS_MACOS
1140 // If the event comes from a real mouse wheel, rather than a track pad
1141 // (Qt::MouseEventSynthesizedBySystem), the shift modifier changes the
1142 // scroll orientation to horizontal.
1143 // Convert horizontal events back to vertical whilst shift is held.
1144 if ((event->modifiers() & Qt::ShiftModifier)
1145 && event->source() == Qt::MouseEventNotSynthesized) {
1146 d->wheelDeltaRemainder += event->angleDelta().x();
1147 } else {
1148 d->wheelDeltaRemainder += event->angleDelta().y();
1149 }
1150#else
1151 d->wheelDeltaRemainder += event->angleDelta().y();
1152#endif
1153 const int steps = d->wheelDeltaRemainder / 120;
1154 d->wheelDeltaRemainder -= steps * 120;
1155 if (stepEnabled() & (steps > 0 ? StepUpEnabled : StepDownEnabled))
1156 stepBy(event->modifiers() & d->stepModifier ? steps * 10 : steps);
1157 event->accept();
1158}
1159#endif
1160
1161
1166{
1167 Q_D(QAbstractSpinBox);
1168
1169 d->edit->event(event);
1170 if (event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason) {
1171 selectAll();
1172 }
1174}
1175
1181{
1182 Q_D(QAbstractSpinBox);
1183
1184 if (d->pendingEmit)
1185 d->interpret(EmitIfChanged);
1186
1187 d->reset();
1188 d->edit->event(event);
1189 d->updateEdit();
1191
1192#ifdef QT_KEYPAD_NAVIGATION
1193 // editingFinished() is already emitted on LeaveEditFocus
1194 if (!QApplicationPrivate::keypadNavigationEnabled())
1195#endif
1197}
1198
1204{
1205 Q_D(QAbstractSpinBox);
1206
1207 d->reset();
1208 if (d->pendingEmit)
1209 d->interpret(EmitIfChanged);
1211}
1212
1218{
1219 Q_D(QAbstractSpinBox);
1220 d->reset();
1221 if (d->pendingEmit)
1222 d->interpret(EmitIfChanged);
1224}
1225
1226
1232{
1233 Q_D(QAbstractSpinBox);
1234
1235 bool doStep = false;
1236 if (event->timerId() == d->spinClickThresholdTimerId) {
1237 killTimer(d->spinClickThresholdTimerId);
1238 d->spinClickThresholdTimerId = -1;
1239 d->effectiveSpinRepeatRate = d->buttonState & Keyboard
1240 ? QGuiApplication::styleHints()->keyboardAutoRepeatRateF()
1241 : d->spinClickTimerInterval;
1242 d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate);
1243 doStep = true;
1244 } else if (event->timerId() == d->spinClickTimerId) {
1245 if (d->accelerate) {
1246 d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05);
1247 if (d->effectiveSpinRepeatRate - d->acceleration >= 10) {
1248 killTimer(d->spinClickTimerId);
1249 d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration);
1250 }
1251 }
1252 doStep = true;
1253 }
1254
1255 if (doStep) {
1256 const bool increaseStepRate = d->keyboardModifiers & d->stepModifier;
1257 const StepEnabled st = stepEnabled();
1258 if (d->buttonState & Up) {
1259 if (!(st & StepUpEnabled)) {
1260 d->reset();
1261 } else {
1262 stepBy(increaseStepRate ? 10 : 1);
1263 }
1264 } else if (d->buttonState & Down) {
1265 if (!(st & StepDownEnabled)) {
1266 d->reset();
1267 } else {
1268 stepBy(increaseStepRate ? -10 : -1);
1269 }
1270 }
1271 return;
1272 }
1274 return;
1275}
1276
1281#if QT_CONFIG(contextmenu)
1283{
1284 Q_D(QAbstractSpinBox);
1285
1286 QPointer<QMenu> menu = d->edit->createStandardContextMenu();
1287 if (!menu)
1288 return;
1289
1290 d->reset();
1291
1292 QAction *selAll = new QAction(tr("&Select All"), menu);
1293#if QT_CONFIG(shortcut)
1294 selAll->setShortcut(QKeySequence::SelectAll);
1295#endif
1296 menu->insertAction(d->edit->d_func()->selectAllAction,
1297 selAll);
1298 menu->removeAction(d->edit->d_func()->selectAllAction);
1299 menu->addSeparator();
1300 const uint se = stepEnabled();
1301 QAction *up = menu->addAction(tr("&Step up"));
1302 up->setEnabled(se & StepUpEnabled);
1303 QAction *down = menu->addAction(tr("Step &down"));
1304 down->setEnabled(se & StepDownEnabled);
1305 menu->addSeparator();
1306
1307 const QPointer<QAbstractSpinBox> that = this;
1308 const QPoint pos = (event->reason() == QContextMenuEvent::Mouse)
1309 ? event->globalPos() : mapToGlobal(QPoint(event->pos().x(), 0)) + QPoint(width() / 2, height() / 2);
1310 const QAction *action = menu->exec(pos);
1311 delete static_cast<QMenu *>(menu);
1312 if (that && action) {
1313 if (action == up) {
1314 stepBy(1);
1315 } else if (action == down) {
1316 stepBy(-1);
1317 } else if (action == selAll) {
1318 selectAll();
1319 }
1320 }
1321 event->accept();
1322}
1323#endif // QT_CONFIG(contextmenu)
1324
1330{
1331 Q_D(QAbstractSpinBox);
1332
1333 d->keyboardModifiers = event->modifiers();
1334 d->updateHoverControl(event->position().toPoint());
1335
1336 // If we have a timer ID, update the state
1337 if (d->spinClickTimerId != -1 && d->buttonSymbols != NoButtons) {
1338 const StepEnabled se = stepEnabled();
1339 if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp)
1340 d->updateState(true);
1341 else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown)
1342 d->updateState(false);
1343 else
1344 d->reset();
1345 event->accept();
1346 }
1347}
1348
1354{
1355 Q_D(QAbstractSpinBox);
1356
1357 d->keyboardModifiers = event->modifiers();
1358 if (event->button() != Qt::LeftButton || d->buttonState != None) {
1359 return;
1360 }
1361
1362 d->updateHoverControl(event->position().toPoint());
1363 event->accept();
1364
1365 const StepEnabled se = (d->buttonSymbols == NoButtons) ? StepEnabled(StepNone) : stepEnabled();
1366 if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp) {
1367 d->updateState(true);
1368 } else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown) {
1369 d->updateState(false);
1370 } else {
1371 event->ignore();
1372 }
1373}
1374
1379{
1380 Q_D(QAbstractSpinBox);
1381
1382 d->keyboardModifiers = event->modifiers();
1383 if ((d->buttonState & Mouse) != 0)
1384 d->reset();
1385 event->accept();
1386}
1387
1388// --- QAbstractSpinBoxPrivate ---
1389
1396 : pendingEmit(false), readOnly(false), wrapping(false),
1397 ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true),
1398 cleared(false), ignoreUpdateEdit(false), showGroupSeparator(false)
1399{
1400}
1401
1402/*
1403 \internal
1404 Called when the QAbstractSpinBoxPrivate is destroyed
1405*/
1409
1416{
1417 Q_Q(QAbstractSpinBox);
1418 QRect lastHoverRect = hoverRect;
1419 QStyle::SubControl lastHoverControl = hoverControl;
1420 bool doesHover = q->testAttribute(Qt::WA_Hover);
1421 if (lastHoverControl != newHoverControl(pos) && doesHover) {
1422 q->update(lastHoverRect);
1423 q->update(hoverRect);
1424 return true;
1425 }
1426 return !doesHover;
1427}
1428
1435{
1436 Q_Q(QAbstractSpinBox);
1437
1438 QStyleOptionSpinBox opt;
1439 q->initStyleOption(&opt);
1440 opt.subControls = QStyle::SC_All;
1441 hoverControl = q->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, pos, q);
1442 hoverRect = q->style()->subControlRect(QStyle::CC_SpinBox, &opt, hoverControl, q);
1443 return hoverControl;
1444}
1445
1452{
1454 if (specialValueText.size() == 0 || text != specialValueText) {
1455 int from = 0;
1456 int size = text.size();
1457 bool changed = false;
1458 if (prefix.size() && text.startsWith(prefix)) {
1459 from += prefix.size();
1460 size -= from;
1461 changed = true;
1462 }
1463 if (suffix.size() && text.endsWith(suffix)) {
1464 size -= suffix.size();
1465 changed = true;
1466 }
1467 if (changed)
1468 text = text.mid(from, size);
1469 }
1470
1471 const int s = text.size();
1472 text = text.trimmed();
1473 if (pos)
1474 (*pos) -= (s - text.size());
1475 return text.toString();
1476
1477}
1478
1480{
1481 Q_Q(QAbstractSpinBox);
1482 QStyleOptionSpinBox opt;
1483 q->initStyleOption(&opt);
1484 opt.subControls = QStyle::SC_SpinBoxEditField;
1485 edit->setGeometry(q->style()->subControlRect(QStyle::CC_SpinBox, &opt,
1487}
1494{
1495 return (value == minimum && !specialValueText.isEmpty());
1496}
1497
1506
1515{
1516 Q_Q(QAbstractSpinBox);
1517
1518 if (keyboardTracking) {
1519 QString tmp = t;
1520 int pos = edit->cursorPosition();
1521 QValidator::State state = q->validate(tmp, pos);
1523 const QVariant v = valueFromText(tmp);
1524 setValue(v, EmitIfChanged, tmp != t);
1525 pendingEmit = false;
1526 } else {
1527 pendingEmit = true;
1528 }
1529 } else {
1530 pendingEmit = true;
1531 }
1532}
1533
1545{
1548
1549 bool allowSelection = true;
1550 int pos = -1;
1551 if (newpos < prefix.size() && newpos != 0) {
1552 if (oldpos == 0) {
1553 allowSelection = false;
1554 pos = prefix.size();
1555 } else {
1556 pos = oldpos;
1557 }
1558 } else if (newpos > edit->text().size() - suffix.size()
1559 && newpos != edit->text().size()) {
1560 if (oldpos == edit->text().size()) {
1561 pos = edit->text().size() - suffix.size();
1562 allowSelection = false;
1563 } else {
1564 pos = edit->text().size();
1565 }
1566 }
1567 if (pos != -1) {
1568 const int selSize = edit->selectionStart() >= 0 && allowSelection
1569 ? (edit->selectedText().size()
1570 * (newpos < pos ? -1 : 1)) - newpos + pos
1571 : 0;
1572
1573 const QSignalBlocker blocker(edit);
1574 if (selSize != 0) {
1575 edit->setSelection(pos - selSize, selSize);
1576 } else {
1578 }
1579 }
1581 }
1582}
1583
1591{
1592 Q_Q(QAbstractSpinBox);
1593
1594 q->setLineEdit(new QLineEdit(q));
1595 edit->setObjectName("qt_spinbox_lineedit"_L1);
1596 validator = new QSpinBoxValidator(q, this);
1598
1599 QStyleOptionSpinBox opt;
1600 // ### This is called from the ctor and thus we shouldn't call initStyleOption yet
1601 // ### as we only call the base class implementation of initStyleOption called.
1602 q->initStyleOption(&opt);
1605 q->setFocusPolicy(Qt::WheelFocus);
1607 q->setAttribute(Qt::WA_InputMethodEnabled);
1608
1609 q->setAttribute(Qt::WA_MacShowFocusRect);
1610}
1611
1620{
1621 Q_Q(QAbstractSpinBox);
1622
1623 buttonState = None;
1624 if (q) {
1625 if (spinClickTimerId != -1)
1626 q->killTimer(spinClickTimerId);
1627 if (spinClickThresholdTimerId != -1)
1628 q->killTimer(spinClickThresholdTimerId);
1630 acceleration = 0;
1631 q->update();
1632 }
1633}
1634
1641void QAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */)
1642{
1643 Q_Q(QAbstractSpinBox);
1644 if ((up && (buttonState & Up)) || (!up && (buttonState & Down)))
1645 return;
1646 reset();
1647 if (q && (q->stepEnabled() & (up ? QAbstractSpinBox::StepUpEnabled
1649 buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse);
1650 int steps = up ? 1 : -1;
1652 steps *= 10;
1653 q->stepBy(steps);
1655#if QT_CONFIG(accessibility)
1656 QAccessibleValueChangeEvent event(q, value);
1657 QAccessible::updateAccessibility(&event);
1658#endif
1659 }
1660}
1661
1662
1670void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const
1671{
1672 if (!option)
1673 return;
1674
1675 Q_D(const QAbstractSpinBox);
1676 option->initFrom(this);
1677 option->activeSubControls = QStyle::SC_None;
1678 option->buttonSymbols = d->buttonSymbols;
1679 option->subControls = QStyle::SC_SpinBoxEditField;
1680 if (style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this))
1681 option->subControls |= QStyle::SC_SpinBoxFrame;
1682 if (d->buttonSymbols != QAbstractSpinBox::NoButtons) {
1684 if (d->buttonState & Up) {
1685 option->activeSubControls = QStyle::SC_SpinBoxUp;
1686 } else if (d->buttonState & Down) {
1687 option->activeSubControls = QStyle::SC_SpinBoxDown;
1688 }
1689 }
1690
1691 if (d->buttonState) {
1692 option->state |= QStyle::State_Sunken;
1693 } else {
1694 option->activeSubControls = d->hoverControl;
1695 }
1696
1697 option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds, nullptr, this)
1698 ? stepEnabled()
1700
1701 option->frame = d->frame;
1702}
1703
1712QVariant QAbstractSpinBoxPrivate::bound(const QVariant &val, const QVariant &old, int steps) const
1713{
1714 QVariant v = val;
1715 if (!wrapping || steps == 0 || old.isNull()) {
1716 if (variantCompare(v, minimum) < 0) {
1717 v = wrapping ? maximum : minimum;
1718 }
1719 if (variantCompare(v, maximum) > 0) {
1720 v = wrapping ? minimum : maximum;
1721 }
1722 } else {
1723 const bool wasMin = old == minimum;
1724 const bool wasMax = old == maximum;
1725 const int oldcmp = variantCompare(v, old);
1726 const int maxcmp = variantCompare(v, maximum);
1727 const int mincmp = variantCompare(v, minimum);
1728 const bool wrapped = (oldcmp > 0 && steps < 0) || (oldcmp < 0 && steps > 0);
1729 if (maxcmp > 0) {
1730 v = ((wasMax && !wrapped && steps > 0) || (steps < 0 && !wasMin && wrapped))
1731 ? minimum : maximum;
1732 } else if (wrapped && (maxcmp > 0 || mincmp < 0)) {
1733 v = ((wasMax && steps > 0) || (!wasMin && steps < 0)) ? minimum : maximum;
1734 } else if (mincmp < 0) {
1735 v = (!wasMax && !wasMin ? minimum : maximum);
1736 }
1737 }
1738
1739 return v;
1740}
1741
1750 bool doUpdate)
1751{
1752 Q_Q(QAbstractSpinBox);
1753 const QVariant old = value;
1754 value = bound(val);
1755 pendingEmit = false;
1756 cleared = false;
1757 if (doUpdate) {
1758 updateEdit();
1759 }
1760 q->update();
1761
1762 if (ep == AlwaysEmit || (ep == EmitIfChanged && old != value)) {
1763 emitSignals(ep, old);
1764 }
1765}
1766
1774{
1775 Q_Q(QAbstractSpinBox);
1777 return;
1779 if (newText == edit->displayText() || cleared)
1780 return;
1781
1782 const bool empty = edit->text().isEmpty();
1783 int cursor = edit->cursorPosition();
1784 int selsize = edit->selectedText().size();
1785 const QSignalBlocker blocker(edit);
1786 edit->setText(newText);
1787
1788 if (!specialValue()) {
1790
1791 if (selsize > 0) {
1792 edit->setSelection(cursor, selsize);
1793 } else {
1794 edit->setCursorPosition(empty ? prefix.size() : cursor);
1795 }
1796 }
1797 q->update();
1798}
1799
1807{
1808 Q_Q(QAbstractSpinBox);
1809
1810 clearCache();
1811 minimum = min;
1812 maximum = (variantCompare(min, max) < 0 ? max : min);
1814 cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about min/max
1815
1816 reset();
1817 if (!(bound(value) == value)) {
1819 } else if (value == minimum && !specialValueText.isEmpty()) {
1820 updateEdit();
1821 }
1822
1823 q->updateGeometry();
1824}
1825
1833{
1834 QVariant ret;
1835 switch (type) {
1836 case QMetaType::Int: ret = QVariant(0); break;
1837 case QMetaType::Double: ret = QVariant(0.0); break;
1838 default: break;
1839 }
1840 return ret;
1841}
1842
1855{
1856 return QString();
1857}
1858
1871{
1872 return QVariant();
1873}
1882{
1883 Q_Q(QAbstractSpinBox);
1885 return;
1886
1888 bool doInterpret = true;
1889 QString tmp = edit->displayText();
1890 int pos = edit->cursorPosition();
1891 const int oldpos = pos;
1892
1893 if (q->validate(tmp, pos) != QValidator::Acceptable) {
1894 const QString copy = tmp;
1895 q->fixup(tmp);
1896 QASBDEBUG() << "QAbstractSpinBoxPrivate::interpret() text '"
1897 << edit->displayText()
1898 << "' >> '" << copy << '\''
1899 << "' >> '" << tmp << '\'';
1900
1901 doInterpret = tmp != copy && (q->validate(tmp, pos) == QValidator::Acceptable);
1902 if (!doInterpret) {
1905 }
1906 }
1907 if (doInterpret) {
1908 v = valueFromText(tmp);
1909 }
1910 clearCache();
1911 setValue(v, ep, true);
1912 if (oldpos != pos)
1914}
1915
1922
1924{
1925 Q_UNUSED(steps);
1926 return singleStep;
1927}
1928
1929// --- QSpinBoxValidator ---
1930
1937 : QValidator(qp), qptr(qp), dptr(dp)
1938{
1939 setObjectName("qt_spinboxvalidator"_L1);
1940}
1941
1950{
1951 if (dptr->specialValueText.size() > 0 && input == dptr->specialValueText)
1953
1954 if (!dptr->prefix.isEmpty() && !input.startsWith(dptr->prefix)) {
1955 input.prepend(dptr->prefix);
1956 pos += dptr->prefix.size();
1957 }
1958
1959 if (!dptr->suffix.isEmpty() && !input.endsWith(dptr->suffix))
1960 input.append(dptr->suffix);
1961
1962 return qptr->validate(input, pos);
1963}
1970{
1971 qptr->fixup(input);
1972}
1973
1974// --- global ---
1975
1982{
1983 QVariant ret;
1984 if (Q_UNLIKELY(arg1.userType() != arg2.userType()))
1985 qWarning("QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
1986 arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
1987 switch (arg1.userType()) {
1988 case QMetaType::Int: {
1989 const int int1 = arg1.toInt();
1990 const int int2 = arg2.toInt();
1991 if (int1 > 0 && (int2 >= INT_MAX - int1)) {
1992 // The increment overflows
1993 ret = QVariant(INT_MAX);
1994 } else if (int1 < 0 && (int2 <= INT_MIN - int1)) {
1995 // The increment underflows
1996 ret = QVariant(INT_MIN);
1997 } else {
1998 ret = QVariant(int1 + int2);
1999 }
2000 break;
2001 }
2002 case QMetaType::Double: ret = QVariant(arg1.toDouble() + arg2.toDouble()); break;
2003#if QT_CONFIG(datetimeparser)
2004 case QMetaType::QDateTime: {
2005 QDateTime a2 = arg2.toDateTime();
2006 QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATE_MIN.daysTo(a2.date()));
2007 a1.setTime(a1.time().addMSecs(a2.time().msecsSinceStartOfDay()));
2008 ret = QVariant(a1);
2009 break;
2010 }
2011#endif // datetimeparser
2012 default: break;
2013 }
2014 return ret;
2015}
2016
2017
2024{
2025 QVariant ret;
2026 if (Q_UNLIKELY(arg1.userType() != arg2.userType()))
2027 qWarning("QAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)",
2028 arg1.typeName(), arg2.typeName(), __FILE__, __LINE__);
2029 switch (arg1.userType()) {
2030 case QMetaType::Int: ret = QVariant(arg1.toInt() - arg2.toInt()); break;
2031 case QMetaType::Double: ret = QVariant(arg1.toDouble() - arg2.toDouble()); break;
2032 case QMetaType::QDateTime: {
2033 QDateTime a1 = arg1.toDateTime();
2034 QDateTime a2 = arg2.toDateTime();
2035 int days = a2.daysTo(a1);
2036 int secs = a2.secsTo(a1);
2037 int msecs = qMax(0, a1.time().msec() - a2.time().msec());
2038 if (days < 0 || secs < 0 || msecs < 0) {
2039 ret = arg1;
2040 } else {
2041 QDateTime dt = a2.addDays(days).addSecs(secs);
2042 if (msecs > 0)
2043 dt.setTime(dt.time().addMSecs(msecs));
2044 ret = QVariant(dt);
2045 }
2046 break;
2047 }
2048 default: break;
2049 }
2050 return ret;
2051}
2052
2058QVariant operator*(const QVariant &arg1, double multiplier)
2059{
2060 QVariant ret;
2061
2062 switch (arg1.userType()) {
2063 case QMetaType::Int:
2064 ret = static_cast<int>(qBound<double>(INT_MIN, arg1.toInt() * multiplier, INT_MAX));
2065 break;
2066 case QMetaType::Double: ret = QVariant(arg1.toDouble() * multiplier); break;
2067#if QT_CONFIG(datetimeparser)
2068 case QMetaType::QDateTime: {
2069 double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier;
2070 const qint64 daysInt = qint64(days);
2071 days -= daysInt;
2072 qint64 msecs = qint64(arg1.toDateTime().time().msecsSinceStartOfDay() * multiplier
2073 + days * (24 * 3600 * 1000));
2074 ret = QDATETIMEEDIT_DATE_MIN.addDays(daysInt).startOfDay().addMSecs(msecs);
2075 break;
2076 }
2077#endif // datetimeparser
2078 default: ret = arg1; break;
2079 }
2080
2081 return ret;
2082}
2083
2084
2085
2086double operator/(const QVariant &arg1, const QVariant &arg2)
2087{
2088 double a1 = 0;
2089 double a2 = 0;
2090
2091 switch (arg1.userType()) {
2092 case QMetaType::Int:
2093 a1 = (double)arg1.toInt();
2094 a2 = (double)arg2.toInt();
2095 break;
2096 case QMetaType::Double:
2097 a1 = arg1.toDouble();
2098 a2 = arg2.toDouble();
2099 break;
2100#if QT_CONFIG(datetimeparser)
2101 case QMetaType::QDateTime:
2102 a1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate());
2103 a2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate());
2104 a1 += arg1.toDateTime().time().msecsSinceStartOfDay() / (36e5 * 24);
2105 a2 += arg2.toDateTime().time().msecsSinceStartOfDay() / (36e5 * 24);
2106 break;
2107#endif // datetimeparser
2108 default: break;
2109 }
2110
2111 return (a1 != 0 && a2 != 0) ? (a1 / a2) : 0.0;
2112}
2113
2115{
2116 switch (arg2.userType()) {
2117 case QMetaType::QDate:
2118 Q_ASSERT_X(arg1.userType() == QMetaType::QDate, "QAbstractSpinBoxPrivate::variantCompare",
2119 qPrintable(QString::fromLatin1("Internal error 1 (%1)").
2120 arg(QString::fromLatin1(arg1.typeName()))));
2121 if (arg1.toDate() == arg2.toDate()) {
2122 return 0;
2123 } else if (arg1.toDate() < arg2.toDate()) {
2124 return -1;
2125 } else {
2126 return 1;
2127 }
2128 case QMetaType::QTime:
2129 Q_ASSERT_X(arg1.userType() == QMetaType::QTime, "QAbstractSpinBoxPrivate::variantCompare",
2130 qPrintable(QString::fromLatin1("Internal error 2 (%1)").
2131 arg(QString::fromLatin1(arg1.typeName()))));
2132 if (arg1.toTime() == arg2.toTime()) {
2133 return 0;
2134 } else if (arg1.toTime() < arg2.toTime()) {
2135 return -1;
2136 } else {
2137 return 1;
2138 }
2139
2140
2141 case QMetaType::QDateTime:
2142 if (arg1.toDateTime() == arg2.toDateTime()) {
2143 return 0;
2144 } else if (arg1.toDateTime() < arg2.toDateTime()) {
2145 return -1;
2146 } else {
2147 return 1;
2148 }
2149 case QMetaType::Int:
2150 if (arg1.toInt() == arg2.toInt()) {
2151 return 0;
2152 } else if (arg1.toInt() < arg2.toInt()) {
2153 return -1;
2154 } else {
2155 return 1;
2156 }
2157 case QMetaType::Double:
2158 if (arg1.toDouble() == arg2.toDouble()) {
2159 return 0;
2160 } else if (arg1.toDouble() < arg2.toDouble()) {
2161 return -1;
2162 } else {
2163 return 1;
2164 }
2166 if (arg2.userType() == QMetaType::UnknownType)
2167 return 0;
2168 Q_FALLTHROUGH();
2169 default:
2170 Q_ASSERT_X(0, "QAbstractSpinBoxPrivate::variantCompare",
2171 qPrintable(QString::fromLatin1("Internal error 3 (%1 %2)").
2172 arg(QString::fromLatin1(arg1.typeName()),
2173 QString::fromLatin1(arg2.typeName()))));
2174 }
2175 return -2;
2176}
2177
2179 const QVariant &value,
2180 const QVariant &max)
2181{
2182 Q_ASSERT(variantCompare(min, max) <= 0);
2183 if (variantCompare(min, value) < 0) {
2184 const int compMax = variantCompare(value, max);
2185 return (compMax < 0 ? value : max);
2186 } else {
2187 return min;
2188 }
2189}
2190
2191
2193
2194#include "moc_qabstractspinbox.cpp"
virtual QVariant valueFromText(const QString &input) const
virtual void emitSignals(EmitPolicy ep, const QVariant &old)
virtual QStyle::SubControl newHoverControl(const QPoint &pos)
static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max)
virtual QVariant getZeroVariant() const
virtual void editorCursorPositionChanged(int oldpos, int newpos)
virtual void setRange(const QVariant &min, const QVariant &max)
QSpinBoxValidator * validator
static int variantCompare(const QVariant &arg1, const QVariant &arg2)
QString stripped(const QString &text, int *pos=nullptr) const
Qt::KeyboardModifier stepModifier
Qt::KeyboardModifiers keyboardModifiers
void editorTextChanged(const QString &)
virtual void interpret(EmitPolicy ep)
QStyle::SubControl hoverControl
virtual void updateEditFieldGeometry()
virtual QString textFromValue(const QVariant &n) const
void updateState(bool up, bool fromKeyboard=false)
virtual QVariant bound(const QVariant &val, const QVariant &old=QVariant(), int steps=0) const
virtual void clearCache() const
QValidator::State cachedState
void setValue(const QVariant &val, EmitPolicy ep, bool updateEdit=true)
bool updateHoverControl(const QPoint &pos)
QAbstractSpinBox::CorrectionMode correctionMode
virtual QVariant calculateAdaptiveDecimalStep(int steps) const
The QAbstractSpinBox class provides a spinbox and a line edit to display values.
QString specialValueText
the special-value text
void selectAll()
Selects all the text in the spinbox except the prefix and suffix.
void editingFinished()
This signal is emitted editing is finished.
void focusInEvent(QFocusEvent *event) override
\reimp
QString text
the spin box's text, including any prefix and suffix
void setButtonSymbols(ButtonSymbols bs)
void interpretText()
This function interprets the text of the spin box.
void setSpecialValueText(const QString &txt)
bool isGroupSeparatorShown() const
void hideEvent(QHideEvent *event) override
\reimp
void mouseMoveEvent(QMouseEvent *event) override
\reimp
void setCorrectionMode(CorrectionMode cm)
void changeEvent(QEvent *event) override
\reimp
void paintEvent(QPaintEvent *event) override
\reimp
void resizeEvent(QResizeEvent *event) override
\reimp
void setKeyboardTracking(bool kt)
CorrectionMode correctionMode
the mode to correct an \l{QValidator::}{Intermediate} value if editing finishes
Qt::Alignment alignment
the alignment of the spin box
ButtonSymbols buttonSymbols
the current button symbol mode
void stepUp()
Steps up by one linestep Calling this slot is analogous to calling stepBy(1);.
void mousePressEvent(QMouseEvent *event) override
\reimp
~QAbstractSpinBox()
Called when the QAbstractSpinBox is destroyed.
QAbstractSpinBox(QWidget *parent=nullptr)
Constructs an abstract spinbox with the given parent with default \l wrapping, and \l alignment prope...
virtual void fixup(QString &input) const
This virtual function is called by the QAbstractSpinBox if the input is not validated to QValidator::...
bool keyboardTracking
whether keyboard tracking is enabled for the spinbox.
void setLineEdit(QLineEdit *edit)
Sets the line edit of the spinbox to be lineEdit instead of the current line edit widget.
virtual void stepBy(int steps)
Virtual function that is called whenever the user triggers a step.
void setAlignment(Qt::Alignment flag)
void setAccelerated(bool on)
QSize minimumSizeHint() const override
\reimp
void showEvent(QShowEvent *event) override
\reimp
void stepDown()
Steps down by one linestep Calling this slot is analogous to calling stepBy(-1);.
void closeEvent(QCloseEvent *event) override
\reimp
CorrectionMode
This enum type describes the mode the spinbox will use to correct an \l{QValidator::}{Intermediate} v...
virtual void initStyleOption(QStyleOptionSpinBox *option) const
Initialize option with the values from this QSpinBox.
void keyReleaseEvent(QKeyEvent *event) override
\reimp
void timerEvent(QTimerEvent *event) override
\reimp
QLineEdit * lineEdit() const
This function returns a pointer to the line edit of the spin box.
bool isAccelerated() const
QSize sizeHint() const override
\reimp
bool event(QEvent *event) override
\reimp
void mouseReleaseEvent(QMouseEvent *event) override
\reimp
void focusOutEvent(QFocusEvent *event) override
\reimp
virtual StepEnabled stepEnabled() const
Virtual function that determines whether stepping up and down is legal at any given time.
void setGroupSeparatorShown(bool shown)
bool wrapping
whether the spin box is circular.
bool hasAcceptableInput() const
virtual void clear()
Clears the lineedit of all text but prefix and suffix.
void keyPressEvent(QKeyEvent *event) override
\reimp
QVariant inputMethodQuery(Qt::InputMethodQuery) const override
\reimp
ButtonSymbols
This enum type describes the symbols that can be displayed on the buttons in a spin box.
virtual QValidator::State validate(QString &input, int &pos) const
This virtual function is called by the QAbstractSpinBox to determine whether input is valid.
The QAction class provides an abstraction for user commands that can be added to different user inter...
Definition qaction.h:30
void setEnabled(bool)
Definition qaction.cpp:927
The QCloseEvent class contains parameters that describe a close event.
Definition qevent.h:562
The QContextMenuEvent class contains parameters that describe a context menu event.
Definition qevent.h:594
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
\inmodule QtCore\reentrant
Definition qdatetime.h:283
\inmodule QtCore
Definition qcoreevent.h:45
@ EnabledChange
Definition qcoreevent.h:134
@ LayoutDirectionChange
Definition qcoreevent.h:124
@ ApplicationLayoutDirectionChange
Definition qcoreevent.h:92
@ ReadOnlyChange
Definition qcoreevent.h:145
@ ShortcutOverride
Definition qcoreevent.h:158
@ InputMethod
Definition qcoreevent.h:120
@ StyleChange
Definition qcoreevent.h:136
@ LocaleChange
Definition qcoreevent.h:122
@ FontChange
Definition qcoreevent.h:133
@ ActivationChange
Definition qcoreevent.h:135
@ HoverLeave
Definition qcoreevent.h:176
@ HoverEnter
Definition qcoreevent.h:175
@ HoverMove
Definition qcoreevent.h:177
The QFocusEvent class contains event parameters for widget focus events.
Definition qevent.h:470
\reentrant \inmodule QtGui
static QStyleHints * styleHints()
Returns the application's style hints.
QString platformName
The name of the underlying platform plugin.
The QHideEvent class provides an event which is sent after a widget is hidden.
Definition qevent.h:586
\inmodule QtGui
Definition qevent.h:246
The QKeyEvent class describes a key event.
Definition qevent.h:424
The QLineEdit widget is a one-line text editor.
Definition qlineedit.h:28
int cursorPosition
The current cursor position for this line edit.
Definition qlineedit.h:37
void setValidator(const QValidator *)
Sets the validator for values of line edit to v.
void cursorPositionChanged(int, int)
This signal is emitted whenever the cursor moves.
bool hasSelectedText
Whether there is any text selected.
Definition qlineedit.h:40
int selectionStart() const
Returns the index of the first selected character in the line edit (or -1 if no text is selected).
QString displayText
The displayed text.
Definition qlineedit.h:36
QString selectedText
The selected text.
Definition qlineedit.h:41
void setCursorPosition(int)
void textChanged(const QString &)
This signal is emitted whenever the text changes.
void setText(const QString &)
void setSelection(int, int)
Selects text from position start and for length characters.
QString text
The line edit's text.
Definition qlineedit.h:32
The QMenu class provides a menu widget for use in menu bars, context menus, and other popup menus.
Definition qmenu.h:26
QAction * exec()
Executes this menu synchronously.
Definition qmenu.cpp:2613
QAction * addSeparator()
This convenience function creates a new separator action, i.e.
Definition qmenu.cpp:1921
void addAction(QAction *action)
Appends the action action to this widget's list of actions.
Definition qwidget.cpp:3117
\inmodule QtGui
Definition qevent.h:196
static QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer< Func1 >::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer< Func2 >::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type=Qt::AutoConnection)
Definition qobject_p.h:299
int startTimer(int interval, Qt::TimerType timerType=Qt::CoarseTimer)
This is an overloaded function that will start a timer of type timerType and a timeout of interval mi...
Definition qobject.cpp:1817
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
virtual void timerEvent(QTimerEvent *event)
This event handler can be reimplemented in a subclass to receive timer events for the object.
Definition qobject.cpp:1470
Q_WEAK_OVERLOAD void setObjectName(const QString &name)
Sets the object's name to name.
Definition qobject.h:127
void killTimer(int id)
Kills the timer with timer identifier, id.
Definition qobject.cpp:1912
The QPaintEvent class contains event parameters for paint events.
Definition qevent.h:486
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
The QResizeEvent class contains event parameters for resize events.
Definition qevent.h:548
The QShowEvent class provides an event that is sent when a widget is shown.
Definition qevent.h:578
Exception-safe wrapper around QObject::blockSignals().
Definition qobject.h:483
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition qsizepolicy.h:18
\inmodule QtCore
Definition qsize.h:25
void fixup(QString &) const override
QSpinBoxValidator(QAbstractSpinBox *qptr, QAbstractSpinBoxPrivate *dptr)
QValidator::State validate(QString &input, int &) const override
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5455
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
void truncate(qsizetype pos)
Truncates the string at the given position index.
Definition qstring.cpp:6319
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
void clear()
Clears the contents of the string and makes it null.
Definition qstring.h:1252
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5506
QString trimmed() const &
Definition qstring.h:447
The QStylePainter class is a convenience class for drawing QStyle elements inside a widget.
@ State_Sunken
Definition qstyle.h:69
@ CT_SpinBox
Definition qstyle.h:562
virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w=nullptr) const =0
Returns the size of the element described by the specified option and type, based on the provided con...
@ SH_SpinBox_AnimateButton
Definition qstyle.h:627
@ SH_SpinBox_ClickAutoRepeatRate
Definition qstyle.h:629
@ SH_SpinControls_DisableOnBounds
Definition qstyle.h:641
@ SH_SpinBox_SelectOnStep
Definition qstyle.h:706
@ SH_SpinBox_StepModifier
Definition qstyle.h:703
@ SH_SpinBox_ClickAutoRepeatThreshold
Definition qstyle.h:668
@ SH_SpinBox_ButtonsInsideFrame
Definition qstyle.h:702
virtual int styleHint(StyleHint stylehint, const QStyleOption *opt=nullptr, const QWidget *widget=nullptr, QStyleHintReturn *returnData=nullptr) const =0
Returns an integer representing the specified style hint for the given widget described by the provid...
@ CC_SpinBox
Definition qstyle.h:332
SubControl
This enum describes the available sub controls.
Definition qstyle.h:347
@ SC_All
Definition qstyle.h:400
@ SC_SpinBoxDown
Definition qstyle.h:360
@ SC_SpinBoxUp
Definition qstyle.h:359
@ SC_None
Definition qstyle.h:348
@ SC_SpinBoxFrame
Definition qstyle.h:361
@ SC_SpinBoxEditField
Definition qstyle.h:362
\inmodule QtCore
Definition qcoreevent.h:366
The QValidator class provides validation of input text.
Definition qvalidator.h:24
State
This enum type defines the states in which a validated string can exist.
Definition qvalidator.h:30
\inmodule QtCore
Definition qvariant.h:65
T value() const &
Definition qvariant.h:516
void clear()
Convert this variant to type QMetaType::UnknownType and free up any resources used.
void setValue(T &&avalue)
Definition qvariant.h:493
bool isNull() const
Returns true if this is a null variant, false otherwise.
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:886
virtual void hideEvent(QHideEvent *event)
This event handler can be reimplemented in a subclass to receive widget hide events.
void updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
virtual void closeEvent(QCloseEvent *event)
This event handler is called with the given event when Qt receives a window close request for a top-l...
Definition qwidget.cpp:9856
QPointF mapToGlobal(const QPointF &) const
Translates the widget coordinate pos to global screen coordinates.
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
QPoint pos
the position of the widget within its parent widget
Definition qwidget.h:111
QFontMetrics fontMetrics() const
Returns the font metrics for the widget's current font.
Definition qwidget.h:847
virtual void focusInEvent(QFocusEvent *event)
This event handler can be reimplemented in a subclass to receive keyboard focus events (focus receive...
Definition qwidget.cpp:9665
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
void insertAction(QAction *before, QAction *action)
Inserts the action action to this widget's list of actions, before the action before.
Definition qwidget.cpp:3142
void ensurePolished() const
Ensures that the widget and its children have been polished by QStyle (i.e., have a proper font and p...
bool isEnabled() const
Definition qwidget.h:814
void update()
Updates the widget unless updates are disabled or the widget is hidden.
virtual void changeEvent(QEvent *)
This event handler can be reimplemented to handle state changes.
Definition qwidget.cpp:9382
Qt::InputMethodHints inputMethodHints
What input method specific hints the widget has.
Definition qwidget.h:178
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
QStyle * style() const
Definition qwidget.cpp:2600
virtual void focusOutEvent(QFocusEvent *event)
This event handler can be reimplemented in a subclass to receive keyboard focus events (focus lost) f...
Definition qwidget.cpp:9691
virtual void resizeEvent(QResizeEvent *event)
This event handler can be reimplemented in a subclass to receive widget resize events which are passe...
Definition qwidget.cpp:9822
bool isActiveWindow
whether this widget's window is the active window
Definition qwidget.h:139
void removeAction(QAction *action)
Removes the action action from this widget's list of actions.
Definition qwidget.cpp:3186
bool isVisible() const
Definition qwidget.h:874
virtual void contextMenuEvent(QContextMenuEvent *event)
This event handler, for event event, can be reimplemented in a subclass to receive widget context men...
Definition qwidget.cpp:9875
EGLImageKHR int int EGLuint64KHR * modifiers
QString text
QCursor cursor
QStyleOptionButton opt
else opt state
[0]
Combined button and popup list for selecting options.
InputMethodQuery
@ ImHints
@ LeftButton
Definition qnamespace.h:58
@ WA_Hover
Definition qnamespace.h:340
@ WA_MacShowFocusRect
Definition qnamespace.h:359
@ WA_InputMethodEnabled
Definition qnamespace.h:295
@ WheelFocus
Definition qnamespace.h:111
@ MouseEventNotSynthesized
@ Key_Select
@ Key_Return
Definition qnamespace.h:667
@ Key_Right
Definition qnamespace.h:679
@ Key_Enter
Definition qnamespace.h:668
@ Key_PageUp
Definition qnamespace.h:681
@ Key_U
Definition qnamespace.h:567
@ Key_Left
Definition qnamespace.h:677
@ Key_Up
Definition qnamespace.h:678
@ Key_Down
Definition qnamespace.h:680
@ Key_PageDown
Definition qnamespace.h:682
@ Key_Back
Definition qnamespace.h:846
@ Key_Home
Definition qnamespace.h:675
@ Key_End
Definition qnamespace.h:676
KeyboardModifier
@ ShiftModifier
@ ControlModifier
@ NoContextMenu
@ BacktabFocusReason
@ TabFocusReason
QVariant operator-(const QVariant &arg1, const QVariant &arg2)
#define QASBDEBUG
QVariant operator*(const QVariant &arg1, double multiplier)
double operator/(const QVariant &arg1, const QVariant &arg2)
QVariant operator+(const QVariant &arg1, const QVariant &arg2)
@ Keyboard
@ EmitIfChanged
@ NeverEmit
@ AlwaysEmit
static jboolean copy(JNIEnv *, jobject)
#define Q_FALLTHROUGH()
#define Q_UNLIKELY(x)
#define QDATETIMEEDIT_DATE_MIN
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
@ None
Definition qhash.cpp:531
#define qWarning
Definition qlogging.h:166
return ret
constexpr const T & qBound(const T &min, const T &val, const T &max)
Definition qminmax.h:44
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum type
GLboolean enable
GLfloat GLfloat GLfloat GLfloat h
struct _cl_event * event
GLdouble s
[6]
Definition qopenglext.h:235
GLenum query
GLuint GLfloat * val
GLuint GLuint GLuint GLuint arg1
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLenum GLenum input
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
SSL_CTX int void * arg
#define qPrintable(string)
Definition qstring.h:1531
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
#define a2
#define a1
#define tr(X)
#define emit
#define Q_UNUSED(x)
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
QLineEdit * lineEdit
QFrame frame
[0]
QMenu menu
[5]
args<< 1<< 2;QJSValue threeAgain=fun.call(args);QString fileName="helloworld.qs";QFile scriptFile(fileName);if(!scriptFile.open(QIODevice::ReadOnly)) QTextStream stream(&scriptFile);QString contents=stream.readAll();scriptFile.close();myEngine.evaluate(contents, fileName);myEngine.globalObject().setProperty("myNumber", 123);...QJSValue myNumberPlusOne=myEngine.evaluate("myNumber + 1");QJSValue result=myEngine.evaluate(...);if(result.isError()) qDebug()<< "Uncaught exception at line"<< result.property("lineNumber").toInt()<< ":"<< result.toString();QPushButton *button=new QPushButton;QJSValue scriptButton=myEngine.newQObject(button);myEngine.globalObject().setProperty("button", scriptButton);myEngine.evaluate("button.checkable = true");qDebug()<< scriptButton.property("checkable").toBool();scriptButton.property("show").call();QJSEngine engine;QObject *myQObject=new QObject();myQObject- setProperty)("dynamicProperty", 3)