@@ -391,6 +391,15 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name) | |||||
391 | return (PyObject*)wrap; |
|
391 | return (PyObject*)wrap; | |
392 | } |
|
392 | } | |
393 |
|
393 | |||
|
394 | // not a known QObject, try to wrap via foreign wrapper factories | |||
|
395 | PyObject* foreignWrapper = NULL; | |||
|
396 | for (int i=0; i<_foreignWrapperFactories.size(); i++) { | |||
|
397 | foreignWrapper = _foreignWrapperFactories.at(i)->wrap(name, ptr); | |||
|
398 | if (foreignWrapper) { | |||
|
399 | return foreignWrapper; | |||
|
400 | } | |||
|
401 | } | |||
|
402 | ||||
394 | // not a known QObject, so try our wrapper factory: |
|
403 | // not a known QObject, so try our wrapper factory: | |
395 | QObject* wrapper = NULL; |
|
404 | QObject* wrapper = NULL; | |
396 | for (int i=0; i<_cppWrapperFactories.size(); i++) { |
|
405 | for (int i=0; i<_cppWrapperFactories.size(); i++) { | |
@@ -415,8 +424,6 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name) | |||||
415 | info->setMetaObject(wrapper->metaObject()); |
|
424 | info->setMetaObject(wrapper->metaObject()); | |
416 | } |
|
425 | } | |
417 |
|
426 | |||
418 | // TODO XXX: delegate wrapping via CB here (pass name and ptr) |
|
|||
419 |
|
||||
420 | wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr); |
|
427 | wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr); | |
421 | // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1()); |
|
428 | // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1()); | |
422 | } else { |
|
429 | } else { | |
@@ -965,6 +972,11 void PythonQt::addWrapperFactory(PythonQtCppWrapperFactory* factory) | |||||
965 | _p->_cppWrapperFactories.append(factory); |
|
972 | _p->_cppWrapperFactories.append(factory); | |
966 | } |
|
973 | } | |
967 |
|
974 | |||
|
975 | void PythonQt::addWrapperFactory( PythonQtForeignWrapperFactory* factory ) | |||
|
976 | { | |||
|
977 | _p->_foreignWrapperFactories.append(factory); | |||
|
978 | } | |||
|
979 | ||||
968 | //--------------------------------------------------------------------------------------------------- |
|
980 | //--------------------------------------------------------------------------------------------------- | |
969 | PythonQtPrivate::PythonQtPrivate() |
|
981 | PythonQtPrivate::PythonQtPrivate() | |
970 | { |
|
982 | { | |
@@ -1316,3 +1328,15 PythonQtObjectPtr PythonQtPrivate::createModule(const QString& name, PyObject* p | |||||
1316 | } |
|
1328 | } | |
1317 | return result; |
|
1329 | return result; | |
1318 | } |
|
1330 | } | |
|
1331 | ||||
|
1332 | void* PythonQtPrivate::unwrapForeignWrapper( const QByteArray& classname, PyObject* obj ) | |||
|
1333 | { | |||
|
1334 | void* foreignObject = NULL; | |||
|
1335 | for (int i=0; i<_foreignWrapperFactories.size(); i++) { | |||
|
1336 | foreignObject = _foreignWrapperFactories.at(i)->unwrap(classname, obj); | |||
|
1337 | if (foreignObject) { | |||
|
1338 | return foreignObject; | |||
|
1339 | } | |||
|
1340 | } | |||
|
1341 | return NULL; | |||
|
1342 | } No newline at end of file |
@@ -64,6 +64,7 class PythonQtMethodInfo; | |||||
64 | class PythonQtSignalReceiver; |
|
64 | class PythonQtSignalReceiver; | |
65 | class PythonQtImportFileInterface; |
|
65 | class PythonQtImportFileInterface; | |
66 | class PythonQtCppWrapperFactory; |
|
66 | class PythonQtCppWrapperFactory; | |
|
67 | class PythonQtForeignWrapperFactory; | |||
67 | class PythonQtQFileImporter; |
|
68 | class PythonQtQFileImporter; | |
68 |
|
69 | |||
69 | typedef void PythonQtQObjectWrappedCB(QObject* object); |
|
70 | typedef void PythonQtQObjectWrappedCB(QObject* object); | |
@@ -409,6 +410,9 public: | |||||
409 | //! add the given factory to PythonQt (ownership stays with caller) |
|
410 | //! add the given factory to PythonQt (ownership stays with caller) | |
410 | void addWrapperFactory(PythonQtCppWrapperFactory* factory); |
|
411 | void addWrapperFactory(PythonQtCppWrapperFactory* factory); | |
411 |
|
412 | |||
|
413 | //! add the given factory to PythonQt (ownership stays with caller) | |||
|
414 | void addWrapperFactory(PythonQtForeignWrapperFactory* factory); | |||
|
415 | ||||
412 | //@} |
|
416 | //@} | |
413 |
|
417 | |||
414 | //--------------------------------------------------------------------------- |
|
418 | //--------------------------------------------------------------------------- | |
@@ -538,6 +542,9 public: | |||||
538 | //! remove the wrapper ptr again |
|
542 | //! remove the wrapper ptr again | |
539 | void removeWrapperPointer(void* obj); |
|
543 | void removeWrapperPointer(void* obj); | |
540 |
|
544 | |||
|
545 | //! try to unwrap the given object to a C++ pointer using the foreign wrapper factories | |||
|
546 | void* unwrapForeignWrapper(const QByteArray& classname, PyObject* obj); | |||
|
547 | ||||
541 | //! add parent class relation |
|
548 | //! add parent class relation | |
542 | bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset); |
|
549 | bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset); | |
543 |
|
550 | |||
@@ -660,6 +667,8 private: | |||||
660 | //! the cpp object wrapper factories |
|
667 | //! the cpp object wrapper factories | |
661 | QList<PythonQtCppWrapperFactory*> _cppWrapperFactories; |
|
668 | QList<PythonQtCppWrapperFactory*> _cppWrapperFactories; | |
662 |
|
669 | |||
|
670 | QList<PythonQtForeignWrapperFactory*> _foreignWrapperFactories; | |||
|
671 | ||||
663 | QHash<QByteArray, PyObject*> _packages; |
|
672 | QHash<QByteArray, PyObject*> _packages; | |
664 |
|
673 | |||
665 | PythonQtClassInfo* _currentClassInfoForClassWrapperCreation; |
|
674 | PythonQtClassInfo* _currentClassInfoForClassWrapperCreation; |
@@ -386,19 +386,22 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i | |||||
386 | } else if (info.name == "PyObject") { |
|
386 | } else if (info.name == "PyObject") { | |
387 | // handle low level PyObject directly |
|
387 | // handle low level PyObject directly | |
388 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr); |
|
388 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr); | |
389 | } |
|
389 | } else if (obj == Py_None) { | |
390 | // TODO XXX: pass obj and name and add when it returns a pointer |
|
|||
391 | else if (obj == Py_None) { |
|
|||
392 | // None is treated as a NULL ptr |
|
390 | // None is treated as a NULL ptr | |
393 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr); |
|
391 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr); | |
394 | } else { |
|
392 | } else { | |
395 | // if we are not strict, we try if we are passed a 0 integer |
|
393 | void* foreignWrapper = PythonQt::priv()->unwrapForeignWrapper(info.name, obj); | |
396 |
if ( |
|
394 | if (foreignWrapper) { | |
397 | bool ok; |
|
395 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, foreignWrapper, ptr); | |
398 | int value = PyObjGetInt(obj, true, ok); |
|
396 | } else { | |
399 | if (ok && value==0) { |
|
397 | // if we are not strict, we try if we are passed a 0 integer | |
400 | // TODOXXX is this wise? or should it be expected from the programmer to use None? |
|
398 | if (!strict) { | |
401 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr); |
|
399 | bool ok; | |
|
400 | int value = PyObjGetInt(obj, true, ok); | |||
|
401 | if (ok && value==0) { | |||
|
402 | // TODOXXX is this wise? or should it be expected from the programmer to use None? | |||
|
403 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr); | |||
|
404 | } | |||
402 | } |
|
405 | } | |
403 | } |
|
406 | } | |
404 | } |
|
407 | } |
@@ -54,7 +54,25 public: | |||||
54 | virtual ~PythonQtCppWrapperFactory() {}; |
|
54 | virtual ~PythonQtCppWrapperFactory() {}; | |
55 |
|
55 | |||
56 | //! create a wrapper for the given object |
|
56 | //! create a wrapper for the given object | |
57 | virtual QObject* create(const QByteArray& name, void *ptr) = 0; |
|
57 | virtual QObject* create(const QByteArray& classname, void *ptr) = 0; | |
|
58 | ||||
|
59 | }; | |||
|
60 | ||||
|
61 | //! Factory interface for C++ classes that can be mapped directly from/to | |||
|
62 | //! Python with other means than PythonQt/QObjects. | |||
|
63 | class PYTHONQT_EXPORT PythonQtForeignWrapperFactory | |||
|
64 | { | |||
|
65 | public: | |||
|
66 | PythonQtForeignWrapperFactory() {}; | |||
|
67 | virtual ~PythonQtForeignWrapperFactory() {}; | |||
|
68 | ||||
|
69 | //! create a Python object (with new reference count), wrapping the given \p ptr as class of type \p classname | |||
|
70 | //! Return NULL (and not Py_None) if the object could not be wrapped. | |||
|
71 | virtual PyObject* wrap(const QByteArray& classname, void *ptr) = 0; | |||
|
72 | ||||
|
73 | //! unwrap the given object to a C++ object of type \p classname if possible | |||
|
74 | //! Return NULL otherwise. | |||
|
75 | virtual void* unwrap(const QByteArray& classname, PyObject* object) = 0; | |||
58 |
|
76 | |||
59 | }; |
|
77 | }; | |
60 |
|
78 |
General Comments 0
You need to be logged in to leave comments.
Login now