diff options
| author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-08-05 11:55:20 +0200 |
|---|---|---|
| committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-08-07 08:36:11 +0200 |
| commit | 7f4ee7c1b883225a45845be52e151273b31c6bdc (patch) | |
| tree | 7059e3f114d145b397c4530e3a3693b0b0766a74 /sources/pyside6/libpyside/pysidesignal.cpp | |
| parent | e9b81b9ae69555330766ed92df59048eb5d665c9 (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.cpp | 67 |
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) |
