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
qabstractslider.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 <qapplication.h>
5#include "qabstractslider.h"
6#include "qevent.h"
7#include "qabstractslider_p.h"
8#include "qdebug.h"
9#if QT_CONFIG(accessibility)
10#include "qaccessible.h"
11#endif
12#include <limits.h>
13
14#include <private/qapplication_p.h>
15
17
179 : minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1),
180 singleStep(1), singleStepFromItemView(-1), viewMayChangeSingleStep(true), offset_accumulated(0), tracking(true),
181 blocktracking(false), pressed(false),
182 invertedAppearance(false), invertedControls(false),
183 orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction)
184#ifdef QT_KEYPAD_NAVIGATION
185 , isAutoRepeating(false)
186 , repeatMultiplier(1)
187{
188 firstRepeat.invalidate();
189#else
190{
191#endif
192
193}
194
198
207void QAbstractSlider::setRange(int min, int max)
208{
209 Q_D(QAbstractSlider);
210 int oldMin = d->minimum;
211 int oldMax = d->maximum;
212 d->minimum = min;
213 d->maximum = qMax(min, max);
214 if (oldMin != d->minimum || oldMax != d->maximum) {
215 sliderChange(SliderRangeChange);
216 emit rangeChanged(d->minimum, d->maximum);
217 setValue(d->value); // re-bound
218 }
219}
220
221
223{
224 Q_Q(QAbstractSlider);
225 singleStep = qAbs(single);
226 pageStep = qAbs(page);
228}
229
243
246 :QWidget(dd, parent, { })
247{
248}
249
256
265{
266 Q_D(QAbstractSlider);
267 if (d->orientation == orientation)
268 return;
269
270 d->orientation = orientation;
272 setSizePolicy(sizePolicy().transposed());
274 }
275 update();
277}
278
280{
281 Q_D(const QAbstractSlider);
282 return d->orientation;
283}
284
285
297{
298 Q_D(QAbstractSlider);
299 setRange(min, qMax(d->maximum, min));
300}
301
303{
304 Q_D(const QAbstractSlider);
305 return d->minimum;
306}
307
308
321{
322 Q_D(QAbstractSlider);
323 setRange(qMin(d->minimum, max), max);
324}
325
327{
328 Q_D(const QAbstractSlider);
329 return d->maximum;
330}
331
332
333
349{
350 Q_D(QAbstractSlider);
351
352 d->viewMayChangeSingleStep = (step < 0);
353 if (step < 0 && d->singleStepFromItemView > 0)
354 step = d->singleStepFromItemView;
355
356 if (step != d->singleStep)
357 d->setSteps(step, d->pageStep);
358}
359
361{
362 Q_D(const QAbstractSlider);
363 return d->singleStep;
364}
365
366
378{
379 Q_D(QAbstractSlider);
380 if (step != d->pageStep)
381 d->setSteps(d->singleStep, step);
382}
383
385{
386 Q_D(const QAbstractSlider);
387 return d->pageStep;
388}
389
402{
403 Q_D(QAbstractSlider);
404 d->tracking = enable;
405}
406
408{
409 Q_D(const QAbstractSlider);
410 return d->tracking;
411}
412
413
426{
427 Q_D(QAbstractSlider);
428 bool doEmit = d->pressed != down;
429
430 d->pressed = down;
431
432 if (doEmit) {
433 if (down)
435 else
437 }
438
439 if (!down && d->position != d->value)
441}
442
444{
445 Q_D(const QAbstractSlider);
446 return d->pressed;
447}
448
449
457{
458 Q_D(QAbstractSlider);
459 position = d->bound(position);
460 if (position == d->position)
461 return;
462 d->position = position;
463 if (!d->tracking)
464 update();
465 if (d->pressed)
467 if (d->tracking && !d->blocktracking)
469}
470
472{
473 Q_D(const QAbstractSlider);
474 return d->position;
475}
476
477
490{
491 Q_D(const QAbstractSlider);
492 return d->value;
493}
494
496{
497 Q_D(QAbstractSlider);
498 value = d->bound(value);
499 if (d->value == value && d->position == value)
500 return;
501
502 // delay signal emission until sliderChanged() has been called
503 const bool emitValueChanged = (value != d->value);
504 d->value = value;
505
506 if (d->position != value) {
507 d->position = value;
508 if (d->pressed)
509 emit sliderMoved(d->position);
510 }
511#if QT_CONFIG(accessibility)
512 QAccessibleValueChangeEvent event(this, d->value);
513 QAccessible::updateAccessibility(&event);
514#endif
516
517 if (emitValueChanged)
519
520}
521
537{
538 Q_D(const QAbstractSlider);
539 return d->invertedAppearance;
540}
541
543{
544 Q_D(QAbstractSlider);
545 d->invertedAppearance = invert;
546 update();
547}
548
549
561{
562 Q_D(const QAbstractSlider);
563 return d->invertedControls;
564}
565
567{
568 Q_D(QAbstractSlider);
569 d->invertedControls = invert;
570}
571
580{
581 Q_D(QAbstractSlider);
582 d->blocktracking = true;
583 switch (action) {
585 setSliderPosition(d->overflowSafeAdd(d->effectiveSingleStep()));
586 break;
588 setSliderPosition(d->overflowSafeAdd(-d->effectiveSingleStep()));
589 break;
591 setSliderPosition(d->overflowSafeAdd(d->pageStep));
592 break;
594 setSliderPosition(d->overflowSafeAdd(-d->pageStep));
595 break;
596 case SliderToMinimum:
597 setSliderPosition(d->minimum);
598 break;
599 case SliderToMaximum:
600 setSliderPosition(d->maximum);
601 break;
602 case SliderMove:
603 case SliderNoAction:
604 break;
605 };
606 emit actionTriggered(action);
607 d->blocktracking = false;
608 setValue(d->position);
609}
610
616void QAbstractSlider::setRepeatAction(SliderAction action, int thresholdTime, int repeatTime)
617{
618 Q_D(QAbstractSlider);
619 if ((d->repeatAction = action) == SliderNoAction) {
620 d->repeatActionTimer.stop();
621 } else {
622 d->repeatActionTime = repeatTime;
623 d->repeatActionTimer.start(thresholdTime, this);
624 }
625}
626
632{
633 Q_D(const QAbstractSlider);
634 return d->repeatAction;
635}
636
640{
641 Q_D(QAbstractSlider);
642 if (e->timerId() == d->repeatActionTimer.timerId()) {
643 if (d->repeatActionTime) { // was threshold time, use repeat time next time
644 d->repeatActionTimer.start(d->repeatActionTime, this);
645 d->repeatActionTime = 0;
646 }
647 if (d->repeatAction == SliderPageStepAdd)
648 d->setAdjustedSliderPosition(d->overflowSafeAdd(d->pageStep));
649 else if (d->repeatAction == SliderPageStepSub)
650 d->setAdjustedSliderPosition(d->overflowSafeAdd(-d->pageStep));
651 else
652 triggerAction(d->repeatAction);
653 }
654}
655
667
668bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta)
669{
670 Q_Q(QAbstractSlider);
671 int stepsToScroll = 0;
672 // in Qt scrolling to the right gives negative values.
674 delta = -delta;
675 qreal offset = qreal(delta) / 120;
676
678 // Scroll one page regardless of delta:
679 stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep);
681 } else {
682 // Calculate how many lines to scroll. Depending on what delta is (and
683 // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can
684 // only scroll whole lines, so we keep the reminder until next event.
685 qreal stepsToScrollF =
686#if QT_CONFIG(wheelevent)
687 QApplication::wheelScrollLines() *
688#endif
690 // Check if wheel changed direction since last event:
691 if (offset_accumulated != 0 && (offset / offset_accumulated) < 0)
693
694 offset_accumulated += stepsToScrollF;
695
696 // Don't scroll more than one page in any case:
697 stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep);
698
700 if (stepsToScroll == 0) {
701 // We moved less than a line, but might still have accumulated partial scroll,
702 // unless we already are at one of the ends.
703 const float effective_offset = invertedControls ? -offset_accumulated : offset_accumulated;
704 if (effective_offset > 0.f && value < maximum)
705 return true;
706 if (effective_offset < 0.f && value > minimum)
707 return true;
709 return false;
710 }
711 }
712
714 stepsToScroll = -stepsToScroll;
715
716 int prevValue = value;
717 position = bound(overflowSafeAdd(stepsToScroll)); // value will be updated by triggerAction()
718 q->triggerAction(QAbstractSlider::SliderMove);
719
720 if (prevValue == value) {
722 return false;
723 }
724 return true;
725}
726
730#if QT_CONFIG(wheelevent)
731void QAbstractSlider::wheelEvent(QWheelEvent * e)
732{
733 Q_D(QAbstractSlider);
734 e->ignore();
735 bool vertical = bool(e->angleDelta().y());
736 int delta = vertical ? e->angleDelta().y() : e->angleDelta().x();
737 if (e->inverted())
738 delta = -delta;
739 if (d->scrollByDelta(vertical ? Qt::Vertical : Qt::Horizontal, e->modifiers(), delta))
740 e->accept();
741}
742
743#endif
744
749{
750 Q_D(QAbstractSlider);
752#ifdef QT_KEYPAD_NAVIGATION
753 if (ev->isAutoRepeat()) {
754 if (!d->firstRepeat.isValid())
755 d->firstRepeat.start();
756 else if (1 == d->repeatMultiplier) {
757 // This is the interval in milli seconds which one key repetition
758 // takes.
759 const int repeatMSecs = d->firstRepeat.elapsed();
760
764 const qreal currentTimeElapse = (qreal(maximum()) / singleStep()) * repeatMSecs;
765
771 const int SliderRepeatElapse = 2500;
772
773 d->repeatMultiplier = currentTimeElapse / SliderRepeatElapse;
774 }
775
776 }
777 else if (d->firstRepeat.isValid()) {
778 d->firstRepeat.invalidate();
779 d->repeatMultiplier = 1;
780 }
781
782#endif
783
784 switch (ev->key()) {
785#ifdef QT_KEYPAD_NAVIGATION
786 case Qt::Key_Select:
787 if (QApplicationPrivate::keypadNavigationEnabled())
788 setEditFocus(!hasEditFocus());
789 else
790 ev->ignore();
791 break;
792 case Qt::Key_Back:
793 if (QApplicationPrivate::keypadNavigationEnabled() && hasEditFocus()) {
794 setValue(d->origValue);
795 setEditFocus(false);
796 } else
797 ev->ignore();
798 break;
799#endif
800
801 case Qt::Key_Left:
802#ifdef QT_KEYPAD_NAVIGATION
803 // In QApplication::KeypadNavigationDirectional, we want to change the slider
804 // value if there is no left/right navigation possible and if this slider is not
805 // inside a tab widget.
806 if (QApplicationPrivate::keypadNavigationEnabled()
807 && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
808 || d->orientation == Qt::Vertical
809 || !hasEditFocus()
810 && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
811 ev->ignore();
812 return;
813 }
814 if (QApplicationPrivate::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
815 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
816 else
817#endif
818 if (isRightToLeft())
819 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
820 else
821 action = !d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
822 break;
823 case Qt::Key_Right:
824#ifdef QT_KEYPAD_NAVIGATION
825 // Same logic as in Qt::Key_Left
826 if (QApplicationPrivate::keypadNavigationEnabled()
827 && (!hasEditFocus() && QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
828 || d->orientation == Qt::Vertical
829 || !hasEditFocus()
830 && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this)))) {
831 ev->ignore();
832 return;
833 }
834 if (QApplicationPrivate::keypadNavigationEnabled() && d->orientation == Qt::Vertical)
835 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
836 else
837#endif
838 if (isRightToLeft())
839 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
840 else
841 action = !d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
842 break;
843 case Qt::Key_Up:
844#ifdef QT_KEYPAD_NAVIGATION
845 // In QApplication::KeypadNavigationDirectional, we want to change the slider
846 // value if there is no up/down navigation possible.
847 if (QApplicationPrivate::keypadNavigationEnabled()
848 && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
849 || d->orientation == Qt::Horizontal
850 || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
851 ev->ignore();
852 break;
853 }
854#endif
855 action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd;
856 break;
857 case Qt::Key_Down:
858#ifdef QT_KEYPAD_NAVIGATION
859 // Same logic as in Qt::Key_Up
860 if (QApplicationPrivate::keypadNavigationEnabled()
861 && (QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder
862 || d->orientation == Qt::Horizontal
863 || !hasEditFocus() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical))) {
864 ev->ignore();
865 break;
866 }
867#endif
868 action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub;
869 break;
870 case Qt::Key_PageUp:
871 action = d->invertedControls ? SliderPageStepSub : SliderPageStepAdd;
872 break;
873 case Qt::Key_PageDown:
874 action = d->invertedControls ? SliderPageStepAdd : SliderPageStepSub;
875 break;
876 case Qt::Key_Home:
877 action = SliderToMinimum;
878 break;
879 case Qt::Key_End:
880 action = SliderToMaximum;
881 break;
882 default:
883 ev->ignore();
884 break;
885 }
886 if (action)
887 triggerAction(action);
888}
889
894{
895 Q_D(QAbstractSlider);
896 switch (ev->type()) {
898 if (!isEnabled()) {
899 d->repeatActionTimer.stop();
900 setSliderDown(false);
901 }
903 default:
905 }
906}
907
912{
913#ifdef QT_KEYPAD_NAVIGATION
914 Q_D(QAbstractSlider);
915 switch (e->type()) {
916 case QEvent::FocusIn:
917 d->origValue = d->value;
918 break;
919 default:
920 break;
921 }
922#endif
923
924 return QWidget::event(e);
925}
926
927// This function is called from itemviews when doing scroll per pixel (on updateGeometries())
928// It will not have any effect if there has been a call to setSingleStep with
929// a 'reasonable' value (since viewMayChangeSingleStep will be set to false).
930// (If setSingleStep is called with -1 it will however allow the views to change singleStep.)
931
938
940
941#include "moc_qabstractslider.cpp"
int overflowSafeAdd(int add) const
void itemviewChangeSingleStep(int step)
void setSteps(int single, int page)
virtual int bound(int val) const
Qt::Orientation orientation
bool scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta)
The QAbstractSlider class provides an integer value within a range.
bool invertedControls
whether or not the slider inverts its wheel and key events.
void sliderPressed()
This signal is emitted when the user presses the slider with the mouse, or programmatically when setS...
void keyPressEvent(QKeyEvent *ev) override
\reimp
void setInvertedControls(bool)
int value
the slider's current value
QAbstractSlider(QWidget *parent=nullptr)
Constructs an abstract slider.
SliderAction repeatAction() const
Returns the current repeat action.
void setRepeatAction(SliderAction action, int thresholdTime=500, int repeatTime=50)
Sets action action to be triggered repetitively in intervals of repeatTime, after an initial delay of...
void sliderReleased()
This signal is emitted when the user releases the slider with the mouse, or programmatically when set...
virtual void sliderChange(SliderChange change)
Reimplement this virtual function to track slider changes such as \l SliderRangeChange,...
void valueChanged(int value)
This signal is emitted when the slider value has changed, with the new slider value as argument.
SliderAction
\value SliderNoAction \value SliderSingleStepAdd \value SliderSingleStepSub \value SliderPageStepAdd ...
void setTracking(bool enable)
void setInvertedAppearance(bool)
bool isSliderDown() const
int pageStep
the page step.
void setOrientation(Qt::Orientation)
Qt::Orientation orientation
the orientation of the slider
void actionTriggered(int action)
This signal is emitted when the slider action action is triggered.
int sliderPosition
the current slider position
int singleStep
the single step.
bool invertedAppearance
whether or not a slider shows its values inverted.
void sliderMoved(int position)
This signal is emitted when sliderDown is true and the slider moves.
void timerEvent(QTimerEvent *) override
\reimp
bool hasTracking() const
bool event(QEvent *e) override
\reimp
int minimum
the sliders's minimum value
void setRange(int min, int max)
Sets the slider's minimum to min and its maximum to max.
void setSliderPosition(int)
SliderChange
\value SliderRangeChange \value SliderOrientationChange \value SliderStepsChange \value SliderValueCh...
int maximum
the slider's maximum value
void changeEvent(QEvent *e) override
\reimp
~QAbstractSlider()
Destroys the slider.
void triggerAction(SliderAction action)
Triggers a slider action.
\inmodule QtCore
Definition qcoreevent.h:45
@ EnabledChange
Definition qcoreevent.h:134
@ FocusIn
Definition qcoreevent.h:66
Type type() const
Returns the event type.
Definition qcoreevent.h:304
The QKeyEvent class describes a key event.
Definition qevent.h:424
QObject * parent
Definition qobject.h:73
\inmodule QtCore
Definition qcoreevent.h:366
int timerId() const
Returns the unique timer identifier, which is the same identifier as returned from QObject::startTime...
Definition qcoreevent.h:370
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setAttribute(Qt::WidgetAttribute, bool on=true)
Sets the attribute attribute on this widget if on is true; otherwise clears the attribute.
void updateGeometry()
Notifies the layout system that this widget has changed and may need to change geometry.
void setSizePolicy(QSizePolicy)
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition qwidget.h:119
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
bool isRightToLeft() const
Definition qwidget.h:419
bool event(QEvent *event) override
This is the main event handler; it handles event event.
Definition qwidget.cpp:8866
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition qwidget.h:910
EGLImageKHR int int EGLuint64KHR * modifiers
Combined button and popup list for selecting options.
Definition qcompare.h:63
@ NavigationModeKeypadTabOrder
@ WA_WState_OwnSizePolicy
Definition qnamespace.h:334
Orientation
Definition qnamespace.h:98
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
@ Key_Select
@ Key_Right
Definition qnamespace.h:679
@ Key_PageUp
Definition qnamespace.h:681
@ 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
@ ShiftModifier
@ ControlModifier
#define Q_FALLTHROUGH()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
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
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLboolean enable
GLenum GLuint GLintptr offset
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLboolean invert
Definition qopenglext.h:226
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
#define emit
double qreal
Definition qtypes.h:187
settings setValue("DataPump/bgcolor", color)
QByteArray page
[45]