##// END OF EJS Templates
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
florianlink -
r109:7064022fb8cf
parent child
Show More
@@ -56,14 +56,13
56 PythonQt* PythonQt::_self = NULL;
56 PythonQt* PythonQt::_self = NULL;
57 int PythonQt::_uniqueModuleCount = 0;
57 int PythonQt::_uniqueModuleCount = 0;
58
58
59 void PythonQt_init_QtGuiBuiltin();
59 void PythonQt_init_QtGuiBuiltin(PyObject*);
60 void PythonQt_init_QtCoreBuiltin();
60 void PythonQt_init_QtCoreBuiltin(PyObject*);
61
61
62 void PythonQt::init(int flags)
62 void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
63 {
63 {
64 if (!_self) {
64 if (!_self) {
65 _self = new PythonQt(flags);
65 _self = new PythonQt(flags, pythonQtModuleName);
66 }
67
66
68 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
67 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
69 qRegisterMetaType<QList<QObject*> >("QList<void*>");
68 qRegisterMetaType<QList<QObject*> >("QList<void*>");
@@ -79,8 +78,8 void PythonQt::init(int flags)
79
78
80 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
79 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
81
80
82 PythonQt_init_QtCoreBuiltin();
81 PythonQt_init_QtCoreBuiltin(NULL);
83 PythonQt_init_QtGuiBuiltin();
82 PythonQt_init_QtGuiBuiltin(NULL);
84
83
85 PythonQtRegisterToolClassesTemplateConverter(QDate);
84 PythonQtRegisterToolClassesTemplateConverter(QDate);
86 PythonQtRegisterToolClassesTemplateConverter(QTime);
85 PythonQtRegisterToolClassesTemplateConverter(QTime);
@@ -132,6 +131,7 void PythonQt::init(int flags)
132 }
131 }
133 }
132 }
134 }
133 }
134 }
135
135
136 void PythonQt::cleanup()
136 void PythonQt::cleanup()
137 {
137 {
@@ -141,7 +141,7 void PythonQt::cleanup()
141 }
141 }
142 }
142 }
143
143
144 PythonQt::PythonQt(int flags)
144 PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
145 {
145 {
146 _p = new PythonQtPrivate;
146 _p = new PythonQtPrivate;
147 _p->_initFlags = flags;
147 _p->_initFlags = flags;
@@ -182,7 +182,7 PythonQt::PythonQt(int flags)
182 }
182 }
183 Py_INCREF(&PythonQtStdOutRedirectType);
183 Py_INCREF(&PythonQtStdOutRedirectType);
184
184
185 initPythonQtModule(flags & RedirectStdOut);
185 initPythonQtModule(flags & RedirectStdOut, pythonQtModuleName);
186
186
187 _p->setupSharedLibrarySuffixes();
187 _p->setupSharedLibrarySuffixes();
188
188
@@ -227,7 +227,7 void PythonQt::registerClass(const QMetaObject* metaobject, const char* package,
227 _p->registerClass(metaobject, package, wrapperCreator, shell);
227 _p->registerClass(metaobject, package, wrapperCreator, shell);
228 }
228 }
229
229
230 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
230 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell, PyObject* module)
231 {
231 {
232 // we register all classes in the hierarchy
232 // we register all classes in the hierarchy
233 const QMetaObject* m = metaobject;
233 const QMetaObject* m = metaobject;
@@ -236,7 +236,7 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p
236 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(m->className());
236 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(m->className());
237 if (!info->pythonQtClassWrapper()) {
237 if (!info->pythonQtClassWrapper()) {
238 info->setupQObject(m);
238 info->setupQObject(m);
239 createPythonQtClassWrapper(info, package);
239 createPythonQtClassWrapper(info, package, module);
240 if (m->superClass()) {
240 if (m->superClass()) {
241 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
241 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
242 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
242 info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
@@ -255,12 +255,12 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p
255 }
255 }
256 }
256 }
257
257
258 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package)
258 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package, PyObject* module)
259 {
259 {
260 PyObject* pack = packageByName(package);
260 PyObject* pack = module?module:packageByName(package);
261 PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, package);
261 PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, pack);
262 PyModule_AddObject(pack, info->className(), pyobj);
262 PyModule_AddObject(pack, info->className(), pyobj);
263 if (package && strncmp(package,"Qt",2)==0) {
263 if (!module && package && strncmp(package,"Qt",2)==0) {
264 // since PyModule_AddObject steals the reference, we need a incref once more...
264 // since PyModule_AddObject steals the reference, we need a incref once more...
265 Py_INCREF(pyobj);
265 Py_INCREF(pyobj);
266 // put all qt objects into Qt as well
266 // put all qt objects into Qt as well
@@ -393,7 +393,7 PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObje
393 return result;
393 return result;
394 }
394 }
395
395
396 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package) {
396 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtClassInfo* info, PyObject* parentModule) {
397 PythonQtClassWrapper* result;
397 PythonQtClassWrapper* result;
398
398
399 PyObject* className = PyString_FromString(info->className());
399 PyObject* className = PyString_FromString(info->className());
@@ -402,12 +402,8 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla
402 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
402 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
403
403
404 PyObject* typeDict = PyDict_New();
404 PyObject* typeDict = PyDict_New();
405 QByteArray moduleName("PythonQt");
405 PyObject* moduleName = PyObject_GetAttrString(parentModule, "__name__");
406 if (package && strcmp(package, "")!=0) {
406 PyDict_SetItemString(typeDict, "__module__", moduleName);
407 moduleName += ".";
408 moduleName += package;
409 }
410 PyDict_SetItemString(typeDict, "__module__", PyString_FromString(moduleName.constData()));
411
407
412 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
408 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
413
409
@@ -1064,9 +1060,14 static PyMethodDef PythonQtMethods[] = {
1064 {NULL, NULL, 0, NULL}
1060 {NULL, NULL, 0, NULL}
1065 };
1061 };
1066
1062
1067 void PythonQt::initPythonQtModule(bool redirectStdOut)
1063 void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName)
1068 {
1064 {
1069 _p->_pythonQtModule = Py_InitModule("PythonQt", PythonQtMethods);
1065 QByteArray name = "PythonQt";
1066 if (!pythonQtModuleName.isEmpty()) {
1067 name = pythonQtModuleName;
1068 }
1069 _p->_pythonQtModule = Py_InitModule(name.constData(), PythonQtMethods);
1070 _p->_pythonQtModuleName = name;
1070
1071
1071 if (redirectStdOut) {
1072 if (redirectStdOut) {
1072 PythonQtObjectPtr sys;
1073 PythonQtObjectPtr sys;
@@ -1129,12 +1130,12 bool PythonQtPrivate::addParentClass(const char* typeName, const char* parentTyp
1129 }
1130 }
1130 }
1131 }
1131
1132
1132 void PythonQtPrivate::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
1133 void PythonQtPrivate::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell, PyObject* module)
1133 {
1134 {
1134 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1135 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1135 if (!info->pythonQtClassWrapper()) {
1136 if (!info->pythonQtClassWrapper()) {
1136 info->setupCPPObject(typeName);
1137 info->setupCPPObject(typeName);
1137 createPythonQtClassWrapper(info, package);
1138 createPythonQtClassWrapper(info, package, module);
1138 }
1139 }
1139 if (parentTypeName && strcmp(parentTypeName,"")!=0) {
1140 if (parentTypeName && strcmp(parentTypeName,"")!=0) {
1140 addParentClass(typeName, parentTypeName, 0);
1141 addParentClass(typeName, parentTypeName, 0);
@@ -1154,7 +1155,7 PyObject* PythonQtPrivate::packageByName(const char* name)
1154 }
1155 }
1155 PyObject* v = _packages.value(name);
1156 PyObject* v = _packages.value(name);
1156 if (!v) {
1157 if (!v) {
1157 v = PyImport_AddModule((QByteArray("PythonQt.") + name).constData());
1158 v = PyImport_AddModule((_pythonQtModuleName + "." + name).constData());
1158 _packages.insert(name, v);
1159 _packages.insert(name, v);
1159 // AddObject steals the reference, so increment it!
1160 // AddObject steals the reference, so increment it!
1160 Py_INCREF(v);
1161 Py_INCREF(v);
@@ -96,8 +96,10 public:
96 ExternalHelp = 4 //!<< sets if help() calls on PythonQt modules are forwarded to the pythonHelpRequest() signal
96 ExternalHelp = 4 //!<< sets if help() calls on PythonQt modules are forwarded to the pythonHelpRequest() signal
97 };
97 };
98
98
99 //! initialize the python qt binding (flags are a or combination of InitFlags)
99 //! initialize the python qt binding (flags are a or combination of InitFlags), if \c pythonQtModuleName is given
100 static void init(int flags = IgnoreSiteModule | RedirectStdOut);
100 //! it defines the name of the python module that PythonQt will add, otherwise "PythonQt" is used.
101 //! This can be used to e.g. pass in PySide or PyQt4 to make it more compatible.
102 static void init(int flags = IgnoreSiteModule | RedirectStdOut, const QByteArray& pythonQtModuleName = QByteArray());
101
103
102 //! cleanup
104 //! cleanup
103 static void cleanup();
105 static void cleanup();
@@ -361,7 +363,7 public:
361 PythonQtObjectPtr lookupObject(PyObject* module, const QString& name);
363 PythonQtObjectPtr lookupObject(PyObject* module, const QString& name);
362
364
363 private:
365 private:
364 void initPythonQtModule(bool redirectStdOut);
366 void initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName);
365
367
366 //! callback for stdout redirection, emits pythonStdOut signal
368 //! callback for stdout redirection, emits pythonStdOut signal
367 static void stdOutRedirectCB(const QString& str);
369 static void stdOutRedirectCB(const QString& str);
@@ -371,7 +373,7 private:
371 //! get (and create if not available) the signal receiver of that QObject, signal receiver is made child of the passed \c obj
373 //! get (and create if not available) the signal receiver of that QObject, signal receiver is made child of the passed \c obj
372 PythonQtSignalReceiver* getSignalReceiver(QObject* obj);
374 PythonQtSignalReceiver* getSignalReceiver(QObject* obj);
373
375
374 PythonQt(int flags);
376 PythonQt(int flags, const QByteArray& pythonQtModuleName);
375 ~PythonQt();
377 ~PythonQt();
376
378
377 static PythonQt* _self;
379 static PythonQt* _self;
@@ -430,7 +432,7 public:
430 //! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well)
432 //! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well)
431 /* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject,
433 /* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject,
432 you MUST register all your QObject derived classes here when you want them to be detected in signal and slot calls */
434 you MUST register all your QObject derived classes here when you want them to be detected in signal and slot calls */
433 void registerClass(const QMetaObject* metaobject, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL);
435 void registerClass(const QMetaObject* metaobject, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL, PyObject* module = NULL);
434
436
435 //! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants
437 //! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants
436 //! (ownership of wrapper is passed to PythonQt)
438 //! (ownership of wrapper is passed to PythonQt)
@@ -440,7 +442,7 public:
440 All slots that take a pointer to typeName as the first argument will be callable from Python on
442 All slots that take a pointer to typeName as the first argument will be callable from Python on
441 a variant object that contains such a type.
443 a variant object that contains such a type.
442 */
444 */
443 void registerCPPClass(const char* typeName, const char* parentTypeName = NULL, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL);
445 void registerCPPClass(const char* typeName, const char* parentTypeName = NULL, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL, PyObject* module = NULL);
444
446
445 //! as an alternative to registerClass, you can tell PythonQt the names of QObject derived classes
447 //! as an alternative to registerClass, you can tell PythonQt the names of QObject derived classes
446 //! and it will register the classes when it first sees a pointer to such a derived class
448 //! and it will register the classes when it first sees a pointer to such a derived class
@@ -450,7 +452,7 public:
450 void addDecorators(QObject* o, int decoTypes);
452 void addDecorators(QObject* o, int decoTypes);
451
453
452 //! helper method that creates a PythonQtClassWrapper object (returns a new reference)
454 //! helper method that creates a PythonQtClassWrapper object (returns a new reference)
453 PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL);
455 PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, PyObject* module);
454
456
455 //! create a new instance of the given enum type with given value (returns a new reference)
457 //! create a new instance of the given enum type with given value (returns a new reference)
456 static PyObject* createEnumValueInstance(PyObject* enumType, unsigned int enumValue);
458 static PyObject* createEnumValueInstance(PyObject* enumType, unsigned int enumValue);
@@ -487,7 +489,7 private:
487 void setupSharedLibrarySuffixes();
489 void setupSharedLibrarySuffixes();
488
490
489 //! create a new pythonqt class wrapper and place it in the pythonqt module
491 //! create a new pythonqt class wrapper and place it in the pythonqt module
490 void createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package);
492 void createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package, PyObject* module = NULL);
491
493
492 //! get/create new package module (the returned object is a borrowed reference)
494 //! get/create new package module (the returned object is a borrowed reference)
493 PyObject* packageByName(const char* name);
495 PyObject* packageByName(const char* name);
@@ -510,6 +512,9 private:
510 //! the PythonQt python module
512 //! the PythonQt python module
511 PythonQtObjectPtr _pythonQtModule;
513 PythonQtObjectPtr _pythonQtModule;
512
514
515 //! the name of the PythonQt python module
516 QByteArray _pythonQtModuleName;
517
513 //! the importer interface (if set)
518 //! the importer interface (if set)
514 PythonQtImportFileInterface* _importInterface;
519 PythonQtImportFileInterface* _importInterface;
515
520
General Comments 0
You need to be logged in to leave comments. Login now