Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qquicktumbler.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 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 "qquicktumbler_p.h"
5
6#include <QtCore/qloggingcategory.h>
7#include <QtGui/qpa/qplatformtheme.h>
8#include <QtQml/qqmlinfo.h>
9#include <QtQuick/private/qquickflickable_p.h>
10#include <QtQuickTemplates2/private/qquickcontrol_p_p.h>
11#include <QtQuickTemplates2/private/qquicktumbler_p_p.h>
12
14
15Q_LOGGING_CATEGORY(lcTumbler, "qt.quick.controls.tumbler")
16
17
21
60namespace {
61 static inline qreal delegateHeight(const QQuickTumbler *tumbler)
62 {
63 return tumbler->availableHeight() / tumbler->visibleItemCount();
64 }
65}
66
67/*
68 Finds the contentItem of the view that is a child of the control's \a contentItem.
69 The type is stored in \a type.
70*/
72{
73 if (!contentItem) {
75 return nullptr;
76 }
77
78 if (contentItem->inherits("QQuickPathView")) {
82 viewOffset = 0;
83
84 return contentItem;
85 } else if (contentItem->inherits("QQuickListView")) {
87 viewContentItem = qobject_cast<QQuickFlickable*>(contentItem)->contentItem();
89 viewContentY = 0;
90
91 return contentItem;
92 } else {
93 const auto childItems = contentItem->childItems();
94 for (QQuickItem *childItem : childItems) {
95 QQuickItem *item = determineViewType(childItem);
96 if (item)
97 return item;
98 }
99 }
100
103 return nullptr;
104}
105
107{
108 view = nullptr;
109 viewContentItem = nullptr;
111 viewOffset = 0;
113 viewContentY = 0;
115}
116
118{
119 if (!viewContentItem)
120 return QList<QQuickItem *>();
121
122 return viewContentItem->childItems();
123}
124
126{
127 return tumbler->d_func();
128}
129
131{
132 if (ignoreSignals)
133 return;
134
135 // Can't use our own private padding members here, as the padding property might be set,
136 // which doesn't affect them, only their getters.
137 Q_Q(const QQuickTumbler);
138 const qreal itemHeight = delegateHeight(q);
139 const auto items = viewContentItemChildItems();
140 for (QQuickItem *childItem : items)
141 childItem->setHeight(itemHeight);
142}
143
145{
146 if (ignoreSignals)
147 return;
148
149 Q_Q(const QQuickTumbler);
150 const qreal availableWidth = q->availableWidth();
151 const auto items = viewContentItemChildItems();
152 for (QQuickItem *childItem : items)
153 childItem->setWidth(availableWidth);
154}
155
157{
158 Q_Q(QQuickTumbler);
160 // If the user set currentIndex in the onModelChanged handler,
161 // we have to respect that currentIndex by ignoring changes in the view
162 // until the model has finished being set.
163 qCDebug(lcTumbler).nospace() << "view currentIndex changed to "
164 << (view ? view->property("currentIndex").toString() : QStringLiteral("unknown index (no view)"))
165 << ", but we're ignoring it because one or more of the following conditions are true:"
166 << "\n- !view: " << !view
167 << "\n- ignoreCurrentIndexChanges: " << ignoreCurrentIndexChanges
168 << "\n- currentIndexSetDuringModelChange: " << currentIndexSetDuringModelChange;
169 return;
170 }
171
172 const int oldCurrentIndex = currentIndex;
173 currentIndex = view->property("currentIndex").toInt();
174
175 qCDebug(lcTumbler).nospace() << "view currentIndex changed to "
176 << (view ? view->property("currentIndex").toString() : QStringLiteral("unknown index (no view)"))
177 << ", our old currentIndex was " << oldCurrentIndex;
178
179 if (oldCurrentIndex != currentIndex)
180 emit q->currentIndexChanged();
181}
182
184{
185 Q_Q(QQuickTumbler);
186 qCDebug(lcTumbler) << "view count changed - ignoring signals?" << ignoreSignals;
187 if (ignoreSignals)
188 return;
189
190 setCount(view->property("count").toInt());
191
192 if (count > 0) {
193 if (pendingCurrentIndex != -1) {
194 // If there was an attempt to set currentIndex at creation, try to finish that attempt now.
195 // componentComplete() is too early, because the count might only be known sometime after completion.
197 // If we could successfully set the currentIndex, consider it done.
198 // Otherwise, we'll try again later in updatePolish().
201 else
202 q->polish();
203 } else if (currentIndex == -1) {
204 // If new items were added and our currentIndex was -1, we must
205 // enforce our rule of a non-negative currentIndex when count > 0.
207 }
208 } else {
209 setCurrentIndex(-1);
210 }
211}
212
214{
215 viewOffset = view->property("offset").toReal();
217}
218
220{
221 viewContentY = view->property("contentY").toReal();
223}
224
226{
227 const auto items = viewContentItemChildItems();
228 for (QQuickItem *childItem : items) {
229 QQuickTumblerAttached *attached = qobject_cast<QQuickTumblerAttached *>(qmlAttachedPropertiesObject<QQuickTumbler>(childItem, false));
230 if (attached)
232 }
233}
234
236{
239}
240
242{
245}
246
248{
250 if (change.sizeChange())
252}
253
255{
257}
258
261{
263
264 connect(this, SIGNAL(leftPaddingChanged()), this, SLOT(_q_updateItemWidths()));
265 connect(this, SIGNAL(rightPaddingChanged()), this, SLOT(_q_updateItemWidths()));
266 connect(this, SIGNAL(topPaddingChanged()), this, SLOT(_q_updateItemHeights()));
267 connect(this, SIGNAL(bottomPaddingChanged()), this, SLOT(_q_updateItemHeights()));
268}
269
271{
272 Q_D(QQuickTumbler);
273 // Ensure that the item change listener is removed.
274 d->disconnectFromView();
275}
276
283{
284 Q_D(const QQuickTumbler);
285 return d->model;
286}
287
289{
290 Q_D(QQuickTumbler);
291 if (model == d->model)
292 return;
293
294 d->beginSetModel();
295
296 d->model = model;
298
299 d->endSetModel();
300
301 d->currentIndexSetDuringModelChange = false;
302
303 // Don't try to correct the currentIndex if count() isn't known yet.
304 // We can check in setupViewData() instead.
305 if (isComponentComplete() && d->view && count() == 0)
306 d->setCurrentIndex(-1);
307}
308
316{
317 Q_D(const QQuickTumbler);
318 return d->count;
319}
320
332{
333 Q_D(const QQuickTumbler);
334 return d->currentIndex;
335}
336
337void QQuickTumbler::setCurrentIndex(int currentIndex)
338{
339 Q_D(QQuickTumbler);
340 if (d->modelBeingSet)
341 d->currentIndexSetDuringModelChange = true;
343}
344
354{
355 Q_D(const QQuickTumbler);
356 return d->view ? d->view->property("currentItem").value<QQuickItem*>() : nullptr;
357}
358
365{
366 Q_D(const QQuickTumbler);
367 return d->delegate;
368}
369
371{
372 Q_D(QQuickTumbler);
373 if (delegate == d->delegate)
374 return;
375
376 d->delegate = delegate;
378}
379
387{
388 Q_D(const QQuickTumbler);
389 return d->visibleItemCount;
390}
391
392void QQuickTumbler::setVisibleItemCount(int visibleItemCount)
393{
394 Q_D(QQuickTumbler);
395 if (visibleItemCount == d->visibleItemCount)
396 return;
397
398 d->visibleItemCount = visibleItemCount;
399 d->_q_updateItemHeights();
401}
402
404{
405 return new QQuickTumblerAttached(object);
406}
407
422{
423 Q_D(const QQuickTumbler);
424 return d->wrap;
425}
426
428{
429 Q_D(QQuickTumbler);
430 d->setWrap(wrap, true);
431}
432
434{
435 Q_D(QQuickTumbler);
436 d->explicitWrap = false;
437 d->setWrapBasedOnCount();
438}
439
448{
449 Q_D(const QQuickTumbler);
450 return d->view && d->view->property("moving").toBool();
451}
452
477void QQuickTumbler::positionViewAtIndex(int index, QQuickTumbler::PositionMode mode)
478{
479 Q_D(QQuickTumbler);
480 if (!d->view) {
481 d->warnAboutIncorrectContentItem();
482 return;
483 }
484
485 QMetaObject::invokeMethod(d->view, "positionViewAtIndex", Q_ARG(int, index), Q_ARG(int, mode));
486}
487
488void QQuickTumbler::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
489{
490 Q_D(QQuickTumbler);
491
492 QQuickControl::geometryChange(newGeometry, oldGeometry);
493
494 d->_q_updateItemHeights();
495
496 if (newGeometry.width() != oldGeometry.width())
497 d->_q_updateItemWidths();
498}
499
501{
502 Q_D(QQuickTumbler);
503 qCDebug(lcTumbler) << "componentComplete()";
505
506 if (!d->view) {
507 // Force the view to be created.
508 qCDebug(lcTumbler) << "emitting wrapChanged() to force view to be created";
509 emit wrapChanged();
510 // Determine the type of view for attached properties, etc.
511 d->setupViewData(d->contentItem);
512 }
513
514 // If there was no contentItem or it was of an unsupported type,
515 // we don't have anything else to do.
516 if (!d->view)
517 return;
518
519 // Update item heights after we've populated the model,
520 // otherwise ignoreSignals will cause these functions to return early.
521 d->_q_updateItemHeights();
522 d->_q_updateItemWidths();
523 d->_q_onViewCountChanged();
524
525 qCDebug(lcTumbler) << "componentComplete() is done";
526}
527
529{
530 Q_D(QQuickTumbler);
531
532 QQuickControl::contentItemChange(newItem, oldItem);
533
534 if (oldItem)
535 d->disconnectFromView();
536
537 if (newItem) {
538 // We wait until wrap is set to that we know which type of view to create.
539 // If we try to set up the view too early, we'll issue warnings about it not existing.
540 if (isComponentComplete()) {
541 // Make sure we use the new content item and not the current one, as that won't
542 // be changed until after contentItemChange() has finished.
543 d->setupViewData(newItem);
544
545 d->_q_updateItemHeights();
546 d->_q_updateItemWidths();
547 }
548 }
549}
550
552{
553 Q_Q(QQuickTumbler);
554 if (!view) {
555 // If a custom content item is declared, it can happen that
556 // the original contentItem exists without the view etc. having been
557 // determined yet, and then this is called when the custom content item
558 // is eventually set.
559 return;
560 }
561
563 QObject::disconnect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged()));
565 QObject::disconnect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged()));
566
569 else
571
572 QQuickItemPrivate *oldViewContentItemPrivate = QQuickItemPrivate::get(viewContentItem);
574
576}
577
579{
580 // Don't do anything if we've already set up.
581 if (view)
582 return;
583
584 determineViewType(newControlContentItem);
585
587 return;
588
591 return;
592 }
593
594 Q_Q(QQuickTumbler);
595 QObject::connect(view, SIGNAL(currentIndexChanged()), q, SLOT(_q_onViewCurrentIndexChanged()));
596 QObject::connect(view, SIGNAL(currentItemChanged()), q, SIGNAL(currentItemChanged()));
598 QObject::connect(view, SIGNAL(movingChanged()), q, SIGNAL(movingChanged()));
599
603 } else {
604 QObject::connect(view, SIGNAL(contentYChanged()), q, SLOT(_q_onViewContentYChanged()));
606 }
607
610
611 // Sync the view's currentIndex with ours.
613
615}
616
618{
619 Q_Q(QQuickTumbler);
620 qmlWarning(q) << "Tumbler: contentItem must contain either a PathView or a ListView";
621}
622
624{
625 const int actualViewIndex = view->property("currentIndex").toInt();
626 Q_Q(QQuickTumbler);
627
628 const bool isPendingCurrentIndex = pendingCurrentIndex != -1;
629 const int indexToSet = isPendingCurrentIndex ? pendingCurrentIndex : currentIndex;
630
631 // Nothing to do.
632 if (actualViewIndex == indexToSet) {
634 return;
635 }
636
637 // actualViewIndex might be 0 or -1 for PathView and ListView respectively,
638 // but we always use -1 for that.
639 if (q->count() == 0 && actualViewIndex <= 0)
640 return;
641
643 view->setProperty("currentIndex", QVariant(indexToSet));
645
646 if (view->property("currentIndex").toInt() == indexToSet)
648 else if (isPendingCurrentIndex)
649 q->polish();
650}
651
653{
654 qCDebug(lcTumbler) << "setting pendingCurrentIndex to" << index;
656}
657
660{
661 return changeReason == UserChange ? QStringLiteral("UserChange") : QStringLiteral("InternalChange");
662}
663
666{
667 Q_Q(QQuickTumbler);
668 qCDebug(lcTumbler).nospace() << "setting currentIndex to " << newCurrentIndex
669 << ", old currentIndex was " << currentIndex
670 << ", changeReason is " << propertyChangeReasonToString(changeReason);
671 if (newCurrentIndex == currentIndex || newCurrentIndex < -1)
672 return;
673
674 if (!q->isComponentComplete()) {
675 // Views can't set currentIndex until they're ready.
676 qCDebug(lcTumbler) << "we're not complete; setting pendingCurrentIndex instead";
677 setPendingCurrentIndex(newCurrentIndex);
678 return;
679 }
680
681 if (modelBeingSet && changeReason == UserChange) {
682 // If modelBeingSet is true and the user set the currentIndex,
683 // the model is in the process of being set and the user has set
684 // the currentIndex in onModelChanged. We have to queue the currentIndex
685 // change until we're ready.
686 qCDebug(lcTumbler) << "a model is being set; setting pendingCurrentIndex instead";
687 setPendingCurrentIndex(newCurrentIndex);
688 return;
689 }
690
691 // -1 doesn't make sense for a non-empty Tumbler, because unlike
692 // e.g. ListView, there's always one item selected.
693 // Wait until the component has finished before enforcing this rule, though,
694 // because the count might not be known yet.
695 if ((count > 0 && newCurrentIndex == -1) || (newCurrentIndex >= count)) {
696 return;
697 }
698
699 // The view might not have been created yet, as is the case
700 // if you create a Tumbler component and pass e.g. { currentIndex: 2 }
701 // to createObject().
702 if (view) {
703 // Only actually set our currentIndex if the view was able to set theirs.
704 bool couldSet = false;
705 if (count == 0 && newCurrentIndex == -1) {
706 // PathView insists on using 0 as the currentIndex when there are no items.
707 couldSet = true;
708 } else {
710 ignoreSignals = true;
711 view->setProperty("currentIndex", newCurrentIndex);
712 ignoreSignals = false;
714
715 couldSet = view->property("currentIndex").toInt() == newCurrentIndex;
716 }
717
718 if (couldSet) {
719 // The view's currentIndex might not have actually changed, but ours has,
720 // and that's what user code sees.
721 currentIndex = newCurrentIndex;
722 emit q->currentIndexChanged();
723 }
724
725 qCDebug(lcTumbler) << "view's currentIndex is now" << view->property("currentIndex").toInt()
726 << "and ours is" << currentIndex;
727 }
728}
729
731{
732 qCDebug(lcTumbler).nospace() << "setting count to " << newCount
733 << ", old count was " << count;
734 if (newCount == count)
735 return;
736
737 count = newCount;
738
739 Q_Q(QQuickTumbler);
741
742 emit q->countChanged();
743}
744
746{
747 if (count == 0 || explicitWrap || modelBeingSet)
748 return;
749
750 setWrap(count >= visibleItemCount, false);
751}
752
753void QQuickTumblerPrivate::setWrap(bool shouldWrap, bool isExplicit)
754{
755 qCDebug(lcTumbler) << "setting wrap to" << shouldWrap << "- explicit?" << isExplicit;
756 if (isExplicit)
757 explicitWrap = true;
758
759 Q_Q(QQuickTumbler);
760 if (q->isComponentComplete() && shouldWrap == wrap)
761 return;
762
763 // Since we use the currentIndex of the contentItem directly, we must
764 // ensure that we keep track of the currentIndex so it doesn't get lost
765 // between view changes.
766 const int oldCurrentIndex = currentIndex;
767
769
770 wrap = shouldWrap;
771
772 // New views will set their currentIndex upon creation, which we'd otherwise
773 // take as the correct one, so we must ignore them.
775
776 // This will cause the view to be created if our contentItem is a TumblerView.
777 emit q->wrapChanged();
778
780
781 // If isComponentComplete() is true, we require a contentItem. If it's not
782 // true, it might not have been created yet, so we wait until
783 // componentComplete() is called.
784 //
785 // When the contentItem (usually QQuickTumblerView) has been created, we
786 // can start determining its type, etc. If the delegates use attached
787 // properties, this will have already been called, in which case it will
788 // return early. If the delegate doesn't use attached properties, we need
789 // to call it here.
790 if (q->isComponentComplete() || contentItem)
792
793 setCurrentIndex(oldCurrentIndex);
794}
795
797{
798 modelBeingSet = true;
799}
800
802{
803 modelBeingSet = false;
805}
806
808{
810
811 Q_D(QQuickTumbler);
812 if (event->isAutoRepeat() || !d->view)
813 return;
814
815 if (event->key() == Qt::Key_Up) {
816 QMetaObject::invokeMethod(d->view, "decrementCurrentIndex");
817 } else if (event->key() == Qt::Key_Down) {
818 QMetaObject::invokeMethod(d->view, "incrementCurrentIndex");
819 }
820}
821
823{
824 Q_D(QQuickTumbler);
825 if (d->pendingCurrentIndex != -1) {
826 // Update our count, as ignoreSignals might have been true
827 // when _q_onViewCountChanged() was last called.
828 d->setCount(d->view->property("count").toInt());
829
830 // If the count is still 0, it's not going to happen.
831 if (d->count == 0) {
832 d->setPendingCurrentIndex(-1);
833 return;
834 }
835
836 // If there is a pending currentIndex at this stage, it means that
837 // the view wouldn't set our currentIndex in _q_onViewCountChanged
838 // because it wasn't ready. Try one last time here.
839 d->setCurrentIndex(d->pendingCurrentIndex);
840
841 if (d->currentIndex != d->pendingCurrentIndex && d->currentIndex == -1) {
842 // If we *still* couldn't set it, it's probably invalid.
843 // See if we can at least enforce our rule of "non-negative currentIndex when count > 0" instead.
844 d->setCurrentIndex(0);
845 }
846
847 d->setPendingCurrentIndex(-1);
848 }
849}
850
852{
854}
855
857{
859 if (!delegateItem->parentItem()) {
860 qmlWarning(q) << "Tumbler: attached properties must be accessed through a delegate item that has a parent";
861 return;
862 }
863
864 QVariant indexContextProperty = qmlContext(delegateItem)->contextProperty(QStringLiteral("index"));
865 if (!indexContextProperty.isValid()) {
866 qmlWarning(q) << "Tumbler: attempting to access attached property on item without an \"index\" property";
867 return;
868 }
869
870 index = indexContextProperty.toInt();
871
872 QQuickItem *parentItem = delegateItem;
873 while ((parentItem = parentItem->parentItem())) {
874 if ((tumbler = qobject_cast<QQuickTumbler*>(parentItem)))
875 break;
876 }
877}
878
880{
881 const qreal previousDisplacement = displacement;
882 displacement = 0;
883
884 if (!tumbler) {
885 // Can happen if the attached properties are accessed on the wrong type of item or the tumbler was destroyed.
886 // We don't want to emit the change signal though, as this could cause warnings about Tumbler.tumbler being null.
887 return;
888 }
889
890 // Can happen if there is no ListView or PathView within the contentItem.
892 if (!tumblerPrivate->viewContentItem) {
893 emitIfDisplacementChanged(previousDisplacement, displacement);
894 return;
895 }
896
897 // The attached property gets created before our count is updated, so just cheat here
898 // to avoid having to listen to count changes.
899 const int count = tumblerPrivate->view->property("count").toInt();
900 // This can happen in tests, so it may happen in normal usage too.
901 if (count == 0) {
902 emitIfDisplacementChanged(previousDisplacement, displacement);
903 return;
904 }
905
907 const qreal offset = tumblerPrivate->viewOffset;
908
909 displacement = count > 1 ? count - index - offset : 0;
910 // Don't add 1 if count <= visibleItemCount
911 const int visibleItems = tumbler->visibleItemCount();
912 const int halfVisibleItems = visibleItems / 2 + (visibleItems < count ? 1 : 0);
913 if (displacement > halfVisibleItems)
915 else if (displacement < -halfVisibleItems)
917 } else {
918 const qreal contentY = tumblerPrivate->viewContentY;
919 const qreal delegateH = delegateHeight(tumbler);
920 const qreal preferredHighlightBegin = tumblerPrivate->view->property("preferredHighlightBegin").toReal();
921 const qreal itemY = qobject_cast<QQuickItem*>(parent)->y();
922 qreal currentItemY = 0;
923 auto currentItem = tumblerPrivate->view->property("currentItem").value<QQuickItem*>();
924 if (currentItem)
925 currentItemY = currentItem->y();
926 // Start from the y position of the current item.
927 const qreal topOfCurrentItemInViewport = currentItemY - contentY;
928 // Then, calculate the distance between it and the preferredHighlightBegin.
929 const qreal relativePositionToPreferredHighlightBegin = topOfCurrentItemInViewport - preferredHighlightBegin;
930 // Next, calculate the distance between us and the current item.
931 const qreal distanceFromCurrentItem = currentItemY - itemY;
932 const qreal displacementInPixels = distanceFromCurrentItem - relativePositionToPreferredHighlightBegin;
933 // Convert it from pixels to a floating point index.
934 displacement = displacementInPixels / delegateH;
935 }
936
937 emitIfDisplacementChanged(previousDisplacement, displacement);
938}
939
941{
943 if (newDisplacement != oldDisplacement)
944 emit q->displacementChanged();
945}
946
949{
952 if (delegateItem)
953 d->init(delegateItem);
954 else if (parent)
955 qmlWarning(parent) << "Tumbler: attached properties of Tumbler must be accessed through a delegate item";
956
957 if (d->tumbler) {
958 // When the Tumbler is completed, wrapChanged() is emitted to let QQuickTumblerView
959 // know that it can create the view. The view itself might instantiate delegates
960 // that use attached properties. At this point, setupViewData() hasn't been called yet
961 // (it's called on the next line in componentComplete()), so we call it here so that
962 // we have access to the view.
963 QQuickTumblerPrivate *tumblerPrivate = QQuickTumblerPrivate::get(d->tumbler);
964 tumblerPrivate->setupViewData(tumblerPrivate->contentItem);
965
966 if (delegateItem && delegateItem->parentItem() == tumblerPrivate->viewContentItem) {
967 // This item belongs to the "new" view, meaning that the tumbler's contentItem
968 // was probably assigned declaratively. If they're not equal, calling
969 // calculateDisplacement() would use the old contentItem data, which is bad.
970 d->calculateDisplacement();
971 }
972 }
973}
974
983{
984 Q_D(const QQuickTumblerAttached);
985 return d->tumbler;
986}
987
1007{
1008 Q_D(const QQuickTumblerAttached);
1009 return d->displacement;
1010}
1011
1013
1014#include "moc_qquicktumbler_p.cpp"
\reentrant
Definition qfont.h:20
The QKeyEvent class describes a key event.
Definition qevent.h:423
Definition qlist.h:74
QObject * parent
Definition qobject.h:61
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3099
QVariant property(const char *name) const
Returns the value of the object's name property.
Definition qobject.cpp:4187
bool setProperty(const char *name, const QVariant &value)
Sets the value of the object's name property to value.
bool inherits(const char *classname) const
Returns true if this object is an instance of a class that inherits className or a QObject subclass t...
Definition qobject.h:313
The QPalette class contains color groups for each widget state.
Definition qpalette.h:19
The QQmlComponent class encapsulates a QML component definition.
QVariant contextProperty(const QString &) const
Returns the value of the name property for this context as a QVariant.
void itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) override
QQuickDeferredPointer< QQuickItem > contentItem
virtual void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void topPaddingChanged()
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
void rightPaddingChanged()
void bottomPaddingChanged()
void leftPaddingChanged()
void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types)
void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
static QQuickItemPrivate * get(QQuickItem *item)
QList< QQuickItem * > childItems
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
QList< QQuickItem * > childItems() const
Returns the children of this item.
virtual void keyPressEvent(QKeyEvent *event)
This event handler can be reimplemented in a subclass to receive key press events for an item.
qreal y
Defines the item's y position relative to its parent.
Definition qquickitem.h:74
QQuickItem * parentItem() const
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
void setActiveFocusOnTab(bool)
static QPalette palette(Scope scope)
static QFont font(Scope scope)
static QQuickTumblerAttachedPrivate * get(QQuickTumblerAttached *attached)
void emitIfDisplacementChanged(qreal oldDisplacement, qreal newDisplacement)
void init(QQuickItem *delegateItem)
QPointer< QQuickTumbler > tumbler
QQuickTumbler * tumbler
QQuickTumblerAttached(QObject *parent=nullptr)
ContentItemType viewContentItemType
void itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &) override
void setCurrentIndex(int newCurrentIndex, PropertyChangeReason changeReason=InternalChange)
QQuickItem * determineViewType(QQuickItem *contentItem)
void itemChildAdded(QQuickItem *, QQuickItem *) override
void setCount(int newCount)
static QQuickTumblerPrivate * get(QQuickTumbler *tumbler)
void itemChildRemoved(QQuickItem *, QQuickItem *) override
QList< QQuickItem * > viewContentItemChildItems() const
void setPendingCurrentIndex(int index)
void setupViewData(QQuickItem *newControlContentItem)
void setWrap(bool shouldWrap, bool isExplicit)
QPalette defaultPalette() const override
static QString propertyChangeReasonToString(PropertyChangeReason changeReason)
QQuickItem * currentItem
void setWrap(bool wrap)
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
void updatePolish() override
This function should perform any layout as required for this item.
void delegateChanged()
QQmlComponent * delegate
void modelChanged()
void keyPressEvent(QKeyEvent *event) override
This event handler can be reimplemented in a subclass to receive key press events for an item.
QFont defaultFont() const override
void setCurrentIndex(int currentIndex)
QQuickTumbler(QQuickItem *parent=nullptr)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void visibleItemCountChanged()
void setDelegate(QQmlComponent *delegate)
void setModel(const QVariant &model)
void contentItemChange(QQuickItem *newItem, QQuickItem *oldItem) override
void setVisibleItemCount(int visibleItemCount)
static QQuickTumblerAttached * qmlAttachedProperties(QObject *object)
bool isMoving() const
\qmlproperty bool QtQuick.Controls::Tumbler::moving
\inmodule QtCore\reentrant
Definition qrect.h:483
constexpr qreal width() const noexcept
Returns the width of the rectangle.
Definition qrect.h:715
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
\inmodule QtCore
Definition qvariant.h:64
T value() const &
Definition qvariant.h:511
qreal toReal(bool *ok=nullptr) const
Returns the variant as a qreal if the variant has userType() \l QMetaType::Double,...
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:707
int toInt(bool *ok=nullptr) const
Returns the variant as an int if the variant has userType() \l QMetaType::Int, \l QMetaType::Bool,...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
Combined button and popup list for selecting options.
static qreal delegateHeight(const QQuickTumbler *tumbler)
@ Key_Up
Definition qnamespace.h:673
@ Key_Down
Definition qnamespace.h:675
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define SLOT(a)
Definition qobjectdefs.h:51
#define Q_ARG(Type, data)
Definition qobjectdefs.h:62
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLenum mode
GLuint index
[2]
GLenum GLenum GLsizei count
GLenum GLuint GLintptr offset
struct _cl_event * event
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:71
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:483
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
#define QStringLiteral(str)
#define emit
double qreal
Definition qtypes.h:92
QSqlQueryModel * model
[16]
QGraphicsItem * item
QList< QTreeWidgetItem * > items
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent