From 598a9054be59466419f611df0b19702c41818db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Arve=20S=C3=A6ther?= Date: Thu, 16 Apr 2020 10:59:27 +0200 Subject: Add _q_dumpLayoutTree() for debugging purposes I found this quite useful for debugging layouts in order to get a snapshot of the layout hierarchy at any point. It will show the hierarchy and the relevant properties that affect the layouting. It's basically QObject::dumpObjectTree() specialized for Qt Quick Layouts (except it will dump it as QML-ish). For the leaf nodes it will leave out unspecified information. Example on how a dump looks like: RowLayout { // Effective calculated values: sizeHintDirty: 1 sizeHint.min : [ 100, 20] sizeHint.pref: [ 100, 20] sizeHint.max : [ inf, 20] RowLayout { // Effective calculated values: sizeHintDirty: 1 sizeHint.min : [ 100, 20] sizeHint.pref: [ 100, 20] sizeHint.max : [ inf, 20] Rectangle { implicitWidth: 100 implicitHeight: 20 } Rectangle { implicitHeight: 20 Layout.fillWidth: true } } } Change-Id: Ie2fcd56d522395cb9d6f55a1ea3f882a7a9da709 Reviewed-by: Fabian Kosmale Reviewed-by: Mitch Curtis (cherry picked from commit e0a03d04f8880d81e0c1fec909e5892ae685af71) --- src/imports/layouts/qquicklayout.cpp | 76 ++++++++++++++++++++++++++++++++++++ src/imports/layouts/qquicklayout_p.h | 3 ++ 2 files changed, 79 insertions(+) (limited to 'src/imports') diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp index 8d9a6b0165..43c39290c3 100644 --- a/src/imports/layouts/qquicklayout.cpp +++ b/src/imports/layouts/qquicklayout.cpp @@ -1163,6 +1163,82 @@ QLayoutPolicy::Policy QQuickLayout::effectiveSizePolicy_helper(QQuickItem *item, } +void QQuickLayout::_q_dumpLayoutTree() const +{ + QString buf; + dumpLayoutTreeRecursive(0, buf); + qDebug("\n%s", qPrintable(buf)); +} +void QQuickLayout::dumpLayoutTreeRecursive(int level, QString &buf) const +{ + auto formatLine = [&level](const char *fmt) { + QString ss(level *4, QLatin1Char(' ')); + return QString::fromLatin1("%1%2\n").arg(ss).arg(fmt); + }; + + auto f2s = [](qreal f) { + return QString::number(f); + }; + auto b2s = [](bool b) { + static const char *strBool[] = {"false", "true"}; + return QLatin1String(strBool[int(b)]); + }; + + buf += formatLine("%1 {").arg(QQmlMetaType::prettyTypeName(this)); + ++level; + buf += formatLine("// Effective calculated values:"); + buf += formatLine("sizeHintDirty: %2").arg(m_dirty); + QSizeF min = sizeHint(Qt::MinimumSize); + buf += formatLine("sizeHint.min : [%1, %2]").arg(f2s(min.width()), 5).arg(min.height(), 5); + QSizeF pref = sizeHint(Qt::PreferredSize); + buf += formatLine("sizeHint.pref: [%1, %2]").arg(pref.width(), 5).arg(pref.height(), 5); + QSizeF max = sizeHint(Qt::MaximumSize); + buf += formatLine("sizeHint.max : [%1, %2]").arg(f2s(max.width()), 5).arg(f2s(max.height()), 5); + + for (QQuickItem *item : childItems()) { + buf += QLatin1Char('\n'); + if (QQuickLayout *childLayout = qobject_cast(item)) { + childLayout->dumpLayoutTreeRecursive(level, buf); + } else { + buf += formatLine("%1 {").arg(QQmlMetaType::prettyTypeName(item)); + ++level; + if (item->implicitWidth() > 0) + buf += formatLine("implicitWidth: %1").arg(f2s(item->implicitWidth())); + if (item->implicitHeight() > 0) + buf += formatLine("implicitHeight: %1").arg(f2s(item->implicitHeight())); + QSizeF min; + QSizeF pref; + QSizeF max; + QQuickLayoutAttached *info = attachedLayoutObject(item, false); + if (info) { + min = QSizeF(info->minimumWidth(), info->minimumHeight()); + pref = QSizeF(info->preferredWidth(), info->preferredHeight()); + max = QSizeF(info->maximumWidth(), info->maximumHeight()); + if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MinimumSize)) + buf += formatLine("Layout.minimumWidth: %1").arg(f2s(min.width())); + if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MinimumSize)) + buf += formatLine("Layout.minimumHeight: %1").arg(f2s(min.height())); + if (pref.width() >= 0) + buf += formatLine("Layout.preferredWidth: %1").arg(f2s(pref.width())); + if (pref.height() >= 0) + buf += formatLine("Layout.preferredHeight: %1").arg(f2s(pref.height())); + if (info->isExtentExplicitlySet(Qt::Horizontal, Qt::MaximumSize)) + buf += formatLine("Layout.maximumWidth: %1").arg(f2s(max.width())); + if (info->isExtentExplicitlySet(Qt::Vertical, Qt::MaximumSize)) + buf += formatLine("Layout.maximumHeight: %1").arg(f2s(max.height())); + + if (info->isFillWidthSet()) + buf += formatLine("Layout.fillWidth: %1").arg(b2s(info->fillWidth())); + if (info->isFillHeightSet()) + buf += formatLine("Layout.fillHeight: %1").arg(b2s(info->fillHeight())); + } + --level; + buf += formatLine("}"); + } + } + --level; + buf += formatLine("}"); +} QT_END_NAMESPACE diff --git a/src/imports/layouts/qquicklayout_p.h b/src/imports/layouts/qquicklayout_p.h index 5fa16b7b5b..52442b68a0 100644 --- a/src/imports/layouts/qquicklayout_p.h +++ b/src/imports/layouts/qquicklayout_p.h @@ -105,6 +105,9 @@ public: void itemDestroyed(QQuickItem *item) override; void itemVisibilityChanged(QQuickItem *item) override; + Q_INVOKABLE void _q_dumpLayoutTree() const; + void dumpLayoutTreeRecursive(int level, QString &buf) const; + protected: void updatePolish() override; -- cgit v1.2.3