QObject: give some TLC to dumpRecursive()

In no particular order:

- use the variable field width feature of QString::asprintf() to
  generate the indentation implicitly, instead of fill()ing a
  QByteArray with the desired number of spaces

- just default-construct 'flags', don't assign an empty string

- use qUtf16Printable() to avoid funneling UTF-16 data through 8-bit
  encodings

- use a C++11 ranged for instead of a counted loop

- remove a pointless isEmpty() guard (the loop won't execute when the
  children().isEmpty())

- avoid copying object->children() (returns by cref, so it's also ok
  to stuff it directly into the ranged for loop).

Add a test.

Pick-to: 6.3
Change-Id: Ie7314713cb48de7e890cdee0760c0361dd24fd18
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2022-03-14 15:13:53 +01:00
parent 78891e5390
commit e74e27e67e
2 changed files with 34 additions and 13 deletions

View File

@ -4205,12 +4205,9 @@ QList<QByteArray> QObject::dynamicPropertyNames() const
static void dumpRecursive(int level, const QObject *object)
{
if (object) {
QByteArray buf;
buf.fill(' ', level / 2 * 8);
if (level % 2)
buf += " ";
QString name = object->objectName();
QString flags = QLatin1String("");
const int indent = level * 4;
const QString name = object->objectName();
QString flags;
#if 0
if (qApp->focusWidget() == object)
flags += 'F';
@ -4224,13 +4221,10 @@ static void dumpRecursive(int level, const QObject *object)
}
}
#endif
qDebug("%s%s::%s %s", (const char*)buf, object->metaObject()->className(), name.toLocal8Bit().data(),
flags.toLatin1().data());
QObjectList children = object->children();
if (!children.isEmpty()) {
for (int i = 0; i < children.size(); ++i)
dumpRecursive(level+1, children.at(i));
}
qDebug("%*s%s::%ls %ls", indent, "", object->metaObject()->className(),
qUtf16Printable(name), qUtf16Printable(flags));
for (auto child : object->children())
dumpRecursive(level + 1, child);
}
}

View File

@ -108,6 +108,7 @@ private slots:
void deleteSelfInSlot();
void disconnectSelfInSlotAndDeleteAfterEmit();
void dumpObjectInfo();
void dumpObjectTree();
void connectToSender();
void qobjectConstCast();
void uniqConnection();
@ -3413,6 +3414,32 @@ void tst_QObject::dumpObjectInfo()
a.dumpObjectInfo(); // should not crash
}
void tst_QObject::dumpObjectTree()
{
QObject a;
Q_SET_OBJECT_NAME(a);
QTimer b(&a);
Q_SET_OBJECT_NAME(b);
QObject c(&b);
Q_SET_OBJECT_NAME(c);
QFile f(&a);
Q_SET_OBJECT_NAME(f);
const char * const output[] = {
"QObject::a ",
" QTimer::b ",
" QObject::c ",
" QFile::f ",
};
for (const char *line : output)
QTest::ignoreMessage(QtDebugMsg, line);
a.dumpObjectTree();
}
class ConnectToSender : public QObject
{ Q_OBJECT
public slots: