diff options
author | Jan Arve Saether <jan-arve.saether@digia.com> | 2013-08-30 19:05:59 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-11 14:27:14 +0200 |
commit | f408e7307db102c7e030b15d66462778c9fe3f3f (patch) | |
tree | f9ca5455d38fffeda59121f59da5bf8207f8a405 /src/layouts | |
parent | 782161178529e6f112568481383b7766652c859c (diff) |
Reduce chaos during deconstruction
When a layout is destroyed, it will during its destruction unparent its
children and possibly change their visibility. The visibility change
will recurse down to all descendants.
Because of these slots, this information will again be communicated up
to the layout, which again might cause the layout to adjust to this new
change _while_it_is_deconstructing_. This makes it chaotic, is a waste
of resources and makes it harder to maintain, and could in worst case
cause crashes.
Change-Id: I6b3111b8ecc4ec4312dd36068b4b4b4e6529b9ef
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Diffstat (limited to 'src/layouts')
-rw-r--r-- | src/layouts/qquicklayout_p.h | 5 | ||||
-rw-r--r-- | src/layouts/qquicklinearlayout.cpp | 24 | ||||
-rw-r--r-- | src/layouts/qquicklinearlayout_p.h | 3 |
3 files changed, 32 insertions, 0 deletions
diff --git a/src/layouts/qquicklayout_p.h b/src/layouts/qquicklayout_p.h index 13b034469..ecb97c465 100644 --- a/src/layouts/qquicklayout_p.h +++ b/src/layouts/qquicklayout_p.h @@ -78,6 +78,11 @@ public: virtual QSizeF sizeHint(Qt::SizeHint whichSizeHint) const = 0; virtual void invalidate(QQuickItem * childItem = 0); virtual void updateLayoutItems() = 0; + + // iterator + virtual QQuickItem *itemAt(int index) const = 0; + virtual int itemCount() const = 0; + virtual void rearrange(const QSizeF &); bool arrangementIsDirty() const { return m_dirty; } protected: diff --git a/src/layouts/qquicklinearlayout.cpp b/src/layouts/qquicklinearlayout.cpp index f619177a3..7639d337d 100644 --- a/src/layouts/qquicklinearlayout.cpp +++ b/src/layouts/qquicklinearlayout.cpp @@ -256,6 +256,18 @@ Qt::LayoutDirection QQuickGridLayoutBase::effectiveLayoutDirection() const QQuickGridLayoutBase::~QQuickGridLayoutBase() { d_func()->m_isReady = false; + + /* Avoid messy deconstruction, should give: + * Faster deconstruction + * Less risk of signals reaching already deleted objects + */ + for (int i = 0; i < itemCount(); ++i) { + QQuickItem *item = itemAt(i); + QObject::disconnect(item, SIGNAL(destroyed()), this, SLOT(onItemDestroyed())); + QObject::disconnect(item, SIGNAL(visibleChanged()), this, SLOT(onItemVisibleChanged())); + QObject::disconnect(item, SIGNAL(implicitWidthChanged()), this, SLOT(onItemImplicitSizeChanged())); + QObject::disconnect(item, SIGNAL(implicitHeightChanged()), this, SLOT(onItemImplicitSizeChanged())); + } } void QQuickGridLayoutBase::componentComplete() @@ -359,6 +371,18 @@ void QQuickGridLayoutBase::updateLayoutItems() quickLayoutDebug() << "QQuickGridLayoutBase::updateLayoutItems LEAVING"; } +QQuickItem *QQuickGridLayoutBase::itemAt(int index) const +{ + Q_D(const QQuickGridLayoutBase); + return static_cast<QQuickGridLayoutItem*>(d->engine.itemAt(index))->layoutItem(); +} + +int QQuickGridLayoutBase::itemCount() const +{ + Q_D(const QQuickGridLayoutBase); + return d->engine.itemCount(); +} + void QQuickGridLayoutBase::itemChange(ItemChange change, const ItemChangeData &value) { if (change == ItemChildAddedChange) { diff --git a/src/layouts/qquicklinearlayout_p.h b/src/layouts/qquicklinearlayout_p.h index ef0dfd859..ed8bf8f96 100644 --- a/src/layouts/qquicklinearlayout_p.h +++ b/src/layouts/qquicklinearlayout_p.h @@ -78,6 +78,9 @@ public: protected: void updateLayoutItems() Q_DECL_OVERRIDE; + QQuickItem *itemAt(int index) const Q_DECL_OVERRIDE; + int itemCount() const Q_DECL_OVERRIDE; + void rearrange(const QSizeF &size); virtual void insertLayoutItems() = 0; void removeLayoutItem(QQuickItem *item); |