aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates2/qquickcontrol.cpp
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2017-05-18 21:37:09 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2017-05-19 10:39:06 +0000
commit1eaebd0c3b7b21bb7483df9bbfe391823ecdc181 (patch)
tree9ba8e6bacc0209f282e40666f067fbae2de51ca3 /src/quicktemplates2/qquickcontrol.cpp
parentf0a906cdfa7c02826592ed7f7faa1634686a331c (diff)
ScrollView: fix default Flickable content item creation
Short version: do not emit contentItemChanged() while contentItem() is being called to avoid binding loops. Long version: ScrollView is a thin wrapper around Flickable, and when necessary, instantiates a Flickable behind the scenes. However, ScrollView cannot instantiate one unconditionally, because it has to work with existing Flickables, such as ListView and GridView, too. ScrollView { Item { } } // creates a Flickable ScrollView { Flickable { } } // does not create a Flickable ScrollView { contentItem: Flickable { } } // does not create a Flickable When a Flickable is created behind the scenes, it is assigned as the contentItem of the ScrollView. However, when the Flickable is created lazily as a result of ScrollView::contentItem being accessed, it must NOT emit contentItemChanged() while the contentItem() getter is being called, because that results to a binding loop. This problem was exposed by the recent attempts to enable QML caching at build time (QTBUG-58571). Change-Id: I712f2f30da454a6c22a722afe8a00ae240733571 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quicktemplates2/qquickcontrol.cpp')
-rw-r--r--src/quicktemplates2/qquickcontrol.cpp39
1 files changed, 25 insertions, 14 deletions
diff --git a/src/quicktemplates2/qquickcontrol.cpp b/src/quicktemplates2/qquickcontrol.cpp
index c039253d..a2b16a10 100644
--- a/src/quicktemplates2/qquickcontrol.cpp
+++ b/src/quicktemplates2/qquickcontrol.cpp
@@ -281,6 +281,27 @@ QQuickItem *QQuickControlPrivate::getContentItem()
return contentItem;
}
+void QQuickControlPrivate::setContentItem_helper(QQuickItem *item, bool notify)
+{
+ Q_Q(QQuickControl);
+ if (contentItem == item)
+ return;
+
+ q->contentItemChange(item, contentItem);
+ destroyDelegate(contentItem, q);
+ contentItem = item;
+
+ if (item) {
+ if (!item->parentItem())
+ item->setParentItem(q);
+ if (componentComplete)
+ resizeContent();
+ }
+
+ if (notify)
+ emit q->contentItemChanged();
+}
+
#if QT_CONFIG(accessibility)
void QQuickControlPrivate::accessibilityActiveChanged(bool active)
{
@@ -1243,25 +1264,15 @@ void QQuickControl::setBackground(QQuickItem *background)
QQuickItem *QQuickControl::contentItem() const
{
QQuickControlPrivate *d = const_cast<QQuickControlPrivate *>(d_func());
- return d->getContentItem();
+ if (!d->contentItem)
+ d->setContentItem_helper(d->getContentItem(), false);
+ return d->contentItem;
}
void QQuickControl::setContentItem(QQuickItem *item)
{
Q_D(QQuickControl);
- if (d->contentItem == item)
- return;
-
- contentItemChange(item, d->contentItem);
- QQuickControlPrivate::destroyDelegate(d->contentItem, this);
- d->contentItem = item;
- if (item) {
- if (!item->parentItem())
- item->setParentItem(this);
- if (isComponentComplete())
- d->resizeContent();
- }
- emit contentItemChanged();
+ d->setContentItem_helper(item, true);
}
void QQuickControl::classBegin()