@@ -431,6 +431,30 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla | |||||
431 | return result; |
|
431 | return result; | |
432 | } |
|
432 | } | |
433 |
|
433 | |||
|
434 | PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) { | |||
|
435 | PyObject* result; | |||
|
436 | ||||
|
437 | PyObject* className = PyString_FromString(enumName); | |||
|
438 | ||||
|
439 | PyObject* baseClasses = PyTuple_New(1); | |||
|
440 | PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type); | |||
|
441 | ||||
|
442 | PyObject* module = PyObject_GetAttrString(parentObject, "__module__"); | |||
|
443 | PyObject* typeDict = PyDict_New(); | |||
|
444 | PyDict_SetItemString(typeDict, "__module__", module); | |||
|
445 | ||||
|
446 | PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict); | |||
|
447 | ||||
|
448 | // create the new int derived type object by calling the core type | |||
|
449 | result = PyObject_Call((PyObject *)&PyType_Type, args, NULL); | |||
|
450 | ||||
|
451 | Py_DECREF(baseClasses); | |||
|
452 | Py_DECREF(typeDict); | |||
|
453 | Py_DECREF(args); | |||
|
454 | Py_DECREF(className); | |||
|
455 | ||||
|
456 | return result; | |||
|
457 | } | |||
434 |
|
458 | |||
435 | PythonQtSignalReceiver* PythonQt::getSignalReceiver(QObject* obj) |
|
459 | PythonQtSignalReceiver* PythonQt::getSignalReceiver(QObject* obj) | |
436 | { |
|
460 | { |
@@ -446,6 +446,9 public: | |||||
446 | //! helper method that creates a PythonQtClassWrapper object |
|
446 | //! helper method that creates a PythonQtClassWrapper object | |
447 | PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL); |
|
447 | PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL); | |
448 |
|
448 | |||
|
449 | //! helper that creates a new int derived class that represents the enum of the given name | |||
|
450 | PyObject* createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject); | |||
|
451 | ||||
449 | //! helper method that creates a PythonQtInstanceWrapper object and registers it in the object map |
|
452 | //! helper method that creates a PythonQtInstanceWrapper object and registers it in the object map | |
450 | PythonQtInstanceWrapper* createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr = NULL); |
|
453 | PythonQtInstanceWrapper* createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr = NULL); | |
451 |
|
454 |
@@ -43,6 +43,8 | |||||
43 | #include "PythonQtMethodInfo.h" |
|
43 | #include "PythonQtMethodInfo.h" | |
44 | #include "PythonQt.h" |
|
44 | #include "PythonQt.h" | |
45 | #include <QMetaMethod> |
|
45 | #include <QMetaMethod> | |
|
46 | #include <QMetaObject> | |||
|
47 | #include <QMetaEnum> | |||
46 |
|
48 | |||
47 | QHash<QByteArray, int> PythonQtMethodInfo::_parameterTypeDict; |
|
49 | QHash<QByteArray, int> PythonQtMethodInfo::_parameterTypeDict; | |
48 |
|
50 | |||
@@ -56,6 +58,7 PythonQtClassInfo::PythonQtClassInfo() { | |||||
56 | _shellSetInstanceWrapperCB = NULL; |
|
58 | _shellSetInstanceWrapperCB = NULL; | |
57 | _metaTypeId = -1; |
|
59 | _metaTypeId = -1; | |
58 | _isQObject = false; |
|
60 | _isQObject = false; | |
|
61 | _enumsCreated = false; | |||
59 | } |
|
62 | } | |
60 |
|
63 | |||
61 | PythonQtClassInfo::~PythonQtClassInfo() |
|
64 | PythonQtClassInfo::~PythonQtClassInfo() | |
@@ -250,13 +253,23 bool PythonQtClassInfo::lookForEnumAndCache(const QMetaObject* meta, const char* | |||||
250 | QMetaEnum e = meta->enumerator(i); |
|
253 | QMetaEnum e = meta->enumerator(i); | |
251 | for (int j=0; j < e.keyCount(); j++) { |
|
254 | for (int j=0; j < e.keyCount(); j++) { | |
252 | if (qstrcmp(e.key(j), memberName)==0) { |
|
255 | if (qstrcmp(e.key(j), memberName)==0) { | |
253 | PythonQtMemberInfo newInfo(e.value(j)); |
|
256 | PyObject* enumType = findEnumWrapper(e.name()); | |
254 | _cachedMembers.insert(memberName, newInfo); |
|
257 | if (enumType) { | |
|
258 | PyObject* args = Py_BuildValue("(i)", e.value(j)); | |||
|
259 | PyObject* enumValue = PyObject_Call(enumType, args, NULL); | |||
|
260 | Py_DECREF(args); | |||
|
261 | PythonQtObjectPtr enumValuePtr; | |||
|
262 | enumValuePtr.setNewRef(enumValue); | |||
|
263 | PythonQtMemberInfo newInfo(enumValuePtr); | |||
|
264 | _cachedMembers.insert(memberName, newInfo); | |||
255 | #ifdef PYTHONQT_DEBUG |
|
265 | #ifdef PYTHONQT_DEBUG | |
256 | std::cout << "caching enum " << memberName << " on " << meta->className() << std::endl; |
|
266 | std::cout << "caching enum " << memberName << " on " << meta->className() << std::endl; | |
257 | #endif |
|
267 | #endif | |
258 | found = true; |
|
268 | found = true; | |
259 | break; |
|
269 | break; | |
|
270 | } else { | |||
|
271 | std::cout << "enum " << e.name() << " not found on " << className() << std::endl; | |||
|
272 | } | |||
260 | } |
|
273 | } | |
261 | } |
|
274 | } | |
262 | } |
|
275 | } | |
@@ -295,6 +308,15 PythonQtMemberInfo PythonQtClassInfo::member(const char* memberName) | |||||
295 | } |
|
308 | } | |
296 | } |
|
309 | } | |
297 | if (!found) { |
|
310 | if (!found) { | |
|
311 | PyObject* p = findEnumWrapper(memberName); | |||
|
312 | if (p) { | |||
|
313 | info._type = PythonQtMemberInfo::EnumWrapper; | |||
|
314 | info._enumWrapper = p; | |||
|
315 | _cachedMembers.insert(memberName, info); | |||
|
316 | found = true; | |||
|
317 | } | |||
|
318 | } | |||
|
319 | if (!found) { | |||
298 | // we store a NotFound member, so that we get a quick result for non existing members (e.g. operator_equal lookup) |
|
320 | // we store a NotFound member, so that we get a quick result for non existing members (e.g. operator_equal lookup) | |
299 | info._type = PythonQtMemberInfo::NotFound; |
|
321 | info._type = PythonQtMemberInfo::NotFound; | |
300 | _cachedMembers.insert(memberName, info); |
|
322 | _cachedMembers.insert(memberName, info); | |
@@ -470,6 +492,7 QStringList PythonQtClassInfo::memberList(bool metaOnly) | |||||
470 | foreach(const QMetaObject* meta, enumMetaObjects) { |
|
492 | foreach(const QMetaObject* meta, enumMetaObjects) { | |
471 | for (int i = 0; i<meta->enumeratorCount(); i++) { |
|
493 | for (int i = 0; i<meta->enumeratorCount(); i++) { | |
472 | QMetaEnum e = meta->enumerator(i); |
|
494 | QMetaEnum e = meta->enumerator(i); | |
|
495 | l << e.name(); | |||
473 | for (int j=0; j < e.keyCount(); j++) { |
|
496 | for (int j=0; j < e.keyCount(); j++) { | |
474 | l << QString(e.key(j)); |
|
497 | l << QString(e.key(j)); | |
475 | } |
|
498 | } | |
@@ -661,6 +684,9 QObject* PythonQtClassInfo::decorator() | |||||
661 | PythonQt::priv()->addDecorators(_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator); |
|
684 | PythonQt::priv()->addDecorators(_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator); | |
662 | } |
|
685 | } | |
663 | } |
|
686 | } | |
|
687 | if (!_enumsCreated) { | |||
|
688 | createEnumWrappers(); | |||
|
689 | } | |||
664 | return _decoratorProvider; |
|
690 | return _decoratorProvider; | |
665 | } |
|
691 | } | |
666 |
|
692 | |||
@@ -768,3 +794,43 bool PythonQtClassInfo::hasEnum(const QByteArray& name) | |||||
768 | return found; |
|
794 | return found; | |
769 | } |
|
795 | } | |
770 |
|
796 | |||
|
797 | void PythonQtClassInfo::createEnumWrappers(const QMetaObject* meta) | |||
|
798 | { | |||
|
799 | for (int i = meta->enumeratorOffset();i<meta->enumeratorCount();i++) { | |||
|
800 | QMetaEnum e = meta->enumerator(i); | |||
|
801 | PythonQtObjectPtr p; | |||
|
802 | p.setNewRef(PythonQt::priv()->createNewPythonQtEnumWrapper(e.name(), _pythonQtClassWrapper)); | |||
|
803 | _enumWrappers.append(p); | |||
|
804 | } | |||
|
805 | } | |||
|
806 | ||||
|
807 | void PythonQtClassInfo::createEnumWrappers() | |||
|
808 | { | |||
|
809 | if (!_enumsCreated) { | |||
|
810 | _enumsCreated = true; | |||
|
811 | if (_meta) { | |||
|
812 | createEnumWrappers(_meta); | |||
|
813 | } | |||
|
814 | if (decorator()) { | |||
|
815 | createEnumWrappers(decorator()->metaObject()); | |||
|
816 | } | |||
|
817 | foreach(const ParentClassInfo& info, _parentClasses) { | |||
|
818 | info._parent->createEnumWrappers(); | |||
|
819 | } | |||
|
820 | } | |||
|
821 | } | |||
|
822 | ||||
|
823 | PyObject* PythonQtClassInfo::findEnumWrapper(const char* name) { | |||
|
824 | foreach(const PythonQtObjectPtr& p, _enumWrappers) { | |||
|
825 | const char* className = ((PyTypeObject*)p.object())->tp_name; | |||
|
826 | if (qstrcmp(className, name)==0) { | |||
|
827 | return p.object(); | |||
|
828 | } | |||
|
829 | } | |||
|
830 | foreach(const ParentClassInfo& info, _parentClasses) { | |||
|
831 | PyObject* p = info._parent->findEnumWrapper(name); | |||
|
832 | if (p) return p; | |||
|
833 | } | |||
|
834 | return NULL; | |||
|
835 | } | |||
|
836 |
@@ -44,35 +44,38 class PythonQtSlotInfo; | |||||
44 |
|
44 | |||
45 | struct PythonQtMemberInfo { |
|
45 | struct PythonQtMemberInfo { | |
46 | enum Type { |
|
46 | enum Type { | |
47 | Invalid, Slot, EnumValue, Property, NotFound |
|
47 | Invalid, Slot, EnumValue, EnumWrapper, Property, NotFound | |
48 | }; |
|
48 | }; | |
49 |
|
49 | |||
50 | PythonQtMemberInfo():_type(Invalid),_slot(NULL),_enumValue(0) { } |
|
50 | PythonQtMemberInfo():_type(Invalid),_slot(NULL),_enumWrapper(NULL),_enumValue(0) { } | |
51 |
|
51 | |||
52 | PythonQtMemberInfo(PythonQtSlotInfo* info) { |
|
52 | PythonQtMemberInfo(PythonQtSlotInfo* info) { | |
53 | _type = Slot; |
|
53 | _type = Slot; | |
54 | _slot = info; |
|
54 | _slot = info; | |
55 |
_enumValue = |
|
55 | _enumValue = NULL; | |
56 | } |
|
56 | } | |
57 |
|
57 | |||
58 |
PythonQtMemberInfo( |
|
58 | PythonQtMemberInfo(const PythonQtObjectPtr& enumValue) { | |
59 | _type = EnumValue; |
|
59 | _type = EnumValue; | |
60 | _slot = NULL; |
|
60 | _slot = NULL; | |
61 | _enumValue = enumValue; |
|
61 | _enumValue = enumValue; | |
|
62 | _enumWrapper = NULL; | |||
62 | } |
|
63 | } | |
63 |
|
64 | |||
64 | PythonQtMemberInfo(const QMetaProperty& prop) { |
|
65 | PythonQtMemberInfo(const QMetaProperty& prop) { | |
65 | _type = Property; |
|
66 | _type = Property; | |
66 | _slot = NULL; |
|
67 | _slot = NULL; | |
67 |
_enumValue = |
|
68 | _enumValue = NULL; | |
68 | _property = prop; |
|
69 | _property = prop; | |
|
70 | _enumWrapper = NULL; | |||
69 | } |
|
71 | } | |
70 |
|
72 | |||
71 | Type _type; |
|
73 | Type _type; | |
72 |
|
74 | |||
73 | // TODO: this could be a union... |
|
75 | // TODO: this could be a union... | |
74 | PythonQtSlotInfo* _slot; |
|
76 | PythonQtSlotInfo* _slot; | |
75 | unsigned int _enumValue; |
|
77 | PyObject* _enumWrapper; | |
|
78 | PythonQtObjectPtr _enumValue; | |||
76 | QMetaProperty _property; |
|
79 | QMetaProperty _property; | |
77 | }; |
|
80 | }; | |
78 |
|
81 | |||
@@ -194,7 +197,11 public: | |||||
194 | //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum |
|
197 | //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum | |
195 | static bool hasEnum(const QByteArray& name, PythonQtClassInfo* localScope); |
|
198 | static bool hasEnum(const QByteArray& name, PythonQtClassInfo* localScope); | |
196 |
|
199 | |||
197 |
private: |
|
200 | private: | |
|
201 | void createEnumWrappers(); | |||
|
202 | void createEnumWrappers(const QMetaObject* meta); | |||
|
203 | PyObject* findEnumWrapper(const char* name); | |||
|
204 | ||||
198 | //! checks if the enum is part of this class (without any leading scope!) |
|
205 | //! checks if the enum is part of this class (without any leading scope!) | |
199 | bool hasEnum(const QByteArray& name); |
|
206 | bool hasEnum(const QByteArray& name); | |
200 |
|
207 | |||
@@ -223,6 +230,8 private: | |||||
223 | PythonQtSlotInfo* _destructor; |
|
230 | PythonQtSlotInfo* _destructor; | |
224 | QList<PythonQtSlotInfo*> _decoratorSlots; |
|
231 | QList<PythonQtSlotInfo*> _decoratorSlots; | |
225 |
|
232 | |||
|
233 | QList<PythonQtObjectPtr> _enumWrappers; | |||
|
234 | ||||
226 | const QMetaObject* _meta; |
|
235 | const QMetaObject* _meta; | |
227 |
|
236 | |||
228 | QByteArray _wrappedClassName; |
|
237 | QByteArray _wrappedClassName; | |
@@ -240,6 +249,7 private: | |||||
240 | int _metaTypeId; |
|
249 | int _metaTypeId; | |
241 |
|
250 | |||
242 | bool _isQObject; |
|
251 | bool _isQObject; | |
|
252 | bool _enumsCreated; | |||
243 |
|
253 | |||
244 | }; |
|
254 | }; | |
245 |
|
255 |
@@ -183,9 +183,14 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) | |||||
183 | if (wrapper->classInfo()) { |
|
183 | if (wrapper->classInfo()) { | |
184 | PythonQtMemberInfo member = wrapper->classInfo()->member(attributeName); |
|
184 | PythonQtMemberInfo member = wrapper->classInfo()->member(attributeName); | |
185 | if (member._type == PythonQtMemberInfo::EnumValue) { |
|
185 | if (member._type == PythonQtMemberInfo::EnumValue) { | |
186 |
|
|
186 | PyObject* enumValue = member._enumValue; | |
187 | } else |
|
187 | Py_INCREF(enumValue); | |
188 | if (member._type == PythonQtMemberInfo::Slot) { |
|
188 | return enumValue; | |
|
189 | } else if (member._type == PythonQtMemberInfo::EnumWrapper) { | |||
|
190 | PyObject* enumWrapper = member._enumWrapper; | |||
|
191 | Py_INCREF(enumWrapper); | |||
|
192 | return enumWrapper; | |||
|
193 | } else if (member._type == PythonQtMemberInfo::Slot) { | |||
189 | // we return all slots, even the instance slots, since they are callable as unbound slots with self argument |
|
194 | // we return all slots, even the instance slots, since they are callable as unbound slots with self argument | |
190 | return PythonQtSlotFunction_New(member._slot, obj, NULL); |
|
195 | return PythonQtSlotFunction_New(member._slot, obj, NULL); | |
191 | } |
|
196 | } |
@@ -611,7 +611,10 int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) { | |||||
611 | if (val->ob_type == &PyInt_Type) { |
|
611 | if (val->ob_type == &PyInt_Type) { | |
612 | d = PyInt_AS_LONG(val); |
|
612 | d = PyInt_AS_LONG(val); | |
613 | } else if (!strict) { |
|
613 | } else if (!strict) { | |
614 | if (val->ob_type == &PyFloat_Type) { |
|
614 | if (PyObject_TypeCheck(val, &PyInt_Type)) { | |
|
615 | // support for derived int classes, e.g. for our enums | |||
|
616 | d = PyInt_AS_LONG(val); | |||
|
617 | } else if (val->ob_type == &PyFloat_Type) { | |||
615 | d = floor(PyFloat_AS_DOUBLE(val)); |
|
618 | d = floor(PyFloat_AS_DOUBLE(val)); | |
616 | } else if (val->ob_type == &PyLong_Type) { |
|
619 | } else if (val->ob_type == &PyLong_Type) { | |
617 | // handle error on overflow! |
|
620 | // handle error on overflow! | |
@@ -632,7 +635,7 int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) { | |||||
632 | qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) { |
|
635 | qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) { | |
633 | qint64 d = 0; |
|
636 | qint64 d = 0; | |
634 | ok = true; |
|
637 | ok = true; | |
635 | if (val->ob_type == &PyInt_Type) { |
|
638 | if (PyObject_TypeCheck(val, &PyInt_Type)) { | |
636 | d = PyInt_AS_LONG(val); |
|
639 | d = PyInt_AS_LONG(val); | |
637 | } else if (val->ob_type == &PyLong_Type) { |
|
640 | } else if (val->ob_type == &PyLong_Type) { | |
638 | d = PyLong_AsLongLong(val); |
|
641 | d = PyLong_AsLongLong(val); | |
@@ -655,7 +658,7 qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) { | |||||
655 | quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) { |
|
658 | quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) { | |
656 | quint64 d = 0; |
|
659 | quint64 d = 0; | |
657 | ok = true; |
|
660 | ok = true; | |
658 | if (val->ob_type == &PyInt_Type) { |
|
661 | if (PyObject_TypeCheck(val, &PyInt_Type)) { | |
659 | d = PyInt_AS_LONG(val); |
|
662 | d = PyInt_AS_LONG(val); | |
660 | } else if (val->ob_type == &PyLong_Type) { |
|
663 | } else if (val->ob_type == &PyLong_Type) { | |
661 | d = PyLong_AsLongLong(val); |
|
664 | d = PyLong_AsLongLong(val); | |
@@ -681,7 +684,7 double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) { | |||||
681 | if (val->ob_type == &PyFloat_Type) { |
|
684 | if (val->ob_type == &PyFloat_Type) { | |
682 | d = PyFloat_AS_DOUBLE(val); |
|
685 | d = PyFloat_AS_DOUBLE(val); | |
683 | } else if (!strict) { |
|
686 | } else if (!strict) { | |
684 |
if (val |
|
687 | if (PyObject_TypeCheck(val, &PyInt_Type)) { | |
685 | d = PyInt_AS_LONG(val); |
|
688 | d = PyInt_AS_LONG(val); | |
686 | } else if (val->ob_type == &PyLong_Type) { |
|
689 | } else if (val->ob_type == &PyLong_Type) { | |
687 | d = PyLong_AsLong(val); |
|
690 | d = PyLong_AsLong(val); | |
@@ -707,7 +710,7 QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type) | |||||
707 | // no special type requested |
|
710 | // no special type requested | |
708 | if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) { |
|
711 | if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) { | |
709 | type = QVariant::String; |
|
712 | type = QVariant::String; | |
710 |
} else if (val |
|
713 | } else if (PyObject_TypeCheck(val, &PyInt_Type)) { | |
711 | type = QVariant::Int; |
|
714 | type = QVariant::Int; | |
712 | } else if (val->ob_type==&PyLong_Type) { |
|
715 | } else if (val->ob_type==&PyLong_Type) { | |
713 | type = QVariant::LongLong; |
|
716 | type = QVariant::LongLong; |
@@ -277,7 +277,14 static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) | |||||
277 | return PythonQtSlotFunction_New(member._slot, obj, NULL); |
|
277 | return PythonQtSlotFunction_New(member._slot, obj, NULL); | |
278 | break; |
|
278 | break; | |
279 | case PythonQtMemberInfo::EnumValue: |
|
279 | case PythonQtMemberInfo::EnumValue: | |
280 | return PyInt_FromLong(member._enumValue); |
|
280 | PyObject* enumValue = member._enumValue; | |
|
281 | Py_INCREF(enumValue); | |||
|
282 | return enumValue; | |||
|
283 | break; | |||
|
284 | case PythonQtMemberInfo::EnumWrapper: | |||
|
285 | PyObject* enumWrapper = member._enumWrapper; | |||
|
286 | Py_INCREF(enumWrapper); | |||
|
287 | return enumWrapper; | |||
281 | break; |
|
288 | break; | |
282 | default: |
|
289 | default: | |
283 | // is an invalid type, go on |
|
290 | // is an invalid type, go on | |
@@ -353,6 +360,8 static int PythonQtInstanceWrapper_setattro(PyObject *obj,PyObject *name,PyObjec | |||||
353 | error = QString("Slot '") + attributeName + "' can not be overwritten on " + obj->ob_type->tp_name + " object"; |
|
360 | error = QString("Slot '") + attributeName + "' can not be overwritten on " + obj->ob_type->tp_name + " object"; | |
354 | } else if (member._type == PythonQtMemberInfo::EnumValue) { |
|
361 | } else if (member._type == PythonQtMemberInfo::EnumValue) { | |
355 | error = QString("EnumValue '") + attributeName + "' can not be overwritten on " + obj->ob_type->tp_name + " object"; |
|
362 | error = QString("EnumValue '") + attributeName + "' can not be overwritten on " + obj->ob_type->tp_name + " object"; | |
|
363 | } else if (member._type == PythonQtMemberInfo::EnumWrapper) { | |||
|
364 | error = QString("Enum '") + attributeName + "' can not be overwritten on " + obj->ob_type->tp_name + " object"; | |||
356 | } else if (member._type == PythonQtMemberInfo::NotFound) { |
|
365 | } else if (member._type == PythonQtMemberInfo::NotFound) { | |
357 | // if we are a derived python class, we allow setting attributes. |
|
366 | // if we are a derived python class, we allow setting attributes. | |
358 | // if we are a direct CPP wrapper, we do NOT allow it, since |
|
367 | // if we are a direct CPP wrapper, we do NOT allow it, since |
General Comments 0
You need to be logged in to leave comments.
Login now