Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-07-02 10:38:45 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-07-04 11:55:52 +0200
commit08d61b56fa9e901b807b67b07f187e0f54e7551c (patch)
tree2408c7fb6ebb7fcb4267871e9ab0c34c861d1a56 /sources
parent0e920a721830ca0ed900492756335ceafea1fedd (diff)
libpyside: Fix parameters for connections with contexts
Use the new SignalManager::callPythonMetaMethod() overload introduced by ed8fc457e04f4ead8a3b2a2da797bdc14bd5b210 in PySideQSlotObject to convert the void ** arguments to Python. Amends acab25a3ccb836818e5089b23d40196bc7414b7a. Change-Id: I024bc7f8df7fa65b8b1761f517a99a854de2cec8 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Diffstat (limited to 'sources')
-rw-r--r--sources/pyside6/libpyside/pysideqslotobject_p.cpp34
-rw-r--r--sources/pyside6/libpyside/pysideqslotobject_p.h22
-rw-r--r--sources/pyside6/libpyside/qobjectconnect.cpp6
-rw-r--r--sources/pyside6/tests/signals/signal_emission_test.py26
4 files changed, 64 insertions, 24 deletions
diff --git a/sources/pyside6/libpyside/pysideqslotobject_p.cpp b/sources/pyside6/libpyside/pysideqslotobject_p.cpp
index 914be898a..40b011fcf 100644
--- a/sources/pyside6/libpyside/pysideqslotobject_p.cpp
+++ b/sources/pyside6/libpyside/pysideqslotobject_p.cpp
@@ -2,28 +2,46 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "pysideqslotobject_p.h"
+#include "signalmanager.h"
-#include <autodecref.h>
#include <gilstate.h>
namespace PySide
{
+PySideQSlotObject::PySideQSlotObject(PyObject *callable,
+ const QByteArrayList &parameterTypes,
+ const char *returnType) :
+ QtPrivate::QSlotObjectBase(&impl),
+ m_callable(callable),
+ m_parameterTypes(parameterTypes),
+ m_returnType(returnType)
+{
+ Py_INCREF(callable);
+}
+
+PySideQSlotObject::~PySideQSlotObject()
+{
+ Shiboken::GilState state;
+ Py_DECREF(m_callable);
+}
+
+void PySideQSlotObject::call(void **args)
+{
+ SignalManager::callPythonMetaMethod(m_parameterTypes, m_returnType, args, m_callable);
+}
+
void PySideQSlotObject::impl(int which, QSlotObjectBase *this_, QObject *receiver,
void **args, bool *ret)
{
- auto self = static_cast<PySideQSlotObject *>(this_);
+ auto *self = static_cast<PySideQSlotObject *>(this_);
switch (which) {
case Destroy:
delete self;
break;
case Call:
- {
- Shiboken::GilState state;
- Shiboken::AutoDecRef arglist(PyTuple_New(0));
- Shiboken::AutoDecRef ret(PyObject_CallObject(self->callable, arglist));
- break;
- }
+ self->call(args);
+ break;
case Compare:
case NumOperations:
Q_UNUSED(receiver);
diff --git a/sources/pyside6/libpyside/pysideqslotobject_p.h b/sources/pyside6/libpyside/pysideqslotobject_p.h
index d7d258505..827f0193c 100644
--- a/sources/pyside6/libpyside/pysideqslotobject_p.h
+++ b/sources/pyside6/libpyside/pysideqslotobject_p.h
@@ -15,22 +15,18 @@ namespace PySide
class PySideQSlotObject : public QtPrivate::QSlotObjectBase
{
- PyObject *callable;
+public:
+ explicit PySideQSlotObject(PyObject *callable, const QByteArrayList &parameterTypes,
+ const char *returnType = nullptr);
+ ~PySideQSlotObject();
+private:
static void impl(int which, QSlotObjectBase *this_, QObject *receiver, void **args, bool *ret);
+ void call(void **args);
-public:
- PySideQSlotObject(PyObject *callable) : QtPrivate::QSlotObjectBase(&impl), callable(callable)
- {
- Py_INCREF(callable);
- }
-
- ~PySideQSlotObject()
- {
- auto gstate = PyGILState_Ensure();
- Py_DECREF(callable);
- PyGILState_Release(gstate);
- }
+ PyObject *m_callable;
+ const QByteArrayList m_parameterTypes;
+ const char *m_returnType;
};
diff --git a/sources/pyside6/libpyside/qobjectconnect.cpp b/sources/pyside6/libpyside/qobjectconnect.cpp
index d0a1a2c50..e27827ce4 100644
--- a/sources/pyside6/libpyside/qobjectconnect.cpp
+++ b/sources/pyside6/libpyside/qobjectconnect.cpp
@@ -282,7 +282,10 @@ QMetaObject::Connection qobjectConnectCallback(QObject *source, const char *sign
PySide::SignalManager &signalManager = PySide::SignalManager::instance();
- auto *slotObject = new PySideQSlotObject(callback);
+ const QMetaMethod signalMethod = source->metaObject()->method(signalIndex);
+ auto *slotObject = new PySideQSlotObject(callback,
+ signalMethod.parameterTypes(),
+ signalMethod.typeName());
QMetaObject::Connection connection{};
Py_BEGIN_ALLOW_THREADS // PYSIDE-2367, prevent threading deadlocks with connectNotify()
@@ -298,7 +301,6 @@ QMetaObject::Connection qobjectConnectCallback(QObject *source, const char *sign
if (receiver.usingGlobalReceiver)
signalManager.notifyGlobalReceiver(receiver.receiver);
- const QMetaMethod signalMethod = source->metaObject()->method(signalIndex);
static_cast<FriendlyQObject *>(source)->connectNotify(signalMethod);
return connection;
}
diff --git a/sources/pyside6/tests/signals/signal_emission_test.py b/sources/pyside6/tests/signals/signal_emission_test.py
index 769b1839a..b0c02b084 100644
--- a/sources/pyside6/tests/signals/signal_emission_test.py
+++ b/sources/pyside6/tests/signals/signal_emission_test.py
@@ -15,7 +15,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from init_paths import init_test_paths
init_test_paths(False)
-from PySide6.QtCore import QObject, Signal, SIGNAL, QProcess, QTimeLine
+from PySide6.QtCore import QObject, Signal, SIGNAL, QProcess, QTimeLine, Slot
from helper.usesqapplication import UsesQApplication
@@ -45,6 +45,18 @@ class Sender(QObject):
dummy_int = Signal(int)
+class Receiver(QObject):
+ '''Receiver class'''
+
+ def __init__(self, p=None):
+ super().__init__(p)
+ self.n = 0
+
+ @Slot(int)
+ def intSlot(self, n):
+ self.n = n
+
+
class PythonSignalToCppSlots(UsesQApplication):
'''Connect python signals to C++ slots'''
@@ -75,6 +87,18 @@ class PythonSignalToCppSlots(UsesQApplication):
self.assertEqual(timeline.currentTime(), current + 42)
+class ConnectWithContext(UsesQApplication):
+ '''Test whether a connection with context QObject passes parameters.'''
+
+ def testIt(self):
+ sender = Sender()
+ receiver = Receiver()
+ context = sender
+ QObject.connect(sender, SIGNAL("dummy_int(int)"), context, receiver.intSlot)
+ sender.dummy_int.emit(42)
+ self.assertEqual(receiver.n, 42)
+
+
class CppSignalsToCppSlots(UsesQApplication):
'''Connection between C++ slots and signals'''