summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.cpp
diff options
context:
space:
mode:
authorPierre-Yves Siret <gr3cko@gmail.com>2024-11-02 03:45:31 +0100
committerPierre-Yves Siret <gr3cko@gmail.com>2025-02-14 01:51:47 +0100
commitd8b4eb1a1756ecfedcdd45511cc7f084f12379ad (patch)
tree199052940f32e3a5a83cf88d1bda1cd521817e4f /src/corelib/kernel/qobject.cpp
parentaad0ab897f61bcb6ac9ba908afd1ee33e05fe4db (diff)
Add a QMetaObject::connect function
This adds a QMetaObject::connect function allowing to connect a QMetaMethod to a PMF or a functor. This is most useful when connecting a signal retrieved by QMetaObject introspection to a lambda with a capture. This aims to replace the remaining usecases of QSignalMapper with a lighter alternative not relying on sender()/senderSignalIndex(). Note that this function doesn't support implicit conversion between argument or return types. It does support lambda with captures and signals returning values. [ChangeLog][QtCore][QMetaObject] Added a QMetaObject::connect function for connecting a signal's QMetaMethod to a member function or a functor (lambdas, etc.) Fixes: QTBUG-120631 Change-Id: Ifca73cd047478f6a262728493b16a942bff36e40 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r--src/corelib/kernel/qobject.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e2446c83d26..48baa96e104 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -3911,6 +3911,96 @@ void QMetaObject::connectSlotsByName(QObject *o)
}
/*!
+ \fn template<typename PointerToMemberFunction> QMetaObject::Connection QMetaObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type)
+
+ \threadsafe
+ \overload connect()
+
+ \since 6.10
+
+ Creates a connection of the given \a type from the \a signal in
+ the \a sender object to the \a method in the \a receiver object.
+ Returns a handle to the connection that can be used to disconnect
+ it later.
+
+ The Connection handle will be invalid if it cannot create the
+ connection, for example, the parameters were invalid.
+ You can check if the QMetaObject::Connection is valid by casting
+ it to a bool.
+ Pass the returned handle to QObject::disconnect() to disconnect
+ the connection.
+
+ A slot can be connected to a given signal if the signal has at
+ least as many arguments as the slot. There must be an exact match
+ between the corresponding signal and slot arguments, implicit
+ conversions and type checking are not handled by this function.
+ Overloaded slots need to be explicitly be resolved with
+ help of \l qOverload.
+
+ \sa QObject::connect(), QObject::disconnect()
+ */
+
+/*!
+ \fn template<typename Functor> QMetaObject::Connection QMetaObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *context, Functor functor, Qt::ConnectionType type)
+
+ \threadsafe
+ \overload connect()
+
+ \since 6.10
+
+ Creates a connection of a given \a type from \a signal in
+ \a sender object to \a functor to be placed in a specific event
+ loop of \a context.
+ Returns a handle to the connection that can be used to disconnect
+ it later.
+ This can be useful for connecting a signal retrieved from
+ meta-object introspection to a lambda capturing local variables.
+
+ \note Qt::UniqueConnections do not work for lambdas, non-member
+ functions and functors; they only apply to member functions.
+
+ The slot function can be any function or functor with with equal
+ or fewer arguments than the signal. There must be an exact match
+ between the corresponding signal and slot arguments, implicit
+ conversions and type checking are not handled by this function.
+ Overloaded functors need to be explicitly be resolved with
+ help of \l qOverload.
+
+ The connection will automatically disconnect if the sender or
+ the context is destroyed.
+ However, you should take care that any objects used within
+ the functor are still alive when the signal is emitted.
+
+ \sa QObject::connect(), QObject::disconnect()
+ */
+QMetaObject::Connection QMetaObject::connectImpl(const QObject *sender, const QMetaMethod &signal,
+ const QObject *receiver, void **slot,
+ QtPrivate::QSlotObjectBase *slotObjRaw, Qt::ConnectionType type)
+{
+ QtPrivate::SlotObjUniquePtr slotObj(slotObjRaw);
+
+ if (!signal.isValid() || signal.methodType() != QMetaMethod::Signal) {
+ qCWarning(lcConnect, "QObject::connect: invalid signal parameter");
+ return QMetaObject::Connection();
+ }
+
+ int signal_index;
+ {
+ int dummy;
+ QMetaObjectPrivate::memberIndexes(sender, signal, &signal_index, &dummy);
+ }
+
+ const QMetaObject *senderMetaObject = sender->metaObject();
+ if (signal_index == -1) {
+ qCWarning(lcConnect, "QObject::connect: Can't find signal %s on instance of class %s",
+ signal.methodSignature().constData(), senderMetaObject->className());
+ return QMetaObject::Connection();
+ }
+
+ return QObjectPrivate::connectImpl(sender, signal_index, receiver, slot, slotObj.release(), type, nullptr, senderMetaObject);
+}
+
+/*!
\internal
A small RAII helper for QSlotObjectBase.
Calls ref on construction and destroyLastRef in its dtor.