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 <volker.hilsheimer@qt.io>
This commit is contained in:
Friedemann Kleint 2019-06-26 14:09:25 +02:00
parent f9781514d5
commit 352c8ef199

View File

@ -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 <qregexp.h>
@ -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<QSignalSpyCallbackSet> 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