diff options
| author | Pierre-Yves Siret <gr3cko@gmail.com> | 2024-11-02 03:45:31 +0100 |
|---|---|---|
| committer | Pierre-Yves Siret <gr3cko@gmail.com> | 2025-02-14 01:51:47 +0100 |
| commit | d8b4eb1a1756ecfedcdd45511cc7f084f12379ad (patch) | |
| tree | 199052940f32e3a5a83cf88d1bda1cd521817e4f /src/corelib/kernel/qobject.cpp | |
| parent | aad0ab897f61bcb6ac9ba908afd1ee33e05fe4db (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.cpp | 90 |
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. |
