Implemented staticMetaObject property for QObjects.
This commit is contained in:
parent
f1a737a220
commit
c9e2c1ad8a
4 changed files with 87 additions and 62 deletions
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue