aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpyside/signalmanager.cpp50
-rw-r--r--tests/signals/pysignal_test.py16
2 files changed, 66 insertions, 0 deletions
diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp
index 2640e1e51..7d10f77f4 100644
--- a/libpyside/signalmanager.cpp
+++ b/libpyside/signalmanager.cpp
@@ -43,6 +43,7 @@
#include <limits>
#include <typeresolver.h>
#include <basewrapper.h>
+#include <conversions.h>
#if QSLOT_CODE != 1 || QSIGNAL_CODE != 2
#error QSLOT_CODE and/or QSIGNAL_CODE changed! change the hardcoded stuff to the correct value!
@@ -51,6 +52,44 @@
#define PYSIDE_SIGNAL '2'
#include "globalreceiver.h"
+#define PYTHON_TYPE "PyObject"
+
+
+// Use this to wrap PyObject during the Signal/Slot handling
+struct PyObjectWrapper
+{
+ PyObject* m_me;
+ PyObjectWrapper(PyObject* me) : m_me(me) {}
+ PyObjectWrapper() : m_me(Py_None) {}
+ operator PyObject*() const { return m_me; }
+};
+
+Q_DECLARE_METATYPE(PyObjectWrapper)
+
+namespace Shiboken {
+
+template<>
+struct Converter<PyObjectWrapper>
+{
+ static PyObjectWrapper toCpp(PyObject* obj)
+ {
+ return PyObjectWrapper(obj);
+ }
+
+ static PyObject* toPython(void* obj)
+ {
+ return toPython(*reinterpret_cast<PyObjectWrapper*>(obj));
+ }
+
+ static PyObject* toPython(const PyObjectWrapper& obj)
+ {
+ return obj;
+ }
+};
+
+};
+
+
using namespace PySide;
bool PySide::isSignal(const char* signal)
@@ -157,6 +196,11 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
{
// Register Qt primitive typedefs used on signals.
using namespace Shiboken;
+
+ // Register PyObject type to use in queued signal and slot connections
+ qRegisterMetaType<PyObjectWrapper>(PYTHON_TYPE);
+
+ TypeResolver::createValueTypeResolver<PyObjectWrapper>(PYTHON_TYPE);
TypeResolver::createValueTypeResolver<qint8>("qint8");
TypeResolver::createValueTypeResolver<qint16>("qint16");
TypeResolver::createValueTypeResolver<qint32>("qint32");
@@ -228,11 +272,15 @@ static bool emitNormalSignal(QObject* source, int signalIndex, const char* signa
for (int i = 0; i < argsGiven; ++i)
signalArgs[i+1] = Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->toCpp(PySequence_GetItem(args, i));
+
QMetaObject::activate(source, signalIndex, signalArgs);
+
// FIXME: This will cause troubles with non-direct connections.
for (int i = 0; i < argsGiven; ++i)
Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->deleteObject(signalArgs[i+1]);
+
delete[] signalArgs;
+
return true;
}
@@ -272,8 +320,10 @@ int PySide::SignalManager::qt_metacall(QObject* object, QMetaObject::Call call,
} else {
// call python slot
Shiboken::GilState gil;
+
QList<QByteArray> paramTypes = method.parameterTypes();
PyObject* self = Shiboken::BindingManager::instance().retrieveWrapper(object);
+
Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count()));
for (int i = 0, max = paramTypes.count(); i < max; ++i) {
diff --git a/tests/signals/pysignal_test.py b/tests/signals/pysignal_test.py
index 5f7fc85a2..5d4b09feb 100644
--- a/tests/signals/pysignal_test.py
+++ b/tests/signals/pysignal_test.py
@@ -15,6 +15,22 @@ class Dummy(QObject):
def __init__(self, parent=None):
QObject.__init__(self, parent)
+ def callDummy(self):
+ self.emit(SIGNAL("dummy(PyObject)"), "PyObject")
+
+
+class PyObjectType(unittest.TestCase):
+ def mySlot(self, arg):
+ self.assertEqual(arg, "PyObject")
+ self.called = True
+
+ def testType(self):
+ self.called = False
+ o = Dummy()
+ o.connect(SIGNAL("dummy(PyObject)"), self.mySlot)
+ o.callDummy()
+ self.assert_(self.called)
+
class PythonSigSlot(unittest.TestCase):
def setUp(self):
self.called = False