aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/pysidesignal.cpp
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-08-05 11:55:20 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-08-07 08:36:11 +0200
commit7f4ee7c1b883225a45845be52e151273b31c6bdc (patch)
tree7059e3f114d145b397c4530e3a3693b0b0766a74 /sources/pyside6/libpyside/pysidesignal.cpp
parente9b81b9ae69555330766ed92df59048eb5d665c9 (diff)
Signal manager: Use the same signature lookup for connect/disconnect
Extract a helper for matching the signal instance and use it from signalInstanceConnect() and signalInstanceDisconnect(). This currently only matters for signal QObject::destroyed(QObject*) and QObject::destroyed(). Task-number: PYSIDE-2810 Change-Id: I8ebb8487c7b6953cbfff2179c3b5081a3674bf16 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources/pyside6/libpyside/pysidesignal.cpp')
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp67
1 files changed, 34 insertions, 33 deletions
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
index e85ce99a6..b6c9b0b38 100644
--- a/sources/pyside6/libpyside/pysidesignal.cpp
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -473,6 +473,32 @@ static PySideSignalInstance *findSignalInstance(PySideSignalInstance *source, in
return nullptr;
}
+static PySideSignalInstance *findSignalInstanceForSlot(PySideSignalInstance *source,
+ PyObject *slot)
+{
+ Q_ASSERT(slot != nullptr && slot != Py_None);
+
+ // Check signature of the slot (method or function) to match signal
+ const auto args = extractFunctionArgumentsFromSlot(slot);
+
+ if (args.function != nullptr && source->d->next != nullptr) {
+ auto slotArgRange = argCount(args);
+ if (args.isMethod) {
+ slotArgRange.min -= 1;
+ slotArgRange.max -= 1;
+ }
+
+ // Get signature args
+ // Iterate the possible types of connection for this signal and compare
+ // it with slot arguments
+ for (int slotArgs = slotArgRange.max; slotArgs >= slotArgRange.min; --slotArgs) {
+ if (auto *matchedSlot = findSignalInstance(source, slotArgs))
+ return matchedSlot;
+ }
+ }
+ return source;
+}
+
static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *slot = nullptr;
@@ -516,39 +542,13 @@ static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject
sourceWalk = reinterpret_cast<PySideSignalInstance *>(sourceWalk->d->next);
}
} else {
- // Check signature of the slot (method or function) to match signal
- const auto args = extractFunctionArgumentsFromSlot(slot);
- PySideSignalInstance *matchedSlot = nullptr;
-
- if (args.function != nullptr) {
- auto slotArgRange = argCount(args);
- if (args.isMethod) {
- slotArgRange.min -= 1;
- slotArgRange.max -= 1;
- }
-
- // Get signature args
- // Iterate the possible types of connection for this signal and compare
- // it with slot arguments
- for (int slotArgs = slotArgRange.max;
- slotArgs >= slotArgRange.min && matchedSlot == nullptr; --slotArgs) {
- matchedSlot = findSignalInstance(source, slotArgs);
- }
- }
-
// Adding references to pyArgs
PyList_Append(pyArgs, source->d->source);
- if (matchedSlot != nullptr) {
- // If a slot matching the same number of arguments was found,
- // include signature to the pyArgs
- Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(matchedSlot->d->signature));
- PyList_Append(pyArgs, signature);
- } else {
- // Try the first by default if the slot was not found
- Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(source->d->signature));
- PyList_Append(pyArgs, signature);
- }
+ // Check signature of the slot (method or function) to match signal
+ PySideSignalInstance *matchedSlot = findSignalInstanceForSlot(source, slot);
+ Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(matchedSlot->d->signature));
+ PyList_Append(pyArgs, signature);
PyList_Append(pyArgs, slot);
match = true;
}
@@ -695,9 +695,10 @@ static PyObject *signalInstanceDisconnect(PyObject *self, PyObject *args)
PyList_Append(pyArgs, slot);
match = true;
} else {
- //try the first signature
- PyList_Append(pyArgs, source->d->source);
- Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(source->d->signature));
+ // try the matching signature, fall back to first
+ auto *matchedSlot = slot != Py_None ? findSignalInstanceForSlot(source, slot) : source;
+ PyList_Append(pyArgs, matchedSlot->d->source);
+ Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(matchedSlot->d->signature));
PyList_Append(pyArgs, signature);
// disconnect all, so we need to use the c++ signature disconnect(qobj, signal, 0, 0)