##// END OF EJS Templates
added initial version of foreign wrappers, needs testing...
florianlink -
r167:2184742f9ca8
parent child
Show More
@@ -391,6 +391,15 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
391 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 403 // not a known QObject, so try our wrapper factory:
395 404 QObject* wrapper = NULL;
396 405 for (int i=0; i<_cppWrapperFactories.size(); i++) {
@@ -415,8 +424,6 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
415 424 info->setMetaObject(wrapper->metaObject());
416 425 }
417 426
418 // TODO XXX: delegate wrapping via CB here (pass name and ptr)
419
420 427 wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
421 428 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
422 429 } else {
@@ -965,6 +972,11 void PythonQt::addWrapperFactory(PythonQtCppWrapperFactory* factory)
965 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 981 PythonQtPrivate::PythonQtPrivate()
970 982 {
@@ -1316,3 +1328,15 PythonQtObjectPtr PythonQtPrivate::createModule(const QString& name, PyObject* p
1316 1328 }
1317 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 64 class PythonQtSignalReceiver;
65 65 class PythonQtImportFileInterface;
66 66 class PythonQtCppWrapperFactory;
67 class PythonQtForeignWrapperFactory;
67 68 class PythonQtQFileImporter;
68 69
69 70 typedef void PythonQtQObjectWrappedCB(QObject* object);
@@ -409,6 +410,9 public:
409 410 //! add the given factory to PythonQt (ownership stays with caller)
410 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 542 //! remove the wrapper ptr again
539 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 548 //! add parent class relation
542 549 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset);
543 550
@@ -660,6 +667,8 private:
660 667 //! the cpp object wrapper factories
661 668 QList<PythonQtCppWrapperFactory*> _cppWrapperFactories;
662 669
670 QList<PythonQtForeignWrapperFactory*> _foreignWrapperFactories;
671
663 672 QHash<QByteArray, PyObject*> _packages;
664 673
665 674 PythonQtClassInfo* _currentClassInfoForClassWrapperCreation;
@@ -386,19 +386,22 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
386 386 } else if (info.name == "PyObject") {
387 387 // handle low level PyObject directly
388 388 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
389 }
390 // TODO XXX: pass obj and name and add when it returns a pointer
391 else if (obj == Py_None) {
389 } else if (obj == Py_None) {
392 390 // None is treated as a NULL ptr
393 391 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
394 392 } else {
395 // if we are not strict, we try if we are passed a 0 integer
396 if (!strict) {
397 bool ok;
398 int value = PyObjGetInt(obj, true, ok);
399 if (ok && value==0) {
400 // TODOXXX is this wise? or should it be expected from the programmer to use None?
401 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
393 void* foreignWrapper = PythonQt::priv()->unwrapForeignWrapper(info.name, obj);
394 if (foreignWrapper) {
395 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, foreignWrapper, ptr);
396 } else {
397 // if we are not strict, we try if we are passed a 0 integer
398 if (!strict) {
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 54 virtual ~PythonQtCppWrapperFactory() {};
55 55
56 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