From 352c8ef1997542de2d471a8d929442529b876263 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 26 Jun 2019 14:09:25 +0200 Subject: QMetaObject::connectSlotsByName(): Add output of connections Help porting connections over by printing the connection statements. [ChangeLog][QtCore][QObject] A logging category qt.core.qmetaobject.connectslotsbyname was added, which will produce about the connections made by QMetaObject::connectSlotsByName(). Task-number: QTBUG-76375 Change-Id: I9a57cae574156fc8ae5a4fb8e960c2f9a47a5e47 Reviewed-by: Volker Hilsheimer --- src/corelib/kernel/qobject.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index a8e2c43934..8be10ed601 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -47,6 +47,7 @@ #include "qabstracteventdispatcher_p.h" #include "qcoreapplication.h" #include "qcoreapplication_p.h" +#include "qloggingcategory.h" #include "qvariant.h" #include "qmetaobject.h" #include @@ -78,6 +79,8 @@ QT_BEGIN_NAMESPACE static int DIRECT_CONNECTION_ONLY = 0; +Q_LOGGING_CATEGORY(lcConnections, "qt.core.qmetaobject.connectslotsbyname") + Q_CORE_EXPORT QBasicAtomicPointer qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr); void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set) @@ -3559,6 +3562,37 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender, return success; } +// Helpers for formatting the connect statements of connectSlotsByName()'s debug mode +static QByteArray formatConnectionSignature(const char *className, const QMetaMethod &method) +{ + const auto signature = method.methodSignature(); + Q_ASSERT(signature.endsWith(')')); + const int openParen = signature.indexOf('('); + const bool hasParameters = openParen >= 0 && openParen < signature.size() - 2; + QByteArray result; + if (hasParameters) { + result += "qOverload<" + + signature.mid(openParen + 1, signature.size() - openParen - 2) + ">("; + } + result += '&'; + result += className + QByteArrayLiteral("::") + method.name(); + if (hasParameters) + result += ')'; + return result; +} + +static QByteArray msgConnect(const QMetaObject *senderMo, const QByteArray &senderName, + const QMetaMethod &signal, const QObject *receiver, int receiverIndex) +{ + const auto receiverMo = receiver->metaObject(); + const auto slot = receiverMo->method(receiverIndex); + QByteArray message = QByteArrayLiteral("QObject::connect(") + + senderName + ", " + formatConnectionSignature(senderMo->className(), signal) + + ", " + receiver->objectName().toLatin1() + ", " + + formatConnectionSignature(receiverMo->className(), slot) + ");"; + return message; +} + /*! \fn void QMetaObject::connectSlotsByName(QObject *object) @@ -3640,6 +3674,8 @@ void QMetaObject::connectSlotsByName(QObject *o) // we connect it... if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) { foundIt = true; + qCDebug(lcConnections, "%s", + msgConnect(smeta, coName, QMetaObjectPrivate::signal(smeta, sigIndex), o, i).constData()); // ...and stop looking for further objects with the same name. // Note: the Designer will make sure each object name is unique in the above // 'list' but other code may create two child objects with the same name. In -- cgit v1.2.3