diff options
author | Renato Filho <renato.filho@openbossa.org> | 2011-07-06 15:39:48 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2012-03-08 16:54:31 -0300 |
commit | f2cecb5697bbc725432315a1e9c54b2904c3b1e2 (patch) | |
tree | 46ec6d2a7c1deb90313f71de5c99d07c553e3877 /libpyside | |
parent | f3d69f65d18b641aeeedfbbfe8a0e16d2a75d9fe (diff) |
Implemented staticMetaObject property for QObjects.
Diffstat (limited to 'libpyside')
-rw-r--r-- | libpyside/dynamicqmetaobject.cpp | 71 | ||||
-rw-r--r-- | libpyside/dynamicqmetaobject.h | 5 | ||||
-rw-r--r-- | libpyside/pyside.cpp | 71 |
3 files changed, 86 insertions, 61 deletions
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index 86190fa5d..205c7286e 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -37,6 +37,7 @@ #include <cstring> #include <QDebug> #include <QMetaMethod> +#include <shiboken.h> #define EMPTY_META_METHOD "0()" @@ -279,7 +280,22 @@ bool PropertyData::operator==(const char* name) const } -DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject) : m_d(new DynamicQMetaObjectPrivate) +DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* base) + : m_d(new DynamicQMetaObjectPrivate) +{ + d.superdata = base; + d.stringdata = 0; + d.data = 0; + d.extradata = 0; + + m_d->m_className = QByteArray(type->tp_name).split('.').last(); + parsePythonType(type); + //TODO : fill type userData + m_d->updateMetaObject(this); +} + +DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject) + : m_d(new DynamicQMetaObjectPrivate) { d.superdata = metaObject; d.stringdata = 0; @@ -420,6 +436,59 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList *prtIndex = index; } +void DynamicQMetaObject::parsePythonType(PyTypeObject* type) +{ + PyObject* attrs = type->tp_dict; + PyObject* key = 0; + PyObject* value = 0; + Py_ssize_t pos = 0; + + typedef std::pair<const char*, PyObject*> PropPair; + QList<PropPair> properties; + + Shiboken::AutoDecRef slotAttrName(PyString_FromString(PYSIDE_SLOT_LIST_ATTR)); + + while (PyDict_Next(attrs, &pos, &key, &value)) { + if (Property::checkType(value)) { + // Leave the properties to be register after signals because they may depend on notify signals + properties << PropPair(PyString_AS_STRING(key), value); + } else if (Signal::checkType(value)) { // Register signals + PySideSignal* data = reinterpret_cast<PySideSignal*>(value); + const char* signalName = PyString_AS_STRING(key); + data->signalName = strdup(signalName); + QByteArray sig; + sig.reserve(128); + for (int i = 0; i < data->signaturesSize; ++i) { + sig = signalName; + sig += '('; + if (data->signatures[i]) + sig += data->signatures[i]; + sig += ')'; + if (d.superdata->indexOfSignal(sig) == -1) + addSignal(sig); + } + } else if (PyFunction_Check(value)) { // Register slots + if (PyObject_HasAttr(value, slotAttrName)) { + PyObject* signatureList = PyObject_GetAttr(value, slotAttrName); + for(Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) { + PyObject* signature = PyList_GET_ITEM(signatureList, i); + QByteArray sig(PyString_AS_STRING(signature)); + //slot the slot type and signature + QList<QByteArray> slotInfo = sig.split(' '); + int index = d.superdata->indexOfSlot(slotInfo[1]); + if (index == -1) + addSlot(slotInfo[1], slotInfo[0]); + } + } + } + } + + // Register properties + foreach (PropPair propPair, properties) + addProperty(propPair.first, propPair.second); + +} + void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject* metaObj) { uint n_methods = m_methods.size(); diff --git a/libpyside/dynamicqmetaobject.h b/libpyside/dynamicqmetaobject.h index d137e3057..f95070c28 100644 --- a/libpyside/dynamicqmetaobject.h +++ b/libpyside/dynamicqmetaobject.h @@ -34,7 +34,8 @@ namespace PySide class DynamicQMetaObject : public QMetaObject { public: - DynamicQMetaObject(const char* className, const QMetaObject* metaObject); + DynamicQMetaObject(const char* className, const QMetaObject* metaObject); //deprecated + DynamicQMetaObject(PyTypeObject* type, const QMetaObject* metaobject); ~DynamicQMetaObject(); @@ -53,6 +54,8 @@ public: private: class DynamicQMetaObjectPrivate; DynamicQMetaObjectPrivate* m_d; + + void parsePythonType(PyTypeObject* type); }; } diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp index 950e2da5f..ea48b1785 100644 --- a/libpyside/pyside.cpp +++ b/libpyside/pyside.cpp @@ -41,6 +41,7 @@ #include <cctype> #include <QStack> #include <QCoreApplication> +#include <QDebug> static QStack<PySide::CleanupFunction> cleanupFunctionList; @@ -125,6 +126,7 @@ static void destructionVisitor(SbkObject* pyObj, void* data) Py_END_ALLOW_THREADS } } + }; void destroyQCoreApplication() @@ -148,9 +150,15 @@ void destroyQCoreApplication() void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base) { - QByteArray typeName = QByteArray(type->super.ht_type.tp_name).split('.').last(); - DynamicQMetaObject* mo = new PySide::DynamicQMetaObject(typeName, base); - Shiboken::ObjectType::setTypeUserData(type, mo, &Shiboken::callCppDestructor<DynamicQMetaObject>); + //create DynamicMetaObject based on python type + DynamicQMetaObject* mo = new PySide::DynamicQMetaObject(reinterpret_cast<PyTypeObject*>(type), base); + Shiboken::ObjectType::setTypeUserData(type, mo, Shiboken::callCppDestructor<DynamicQMetaObject>); + + //initialize staticQMetaObject property + PyObject* pyMetaObject = Shiboken::TypeResolver::get("QMetaObject*")->toPython(&mo); + + PyObject_SetAttrString(reinterpret_cast<PyObject*>(type), "staticMetaObject", pyMetaObject); + Py_DECREF(pyMetaObject); } void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds) @@ -166,10 +174,6 @@ void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds) PyTypeObject* base = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i)); if (PyType_IsSubtype(base, qObjType)) { baseMo = reinterpret_cast<QMetaObject*>(Shiboken::ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType*>(base))); - // If it's a class like QObject, QWidget, etc, use the original QMetaObject instead of the dynamic one - // IMO this if is a bug, however it keeps the current behaviour. - if (!Shiboken::ObjectType::isUserType(base)) - baseMo = const_cast<QMetaObject*>(baseMo->d.superdata); break; } } @@ -178,58 +182,7 @@ void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds) return; } - DynamicQMetaObject* mo = new PySide::DynamicQMetaObject(className.constData(), baseMo); - - Shiboken::ObjectType::setTypeUserData(type, mo, &Shiboken::callCppDestructor<DynamicQMetaObject>); - - PyObject* attrs = PyTuple_GET_ITEM(args, 2); - PyObject* key; - PyObject* value; - Py_ssize_t pos = 0; - - typedef std::pair<const char*, PyObject*> PropPair; - QList<PropPair> properties; - - Shiboken::AutoDecRef slotAttrName(PyString_FromString(PYSIDE_SLOT_LIST_ATTR)); - - while (PyDict_Next(attrs, &pos, &key, &value)) { - if (Property::checkType(value)) { - // Leave the properties to be register after signals because they may depend on notify signals - properties << PropPair(PyString_AS_STRING(key), value); - } else if (Signal::checkType(value)) { // Register signals - PySideSignal* data = reinterpret_cast<PySideSignal*>(value); - const char* signalName = PyString_AS_STRING(key); - data->signalName = strdup(signalName); - QByteArray sig; - sig.reserve(128); - for (int i = 0; i < data->signaturesSize; ++i) { - sig = signalName; - sig += '('; - if (data->signatures[i]) - sig += data->signatures[i]; - sig += ')'; - if (baseMo->indexOfSignal(sig) == -1) - mo->addSignal(sig); - } - } else if (PyFunction_Check(value)) { // Register slots - if (PyObject_HasAttr(value, slotAttrName)) { - PyObject* signatureList = PyObject_GetAttr(value, slotAttrName); - for(Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) { - PyObject* signature = PyList_GET_ITEM(signatureList, i); - QByteArray sig(PyString_AS_STRING(signature)); - //slot the slot type and signature - QList<QByteArray> slotInfo = sig.split(' '); - int index = baseMo->indexOfSlot(slotInfo[1]); - if (index == -1) - mo->addSlot(slotInfo[1], slotInfo[0]); - } - } - } - } - - // Register properties - foreach (PropPair propPair, properties) - mo->addProperty(propPair.first, propPair.second); + initDynamicMetaObject(type, baseMo); } PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* name) |