improved enum generation for decorators · iCodeIN/pythonqt@f3bcda8 · GitHub
Skip to content

Commit f3bcda8

Browse files
committed
improved enum generation for decorators
improved sequence conversion callback added support for inheritance chain of Python classes when deriving from a Qt wrapper
1 parent cd4761f commit f3bcda8

7 files changed

Lines changed: 69 additions & 22 deletions

src/PythonQt.cpp

Lines changed: 19 additions & 2 deletions

src/PythonQt.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,11 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject {
742742
//! get the dynamic meta object for the given wrapper. It will contain the signals/slots that have been added in Python
743743
const QMetaObject* getDynamicMetaObject(PythonQtInstanceWrapper* wrapper, const QMetaObject* prototypeMetaObject);
744744

745-
void buildDynamicMetaObject(PythonQtClassWrapper* type, const QMetaObject* prototypeMetaObject);
745+
//! recursively creates the dynamic meta object chain down to the Qt class wrapper.
746+
const QMetaObject* setupDynamicMetaObjectChain(PythonQtClassWrapper* type, const QMetaObject* prototypeMetaObject);
747+
748+
//! builds and returns the dynamic meta object for the given type, derived from prototypeMetaObject.
749+
const QMetaObject* buildDynamicMetaObject(PythonQtClassWrapper* type, const QMetaObject* prototypeMetaObject);
746750

747751
//! redirected from shell classes, tries to call the given meta call on the Python wrapper.
748752
int handleMetaCall(QObject* object, PythonQtInstanceWrapper* wrapper, QMetaObject::Call call, int id, void** args);

src/PythonQtClassInfo.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -738,14 +738,14 @@ QObject* PythonQtClassInfo::decorator()
738738
_decoratorProvider->setParent(PythonQt::priv());
739739
// setup enums early, since they might be needed by the constructor decorators:
740740
if (!_enumsCreated) {
741-
createEnumWrappers();
741+
createEnumWrappers(_decoratorProvider);
742742
}
743743
PythonQt::priv()->addDecorators(_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator);
744744
}
745745
}
746746
// check if enums need to be created and create them if they are not yet created
747747
if (!_enumsCreated) {
748-
createEnumWrappers();
748+
createEnumWrappers(_decoratorProvider);
749749
}
750750
return _decoratorProvider;
751751
}
@@ -857,26 +857,30 @@ void PythonQtClassInfo::createEnumWrappers(const QMetaObject* meta)
857857
}
858858
}
859859

860-
void PythonQtClassInfo::createEnumWrappers()
860+
void PythonQtClassInfo::createEnumWrappers(const QObject* decoratorProvider)
861861
{
862862
if (!_enumsCreated) {
863863
_enumsCreated = true;
864864
if (_meta) {
865865
createEnumWrappers(_meta);
866866
}
867-
if (decorator()) {
868-
createEnumWrappers(decorator()->metaObject());
867+
if (decoratorProvider) {
868+
createEnumWrappers(decoratorProvider->metaObject());
869869
}
870870
Q_FOREACH(const ParentClassInfo& info, _parentClasses) {
871-
info._parent->createEnumWrappers();
871+
// trigger decorator() instead of createEnumWrappers(),
872+
// which will then call createEnumWrappers().
873+
info._parent->decorator();
872874
}
873875
}
874876
}
875877

876878
PyObject* PythonQtClassInfo::findEnumWrapper(const char* name) {
877879
// force enum creation
878880
if (!_enumsCreated) {
879-
createEnumWrappers();
881+
// trigger decorator() instead of createEnumWrappers(),
882+
// which will then call createEnumWrappers().
883+
decorator();
880884
}
881885
Q_FOREACH(const PythonQtObjectPtr& p, _enumWrappers) {
882886
const char* className = ((PyTypeObject*)p.object())->tp_name;

src/PythonQtClassInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ class PYTHONQT_EXPORT PythonQtClassInfo {
239239
private:
240240
void updateRefCountingCBs();
241241

242-
void createEnumWrappers();
242+
void createEnumWrappers(const QObject* decoratorProvider);
243243
void createEnumWrappers(const QMetaObject* meta);
244244
PyObject* findEnumWrapper(const char* name);
245245

src/PythonQtClassWrapper.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,17 @@ static int PythonQtClassWrapper_init(PythonQtClassWrapper* self, PyObject* args,
366366

367367
// take the class info from the superType
368368
self->_classInfo = ((PythonQtClassWrapper*)superType)->classInfo();
369-
370369
self->_dynamicClassInfo = new PythonQtDynamicClassInfo();
370+
371+
// take the class info from the superType and fill the whole chain
372+
PyTypeObject* typeChain = (PyTypeObject *)self;
373+
while (typeChain && Py_TYPE(typeChain) != &PythonQtClassWrapper_Type) {
374+
375+
((PythonQtClassWrapper*)typeChain)->_classInfo = ((PythonQtClassWrapper*)superType)->classInfo();
376+
((PythonQtClassWrapper*)typeChain)->_dynamicClassInfo = new PythonQtDynamicClassInfo();
377+
378+
typeChain = typeChain->tp_base;
379+
}
371380
}
372381

373382
return 0;

src/PythonQtConversion.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,8 +1153,11 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
11531153
pythonToMapVariant<QVariantHash>(val, v);
11541154
break;
11551155
case QVariant::List:
1156-
if (PySequence_Check(val)) {
1157-
if (_pythonSequenceToQVariantListCB) {
1156+
{
1157+
bool isListOrTuple = PyList_Check(val) || PyTuple_Check(val);
1158+
if (isListOrTuple || PySequence_Check(val)) {
1159+
if (!isListOrTuple && _pythonSequenceToQVariantListCB) {
1160+
// Only call this if we don't have a tuple or list.
11581161
QVariant result = (*_pythonSequenceToQVariantListCB)(val);
11591162
if (result.isValid()) {
11601163
return result;
@@ -1165,14 +1168,15 @@ QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
11651168
// only get items if size is valid (>= 0)
11661169
QVariantList list;
11671170
PyObject* value;
1168-
for (int i = 0;i<count;i++) {
1169-
value = PySequence_GetItem(val,i);
1171+
for (int i = 0; i < count; i++) {
1172+
value = PySequence_GetItem(val, i);
11701173
list.append(PyObjToQVariant(value, -1));
11711174
Py_XDECREF(value);
11721175
}
11731176
v = list;
11741177
}
11751178
}
1179+
}
11761180
break;
11771181
case QVariant::StringList:
11781182
{

src/PythonQtInstanceWrapper.cpp

Lines changed: 15 additions & 6 deletions

0 commit comments

Comments
 (0)