Fixed signal emission with pythonic signalture.
Created unittest.
Reviewer: Hugo Parente Lima <hugo.lima@openbossa.org>,
Luciano Wolf <luciano.wolf@openbossa.org>
This commit is contained in:
parent
9ca3e6148a
commit
542095e1ee
2 changed files with 66 additions and 0 deletions
|
|
@ -43,6 +43,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <typeresolver.h>
|
#include <typeresolver.h>
|
||||||
#include <basewrapper.h>
|
#include <basewrapper.h>
|
||||||
|
#include <conversions.h>
|
||||||
|
|
||||||
#if QSLOT_CODE != 1 || QSIGNAL_CODE != 2
|
#if QSLOT_CODE != 1 || QSIGNAL_CODE != 2
|
||||||
#error QSLOT_CODE and/or QSIGNAL_CODE changed! change the hardcoded stuff to the correct value!
|
#error QSLOT_CODE and/or QSIGNAL_CODE changed! change the hardcoded stuff to the correct value!
|
||||||
|
|
@ -51,6 +52,44 @@
|
||||||
#define PYSIDE_SIGNAL '2'
|
#define PYSIDE_SIGNAL '2'
|
||||||
#include "globalreceiver.h"
|
#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;
|
using namespace PySide;
|
||||||
|
|
||||||
bool PySide::isSignal(const char* signal)
|
bool PySide::isSignal(const char* signal)
|
||||||
|
|
@ -157,6 +196,11 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
|
||||||
{
|
{
|
||||||
// Register Qt primitive typedefs used on signals.
|
// Register Qt primitive typedefs used on signals.
|
||||||
using namespace Shiboken;
|
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<qint8>("qint8");
|
||||||
TypeResolver::createValueTypeResolver<qint16>("qint16");
|
TypeResolver::createValueTypeResolver<qint16>("qint16");
|
||||||
TypeResolver::createValueTypeResolver<qint32>("qint32");
|
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)
|
for (int i = 0; i < argsGiven; ++i)
|
||||||
signalArgs[i+1] = Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->toCpp(PySequence_GetItem(args, i));
|
signalArgs[i+1] = Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->toCpp(PySequence_GetItem(args, i));
|
||||||
|
|
||||||
QMetaObject::activate(source, signalIndex, signalArgs);
|
QMetaObject::activate(source, signalIndex, signalArgs);
|
||||||
|
|
||||||
// FIXME: This will cause troubles with non-direct connections.
|
// FIXME: This will cause troubles with non-direct connections.
|
||||||
for (int i = 0; i < argsGiven; ++i)
|
for (int i = 0; i < argsGiven; ++i)
|
||||||
Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->deleteObject(signalArgs[i+1]);
|
Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->deleteObject(signalArgs[i+1]);
|
||||||
|
|
||||||
delete[] signalArgs;
|
delete[] signalArgs;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -272,8 +320,10 @@ int PySide::SignalManager::qt_metacall(QObject* object, QMetaObject::Call call,
|
||||||
} else {
|
} else {
|
||||||
// call python slot
|
// call python slot
|
||||||
Shiboken::GilState gil;
|
Shiboken::GilState gil;
|
||||||
|
|
||||||
QList<QByteArray> paramTypes = method.parameterTypes();
|
QList<QByteArray> paramTypes = method.parameterTypes();
|
||||||
PyObject* self = Shiboken::BindingManager::instance().retrieveWrapper(object);
|
PyObject* self = Shiboken::BindingManager::instance().retrieveWrapper(object);
|
||||||
|
|
||||||
Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count()));
|
Shiboken::AutoDecRef preparedArgs(PyTuple_New(paramTypes.count()));
|
||||||
|
|
||||||
for (int i = 0, max = paramTypes.count(); i < max; ++i) {
|
for (int i = 0, max = paramTypes.count(); i < max; ++i) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,22 @@ class Dummy(QObject):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
QObject.__init__(self, parent)
|
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):
|
class PythonSigSlot(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.called = False
|
self.called = False
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue