Replaced TypeResolver by SbkConverter and SpecificConverter.

Also updated QtGui's WId conversion to Python 3.
This commit is contained in:
Marcelo Lira 2011-11-01 18:42:47 -03:00 • committed by Hugo Parente Lima
commit 2a87b74bfe
14 changed files with 175 additions and 104 deletions

View file

@ -170,7 +170,7 @@
<!-- FIXME This is a workaround to include some headers needed by some includes (nothing to do with QBool) --> <!-- FIXME This is a workaround to include some headers needed by some includes (nothing to do with QBool) -->
<include file-name="QtConcurrentFilter" location="global"/> <include file-name="QtConcurrentFilter" location="global"/>
</primitive-type> </primitive-type>
<primitive-type name="QString"> <primitive-type name="QString" target-lang-api-name="PyUnicode">
<include file-name="QString" location="global"/> <include file-name="QString" location="global"/>
<conversion-rule file="qstring_conversions.h"> <conversion-rule file="qstring_conversions.h">
<native-to-target> <native-to-target>
@ -248,22 +248,28 @@
<native-to-target> <native-to-target>
if (!%in.isValid()) if (!%in.isValid())
Py_RETURN_NONE; Py_RETURN_NONE;
if (qstrcmp(%in.typeName(), "QVariantList") == 0) { if (qstrcmp(%in.typeName(), "QVariantList") == 0) {
QList&lt;QVariant&gt; var = %in.value&lt;QVariantList&gt;(); QList&lt;QVariant&gt; var = %in.value&lt;QVariantList&gt;();
return %CONVERTTOPYTHON[QList&lt;QVariant&gt;](var); return %CONVERTTOPYTHON[QList&lt;QVariant&gt;](var);
} }
if (qstrcmp(%in.typeName(), "QStringList") == 0) { if (qstrcmp(%in.typeName(), "QStringList") == 0) {
QStringList var = %in.value&lt;QStringList&gt;(); QStringList var = %in.value&lt;QStringList&gt;();
return %CONVERTTOPYTHON[QList&lt;QString&gt;](var); return %CONVERTTOPYTHON[QList&lt;QString&gt;](var);
} }
if (qstrcmp(%in.typeName(), "QVariantMap") == 0) { if (qstrcmp(%in.typeName(), "QVariantMap") == 0) {
QMap&lt;QString, QVariant&gt; var = %in.value&lt;QVariantMap&gt;(); QMap&lt;QString, QVariant&gt; var = %in.value&lt;QVariantMap&gt;();
return %CONVERTTOPYTHON[QMap&lt;QString, QVariant&gt;](var); return %CONVERTTOPYTHON[QMap&lt;QString, QVariant&gt;](var);
} }
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(%in.typeName());
if (tr) Shiboken::Conversions::SpecificConverter converter(cppInRef.typeName());
return tr->toPython(const_cast&lt;void*&gt;(%in.data())); if (converter) {
// TODO-CONVERTERS: SET ERROR void* ptr = cppInRef.data();
return converter.toPython(ptr);
}
PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName());
return 0; return 0;
</native-to-target> </native-to-target>
<target-to-native> <target-to-native>
@ -273,11 +279,11 @@
<add-conversion type="Py_None"> <add-conversion type="Py_None">
%out = %OUTTYPE(); %out = %OUTTYPE();
</add-conversion> </add-conversion>
<add-conversion type="PyString" check="%CHECKTYPE[QString](%in)"> <add-conversion type="QString" check="Shiboken::String::check(%in)">
QString in = %CONVERTTOCPP[QString](%in); QString in = %CONVERTTOCPP[QString](%in);
%out = %OUTTYPE(in); %out = %OUTTYPE(in);
</add-conversion> </add-conversion>
<add-conversion type="QByteArray" check="%CHECKTYPE[QByteArray](%in)"> <add-conversion type="QByteArray">
QByteArray in = %CONVERTTOCPP[QByteArray](%in); QByteArray in = %CONVERTTOCPP[QByteArray](%in);
%out = %OUTTYPE(in); %out = %OUTTYPE(in);
</add-conversion> </add-conversion>
@ -301,19 +307,16 @@
// a class supported by QVariant? // a class supported by QVariant?
int typeCode; int typeCode;
const char* typeName = QVariant_resolveMetaType(%in->ob_type, &amp;typeCode); const char* typeName = QVariant_resolveMetaType(%in->ob_type, &amp;typeCode);
if (typeCode &amp;&amp; typeName) { if (!typeCode || !typeName)
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName); return;
QVariant var(typeCode, (void*)0); QVariant var(typeCode, (void*)0);
void* args[] = { var.data() }; Shiboken::Conversions::SpecificConverter converter(typeName);
tr->toCpp(%in, args); converter.toCpp(pyIn, var.data());
%out = var; %out = var;
}
</add-conversion> </add-conversion>
<add-conversion type="PyDict"> <add-conversion type="PyDict">
QVariant ret = QVariant_convertToVariantMap(%in); QVariant ret = QVariant_convertToVariantMap(%in);
if (ret.isValid()) %out = ret.isValid() ? ret : QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
%out = ret;
%out = QVariant::fromValue&lt;PySide::PyObjectWrapper&gt;(%in);
</add-conversion> </add-conversion>
<add-conversion type="PySequence"> <add-conversion type="PySequence">
%out = QVariant_convertToVariantList(%in); %out = QVariant_convertToVariantList(%in);
@ -372,15 +375,13 @@
listTypeName += '>'; listTypeName += '>';
typeId = QMetaType::type(listTypeName); typeId = QMetaType::type(listTypeName);
if (typeId &gt; 0) { if (typeId &gt; 0) {
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(listTypeName); Shiboken::Conversions::SpecificConverter converter(listTypeName);
if (!tr) { if (converter) {
qWarning() &lt;&lt; "TypeResolver for :" &lt;&lt; listTypeName &lt;&lt; "not registered.";
} else {
QVariant var(typeId, (void*)0); QVariant var(typeId, (void*)0);
void* args[] = { var.data(), 0 }; converter.toCpp(list, &amp;var);
tr->toCpp(list, args);
return var; return var;
} }
qWarning() &lt;&lt; "Type converter for :" &lt;&lt; listTypeName &lt;&lt; "not registered.";
} }
} }
return QVariant(); return QVariant();
@ -417,25 +418,22 @@
} }
static QVariant QVariant_convertToVariantList(PyObject* list) static QVariant QVariant_convertToVariantList(PyObject* list)
{ {
bool allString = QVariant_isStringList(list); if (QVariant_isStringList(list)) {
if (allString) {
QList&lt;QString &gt; lst = %CONVERTTOCPP[QList&lt;QString&gt;](list); QList&lt;QString &gt; lst = %CONVERTTOCPP[QList&lt;QString&gt;](list);
return QVariant(QStringList(lst)); return QVariant(QStringList(lst));
} else {
QVariant valueList = QVariant_convertToValueList(list);
if (valueList.isValid())
return valueList;
QList&lt;QVariant&gt; lst;
Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
for (int i = 0; i &lt; size; ++i) {
PyObject* pyItem = PySequence_Fast_GET_ITEM(fast.object(), i);
QVariant item = %CONVERTTOCPP[QVariant](pyItem);
lst.append(item);
}
return QVariant(lst);
} }
Q_ASSERT(false); QVariant valueList = QVariant_convertToValueList(list);
if (valueList.isValid())
return valueList;
QList&lt;QVariant&gt; lst;
Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList"));
Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object());
for (int i = 0; i &lt; size; ++i) {
PyObject* pyItem = PySequence_Fast_GET_ITEM(fast.object(), i);
QVariant item = %CONVERTTOCPP[QVariant](pyItem);
lst.append(item);
}
return QVariant(lst);
} }
</inject-code> </inject-code>
@ -444,12 +442,10 @@
<native-to-target> <native-to-target>
const char* typeName = QVariant::typeToName(%in); const char* typeName = QVariant::typeToName(%in);
PyObject* %out; PyObject* %out;
if (!typeName) { PyTypeObject* pyType = 0;
%out = Py_None; if (typeName)
} else { pyType = Shiboken::Conversions::getPythonTypeObject(typeName);
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName); %out = pyType ? ((PyObject*)pyType) : Py_None;
%out = tr ? (PyObject*)tr->pythonType() : Py_None;
}
Py_INCREF(%out); Py_INCREF(%out);
return %out; return %out;
</native-to-target> </native-to-target>
@ -492,7 +488,10 @@
</conversion-rule> </conversion-rule>
</primitive-type> </primitive-type>
<primitive-type name="QVariantMap" /> <primitive-type name="QVariantMap" target-lang-api-name="PyDict"/>
<inject-code class="target" position="end">
Shiboken::Conversions::registerConverterName(SbkPySide_QtCoreTypeConverters[SBK_QTCORE_QMAP_QSTRING_QVARIANT_IDX], "QVariantMap");
</inject-code>
<inject-code class="native" position="beginning"> <inject-code class="native" position="beginning">
static bool QVariantType_isStringList(PyObject* list) static bool QVariantType_isStringList(PyObject* list)
@ -920,9 +919,10 @@
<!--signal/slot--> <!--signal/slot-->
<inject-code class="target" position="end"> <inject-code class="target" position="end">
Shiboken::TypeResolver::createValueTypeResolver&lt;QString>("unicode"); Shiboken::Conversions::registerConverterName(SbkPySide_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode");
Shiboken::TypeResolver::createValueTypeResolver&lt;QString>("str"); Shiboken::Conversions::registerConverterName(SbkPySide_QtCoreTypeConverters[SBK_QSTRING_IDX], "str");
Shiboken::TypeResolver::createValueTypeResolver&lt;QVariantList>("QVariantList"); Shiboken::Conversions::registerConverterName(SbkPySide_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList");
PySide::init(module); PySide::init(module);
Py_AtExit(QtCoreModuleExit); Py_AtExit(QtCoreModuleExit);
</inject-code> </inject-code>

View file

@ -93,8 +93,8 @@ int PySide::qmlRegisterType(PyObject* pyObj, const char* uri, int versionMajor,
{ {
using namespace Shiboken; using namespace Shiboken;
static PyTypeObject* qobjectType = TypeResolver::get("QObject*")->pythonType(); static PyTypeObject* qobjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
static PyTypeObject* qdeclarativeType = TypeResolver::get("QDeclarativeItem*")->pythonType(); static PyTypeObject* qdeclarativeType = Shiboken::Conversions::getPythonTypeObject("QDeclarativeItem*");
assert(qobjectType); assert(qobjectType);
static int nextType = 0; static int nextType = 0;

View file

@ -60,8 +60,7 @@
</enum-type> </enum-type>
<inject-code class="target" position="end"> <inject-code class="target" position="end">
Shiboken::TypeResolver::createValueTypeResolver&lt; QList&lt;QObject*&gt; &gt;("QList&lt;QObject*&gt;"); PySide::initQmlSupport(module);
PySide::initQmlSupport(module);
</inject-code> </inject-code>
<object-type name="QDeclarativeExtensionInterface"/> <object-type name="QDeclarativeExtensionInterface"/>

View file

@ -23,14 +23,32 @@
<primitive-type name="WId" target-lang-api-name="PyObject"> <primitive-type name="WId" target-lang-api-name="PyObject">
<conversion-rule file="glue/wid_conversions.h"> <conversion-rule file="glue/wid_conversions.h">
<native-to-target> <native-to-target>
#ifdef IS_PY3K
return PyCapsule_New(%in, 0, 0);
#else
return PyCObject_FromVoidPtr(%in, 0); return PyCObject_FromVoidPtr(%in, 0);
#endif
</native-to-target> </native-to-target>
<target-to-native> <target-to-native>
<add-conversion type="PyCObject"> <add-conversion type="checkPyCapsuleOrPyCObject">
#ifdef IS_PY3K
%out = (%OUTTYPE)PyCapsule_GetPointer(%in, 0);
#else
%out = (%OUTTYPE)PyCObject_AsVoidPtr(%in); %out = (%OUTTYPE)PyCObject_AsVoidPtr(%in);
#endif
</add-conversion> </add-conversion>
</target-to-native> </target-to-native>
</conversion-rule> </conversion-rule>
</primitive-type> </primitive-type>
<inject-code class="native" position="beginning">
static bool checkPyCapsuleOrPyCObject(PyObject* pyObj)
{
#ifdef IS_PY3K
return PyCapsule_CheckExact(pyObj);
#else
return PyCObject_Check(pyObj);
#endif
}
</inject-code>
<enum-type name="QPixmap::HBitmapFormat" /> <enum-type name="QPixmap::HBitmapFormat" />
</typesystem> </typesystem>

View file

@ -81,9 +81,6 @@
<include file-name="QSqlField" location="global"/> <include file-name="QSqlField" location="global"/>
</extra-includes> </extra-includes>
<modify-function signature="append(QSqlField)" access="non-final"/> <modify-function signature="append(QSqlField)" access="non-final"/>
<inject-code position="end">
Shiboken::TypeResolver::createReferenceTypeResolver&lt; ::QSqlRecord >("QSqlRecord&amp;");
</inject-code>
</value-type> </value-type>
<value-type name="QSqlError"> <value-type name="QSqlError">

View file

@ -29,6 +29,7 @@
#include <QEvent> #include <QEvent>
#include <QLinkedList> #include <QLinkedList>
#include <autodecref.h> #include <autodecref.h>
#include <sbkconverter.h>
#include <gilstate.h> #include <gilstate.h>
#include "typeresolver.h" #include "typeresolver.h"
@ -293,8 +294,9 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
QList<QByteArray> paramTypes = slot.parameterTypes(); QList<QByteArray> paramTypes = slot.parameterTypes();
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) {
PyObject* arg = Shiboken::TypeResolver::get(paramTypes[i].constData())->toPython(args[i+1]); // Do not increment the reference const QByteArray& paramType = paramTypes[i];
PyTuple_SET_ITEM(preparedArgs.object(), i, arg); Shiboken::Conversions::SpecificConverter converter(paramType.constData());
PyTuple_SET_ITEM(preparedArgs.object(), i, converter.toPython(args[i+1]));
} }
retval = data->call(preparedArgs); retval = data->call(preparedArgs);
} }
@ -306,4 +308,3 @@ int GlobalReceiver::qt_metacall(QMetaObject::Call call, int id, void** args)
return -1; return -1;
} }

View file

@ -35,6 +35,7 @@
#include <basewrapper.h> #include <basewrapper.h>
#include <conversions.h> #include <conversions.h>
#include <sbkconverter.h>
#include <typeresolver.h> #include <typeresolver.h>
#include <bindingmanager.h> #include <bindingmanager.h>
#include <algorithm> #include <algorithm>
@ -141,7 +142,7 @@ void destroyQCoreApplication()
Shiboken::BindingManager& bm = Shiboken::BindingManager::instance(); Shiboken::BindingManager& bm = Shiboken::BindingManager::instance();
SbkObject* pyQApp = bm.retrieveWrapper(app); SbkObject* pyQApp = bm.retrieveWrapper(app);
PyTypeObject* pyQObjectType = Shiboken::TypeResolver::get("QObject*")->pythonType(); PyTypeObject* pyQObjectType = Shiboken::Conversions::getPythonTypeObject("QObject*");
assert(pyQObjectType); assert(pyQObjectType);
void* data[2] = {pyQApp, pyQObjectType}; void* data[2] = {pyQApp, pyQObjectType};
@ -174,7 +175,10 @@ void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base, const s
//initialize staticQMetaObject property //initialize staticQMetaObject property
void* metaObjectPtr = &userData->mo; void* metaObjectPtr = &userData->mo;
Shiboken::AutoDecRef pyMetaObject(Shiboken::TypeResolver::get("QMetaObject*")->toPython(&metaObjectPtr)); static SbkConverter* converter = Shiboken::Conversions::getConverter("QMetaObject");
if (!converter)
return;
Shiboken::AutoDecRef pyMetaObject(Shiboken::Conversions::pointerToPython(converter, metaObjectPtr));
PyObject_SetAttrString(reinterpret_cast<PyObject*>(type), "staticMetaObject", pyMetaObject); PyObject_SetAttrString(reinterpret_cast<PyObject*>(type), "staticMetaObject", pyMetaObject);
} }
@ -185,7 +189,7 @@ void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base)
void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds) void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds)
{ {
PyTypeObject* qObjType = Shiboken::TypeResolver::get("QObject*")->pythonType(); PyTypeObject* qObjType = Shiboken::Conversions::getPythonTypeObject("QObject*");
QByteArray className(Shiboken::String::toCString(PyTuple_GET_ITEM(args, 0))); QByteArray className(Shiboken::String::toCString(PyTuple_GET_ITEM(args, 0)));
PyObject* bases = PyTuple_GET_ITEM(args, 1); PyObject* bases = PyTuple_GET_ITEM(args, 1);

View file

@ -169,10 +169,10 @@ bool call(QObject* self, int methodIndex, PyObject* args, PyObject** retVal)
continue; continue;
} }
Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(typeName); Shiboken::Conversions::SpecificConverter converter(typeName);
if (typeResolver) { if (converter) {
if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ValueType) { int typeId = QMetaType::type(typeName);
int typeId = QMetaType::type(typeName); if (!Shiboken::Conversions::pythonTypeIsObjectType(converter)) {
if (!typeId) { if (!typeId) {
PyErr_Format(PyExc_TypeError, "Value types used on meta functions (including signals) need to be " PyErr_Format(PyExc_TypeError, "Value types used on meta functions (including signals) need to be "
"registered on meta type: %s", typeName.data()); "registered on meta type: %s", typeName.data());
@ -181,8 +181,15 @@ bool call(QObject* self, int methodIndex, PyObject* args, PyObject** retVal)
methValues[i] = QVariant(typeId, (void*) 0); methValues[i] = QVariant(typeId, (void*) 0);
} }
methArgs[i] = methValues[i].data(); methArgs[i] = methValues[i].data();
if (i != 0) // Don't do this for return type if (i == 0) // Don't do this for return type
typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i - 1), &methArgs[i]); continue;
if (typeId == QVariant::String) {
QString tmp;
converter.toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i - 1), &tmp);
methValues[i] = tmp;
} else {
converter.toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i - 1), methArgs[i]);
}
} else { } else {
PyErr_Format(PyExc_TypeError, "Unknown type used to call meta function (that may be a signal): %s", argTypes[i].constData()); PyErr_Format(PyExc_TypeError, "Unknown type used to call meta function (that may be a signal): %s", argTypes[i].constData());
break; break;
@ -195,10 +202,10 @@ bool call(QObject* self, int methodIndex, PyObject* args, PyObject** retVal)
if (retVal) { if (retVal) {
if (methArgs[0]) { if (methArgs[0]) {
static Shiboken::TypeResolver* qVariantTypeResolver = Shiboken::TypeResolver::get("QVariant"); static SbkConverter* qVariantTypeConverter = Shiboken::Conversions::getConverter("QVariant");
Q_ASSERT(qVariantTypeResolver); Q_ASSERT(qVariantTypeConverter);
*retVal = Shiboken::Conversions::copyToPython(qVariantTypeConverter, &methValues[0]);
*retVal = qVariantTypeResolver->toPython(&methValues[0]); SbkDbg() << (*retVal);
} else { } else {
*retVal = Py_None; *retVal = Py_None;
Py_INCREF(*retVal); Py_INCREF(*retVal);

View file

@ -104,8 +104,10 @@ PyTypeObject PySidePropertyType = {
static void qpropertyMetaCall(PySideProperty* pp, PyObject* self, QMetaObject::Call call, void** args) static void qpropertyMetaCall(PySideProperty* pp, PyObject* self, QMetaObject::Call call, void** args)
{ {
Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(pp->d->typeName); Shiboken::Conversions::SpecificConverter converter(pp->d->typeName);
Q_ASSERT(typeResolver); Q_ASSERT(converter);
QByteArray type(pp->d->typeName);
switch(call) { switch(call) {
case QMetaObject::ReadProperty: case QMetaObject::ReadProperty:
@ -113,7 +115,7 @@ static void qpropertyMetaCall(PySideProperty* pp, PyObject* self, QMetaObject::C
Shiboken::GilState gil; Shiboken::GilState gil;
PyObject* value = PySide::Property::getValue(pp, self); PyObject* value = PySide::Property::getValue(pp, self);
if (value) { if (value) {
typeResolver->toCpp(value, &args[0]); converter.toCpp(value, args[0]);
Py_DECREF(value); Py_DECREF(value);
} else if (PyErr_Occurred()) { } else if (PyErr_Occurred()) {
PyErr_Print(); // Clear any errors but print them to stderr PyErr_Print(); // Clear any errors but print them to stderr
@ -124,7 +126,7 @@ static void qpropertyMetaCall(PySideProperty* pp, PyObject* self, QMetaObject::C
case QMetaObject::WriteProperty: case QMetaObject::WriteProperty:
{ {
Shiboken::GilState gil; Shiboken::GilState gil;
Shiboken::AutoDecRef value(typeResolver->toPython(args[0])); Shiboken::AutoDecRef value(converter.toPython(args[0]));
PySide::Property::setValue(pp, self, value); PySide::Property::setValue(pp, self, value);
break; break;
} }

View file

@ -38,6 +38,7 @@
#include <algorithm> #include <algorithm>
#include <typeresolver.h> #include <typeresolver.h>
#include <basewrapper.h> #include <basewrapper.h>
#include <sbkconverter.h>
#include <conversions.h> #include <conversions.h>
#if QSLOT_CODE != 1 || QSIGNAL_CODE != 2 #if QSLOT_CODE != 1 || QSIGNAL_CODE != 2
@ -225,6 +226,22 @@ static void clearSignalManager()
PySide::SignalManager::instance().clear(); PySide::SignalManager::instance().clear();
} }
static void PyObject_PythonToCpp_PyObject_PTR(PyObject* pyIn, void* cppOut)
{
*((PyObject**)cppOut) = pyIn;
}
static PythonToCppFunc is_PyObject_PythonToCpp_PyObject_PTR_Convertible(PyObject* pyIn)
{
return PyObject_PythonToCpp_PyObject_PTR;
}
static PyObject* PyObject_PTR_CppToPython_PyObject(const void* cppIn)
{
PyObject* pyOut = (PyObject*)cppIn;
if (pyOut)
Py_INCREF(pyOut);
return pyOut;
}
SignalManager::SignalManager() : m_d(new SignalManagerPrivate) SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
{ {
// Register Qt primitive typedefs used on signals. // Register Qt primitive typedefs used on signals.
@ -234,9 +251,14 @@ SignalManager::SignalManager() : m_d(new SignalManagerPrivate)
qRegisterMetaType<PyObjectWrapper>(PYTHON_TYPE); qRegisterMetaType<PyObjectWrapper>(PYTHON_TYPE);
qRegisterMetaTypeStreamOperators<PyObjectWrapper>(PYTHON_TYPE); qRegisterMetaTypeStreamOperators<PyObjectWrapper>(PYTHON_TYPE);
TypeResolver::createValueTypeResolver<PyObjectWrapper>(PYTHON_TYPE); SbkConverter* converter = Shiboken::Conversions::createConverter(&PyBaseObject_Type, 0);
TypeResolver::createValueTypeResolver<PyObjectWrapper>("object"); Shiboken::Conversions::setCppPointerToPythonFunction(converter, PyObject_PTR_CppToPython_PyObject);
TypeResolver::createValueTypeResolver<PyObjectWrapper>("PySide::PyObjectWrapper"); Shiboken::Conversions::setPythonToCppPointerFunctions(converter, PyObject_PythonToCpp_PyObject_PTR, is_PyObject_PythonToCpp_PyObject_PTR_Convertible);
Shiboken::Conversions::registerConverterName(converter, PYTHON_TYPE);
Shiboken::Conversions::registerConverterName(converter, "object");
Shiboken::Conversions::registerConverterName(converter, "PyObjectWrapper");
Shiboken::Conversions::registerConverterName(converter, "PySide::PyObjectWrapper");
PySide::registerCleanupFunction(clearSignalManager); PySide::registerCleanupFunction(clearSignalManager);
if (!metaObjectAttr) if (!metaObjectAttr)
@ -436,11 +458,12 @@ int SignalManager::callPythonMetaMethod(const QMetaMethod& method, void** args,
if (!retval.isNull() && retval != Py_None && !PyErr_Occurred()) { if (!retval.isNull() && retval != Py_None && !PyErr_Occurred()) {
const char* returnType = method.typeName(); const char* returnType = method.typeName();
if (returnType && std::strcmp("", returnType)) { if (returnType && std::strcmp("", returnType)) {
Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(returnType); Shiboken::Conversions::SpecificConverter converter(returnType);
if (typeResolver) if (converter)
typeResolver->toCpp(retval, &args[0]); converter.toCpp(retval, args[0]);
else else
PyErr_Format(PyExc_RuntimeError, "Can't fidn type resolver \"%s\" to call Python meta method.", returnType); PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s' to call Python meta method.", returnType);
} }
} }
} }
@ -555,13 +578,10 @@ static PyObject* parseArguments(const QList<QByteArray>& paramTypes, void** args
for (int i = 0, max = argsSize; i < max; ++i) { for (int i = 0, max = argsSize; i < max; ++i) {
void* data = args[i+1]; void* data = args[i+1];
const char* dataType = paramTypes[i].constData(); const char* dataType = paramTypes[i].constData();
Shiboken::Conversions::SpecificConverter converter(dataType);
Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(dataType); if (converter) {
if (tr) { PyTuple_SET_ITEM(preparedArgs, i, converter.toPython(data));
PyObject* arg = tr->toPython(data);
PyTuple_SET_ITEM(preparedArgs, i, arg);
} else { } else {
PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType); PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType);
Py_DECREF(preparedArgs); Py_DECREF(preparedArgs);
return 0; return 0;

View file

@ -3,7 +3,7 @@
import unittest import unittest
from PySide.QtCore import * from PySide.QtCore import QObject, Property, Signal
class MyObjectWithNotifyProperty(QObject): class MyObjectWithNotifyProperty(QObject):
def __init__(self, parent=None): def __init__(self, parent=None):
@ -31,7 +31,12 @@ class PropertyWithNotify(unittest.TestCase):
obj.myProperty = 10 obj.myProperty = 10
self.assert_(self.called_) self.assert_(self.called_)
def testHasProperty(self):
o = MyObjectWithNotifyProperty()
o.setProperty("myProperty", 10)
self.assertEqual(o.myProperty, 10)
self.assertEqual(o.property("myProperty"), 10)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View file

@ -1,5 +1,6 @@
#include "testview.h" #include "testview.h"
#include <QDebug>
#include <QWidget> #include <QWidget>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QAbstractItemDelegate> #include <QAbstractItemDelegate>
@ -21,4 +22,3 @@ TestView::getEditorWidgetFromItemDelegate() const
QStyleOptionViewItem options; QStyleOptionViewItem options;
return m_delegate->createEditor(0, options, index); return m_delegate->createEditor(0, options, index);
} }

View file

@ -3,27 +3,46 @@
<load-typesystem name="typesystem_core.xml" generate="no" /> <load-typesystem name="typesystem_core.xml" generate="no" />
<load-typesystem name="typesystem_gui.xml" generate="no"/> <load-typesystem name="typesystem_gui.xml" generate="no"/>
<value-type name="IntValue"/> <value-type name="IntValue"/>
<primitive-type name="TypedefValue"/> <primitive-type name="TypedefValue">
<!--
A conversion rule is used here because ApiExtractor can't associate
a primitive typedef to a non-primitive type. That would be a good
improvement to ApiExtractor.
-->
<conversion-rule>
<native-to-target>
return %CONVERTTOPYTHON[IntValue](%in);
</native-to-target>
<target-to-native>
<add-conversion type="IntValue">
IntValue value = %CONVERTTOCPP[IntValue](%in);
%out = %OUTTYPE(value);
</add-conversion>
</target-to-native>
</conversion-rule>
</primitive-type>
<object-type name="TestObject" /> <object-type name="TestObject" />
<primitive-type name="PySideInt"/>
<primitive-type name="PySideCPP2::PySideLong"/>
<!--<primitive-type name="PySideLong"/>-->
<function signature="getHiddenObject()" /> <function signature="getHiddenObject()" />
<inject-code position="end"> <inject-code position="end">
Shiboken::TypeResolver::createObjectTypeResolver&lt; ::PySideCPP2::TestObjectWithoutNamespace>("TestObjectWithoutNamespace*"); Shiboken::Conversions::registerConverterName(Shiboken::Conversions::PrimitiveTypeConverter&lt;long&gt;(), "PySideLong");
Shiboken::TypeResolver::createValueTypeResolver&lt; ::PySideCPP2::PySideLong>("PySideLong"); Shiboken::Conversions::registerConverterName(Shiboken::Conversions::PrimitiveTypeConverter&lt;long&gt;(), "PySideCPP2::PySideLong");
Shiboken::TypeResolver::createObjectTypeResolver&lt; ::PySideCPP::TestObjectWithNamespace>("TestObjectWithNamespace*"); qRegisterMetaType&lt;PySideInt>("PySideInt");
Shiboken::TypeResolver::createValueTypeResolver&lt; ::PySideInt>("PySideInt"); qRegisterMetaType&lt;PySideCPP2::PySideLong>("PySideLong");
qRegisterMetaType&lt;PySideInt>("PySideInt");
qRegisterMetaType&lt;PySideCPP2::PySideLong>("PySideLong");
</inject-code> </inject-code>
<namespace-type name="PySideCPP"> <namespace-type name="PySideCPP">
<object-type name="TestObjectWithNamespace" /> <object-type name="TestObjectWithNamespace"/>
</namespace-type> </namespace-type>
<namespace-type name="PySideCPP2" generate="no"> <namespace-type name="PySideCPP2" generate="no">
<enum-type name="Enum1" /> <enum-type name="Enum1" />
<object-type name="TestObjectWithoutNamespace" > <object-type name="TestObjectWithoutNamespace">
<enum-type name="Enum2" /> <enum-type name="Enum2" />
</object-type> </object-type>
</namespace-type> </namespace-type>
@ -36,4 +55,3 @@
</modify-function> </modify-function>
</object-type> </object-type>
</typesystem> </typesystem>