##// 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 56 PythonQt* PythonQt::_self = NULL;
57 57 int PythonQt::_uniqueModuleCount = 0;
58 58
59 void PythonQt_init_QtGuiBuiltin();
60 void PythonQt_init_QtCoreBuiltin();
59 void PythonQt_init_QtGuiBuiltin(PyObject*);
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 64 if (!_self) {
65 _self = new PythonQt(flags);
66 }
65 _self = new PythonQt(flags, pythonQtModuleName);
67 66
68 67 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
69 68 qRegisterMetaType<QList<QObject*> >("QList<void*>");
@@ -79,8 +78,8 void PythonQt::init(int flags)
79 78
80 79 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
81 80
82 PythonQt_init_QtCoreBuiltin();
83 PythonQt_init_QtGuiBuiltin();
81 PythonQt_init_QtCoreBuiltin(NULL);
82 PythonQt_init_QtGuiBuiltin(NULL);
84 83
85 84 PythonQtRegisterToolClassesTemplateConverter(QDate);
86 85 PythonQtRegisterToolClassesTemplateConverter(QTime);
@@ -132,6 +131,7 void PythonQt::init(int flags)
132 131 }
133 132 }
134 133 }
134 }
135 135
136 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 146 _p = new PythonQtPrivate;
147 147 _p->_initFlags = flags;
@@ -182,7 +182,7 PythonQt::PythonQt(int flags)
182 182 }
183 183 Py_INCREF(&PythonQtStdOutRedirectType);
184 184
185 initPythonQtModule(flags & RedirectStdOut);
185 initPythonQtModule(flags & RedirectStdOut, pythonQtModuleName);
186 186
187 187 _p->setupSharedLibrarySuffixes();
188 188
@@ -227,7 +227,7 void PythonQt::registerClass(const QMetaObject* metaobject, const char* package,
227 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 232 // we register all classes in the hierarchy
233 233 const QMetaObject* m = metaobject;
@@ -236,7 +236,7 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* p
236 236 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(m->className());
237 237 if (!info->pythonQtClassWrapper()) {
238 238 info->setupQObject(m);
239 createPythonQtClassWrapper(info, package);
239 createPythonQtClassWrapper(info, package, module);
240 240 if (m->superClass()) {
241 241 PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
242 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);
261 PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, package);
260 PyObject* pack = module?module:packageByName(package);
261 PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, pack);
262 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 264 // since PyModule_AddObject steals the reference, we need a incref once more...
265 265 Py_INCREF(pyobj);
266 266 // put all qt objects into Qt as well
@@ -393,7 +393,7 PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObje
393 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 397 PythonQtClassWrapper* result;
398 398
399 399 PyObject* className = PyString_FromString(info->className());
@@ -402,12 +402,8 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla
402 402 PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
403 403
404 404 PyObject* typeDict = PyDict_New();
405 QByteArray moduleName("PythonQt");
406 if (package && strcmp(package, "")!=0) {
407 moduleName += ".";
408 moduleName += package;
409 }
410 PyDict_SetItemString(typeDict, "__module__", PyString_FromString(moduleName.constData()));
405 PyObject* moduleName = PyObject_GetAttrString(parentModule, "__name__");
406 PyDict_SetItemString(typeDict, "__module__", moduleName);
411 407
412 408 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
413 409
@@ -1064,9 +1060,14 static PyMethodDef PythonQtMethods[] = {
1064 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 1072 if (redirectStdOut) {
1072 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 1135 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1135 1136 if (!info->pythonQtClassWrapper()) {
1136 1137 info->setupCPPObject(typeName);
1137 createPythonQtClassWrapper(info, package);
1138 createPythonQtClassWrapper(info, package, module);
1138 1139 }
1139 1140 if (parentTypeName && strcmp(parentTypeName,"")!=0) {
1140 1141 addParentClass(typeName, parentTypeName, 0);
@@ -1154,7 +1155,7 PyObject* PythonQtPrivate::packageByName(const char* name)
1154 1155 }
1155 1156 PyObject* v = _packages.value(name);
1156 1157 if (!v) {
1157 v = PyImport_AddModule((QByteArray("PythonQt.") + name).constData());
1158 v = PyImport_AddModule((_pythonQtModuleName + "." + name).constData());
1158 1159 _packages.insert(name, v);
1159 1160 // AddObject steals the reference, so increment it!
1160 1161 Py_INCREF(v);
@@ -96,8 +96,10 public:
96 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)
100 static void init(int flags = IgnoreSiteModule | RedirectStdOut);
99 //! initialize the python qt binding (flags are a or combination of InitFlags), if \c pythonQtModuleName is given
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 104 //! cleanup
103 105 static void cleanup();
@@ -361,7 +363,7 public:
361 363 PythonQtObjectPtr lookupObject(PyObject* module, const QString& name);
362 364
363 365 private:
364 void initPythonQtModule(bool redirectStdOut);
366 void initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName);
365 367
366 368 //! callback for stdout redirection, emits pythonStdOut signal
367 369 static void stdOutRedirectCB(const QString& str);
@@ -371,7 +373,7 private:
371 373 //! get (and create if not available) the signal receiver of that QObject, signal receiver is made child of the passed \c obj
372 374 PythonQtSignalReceiver* getSignalReceiver(QObject* obj);
373 375
374 PythonQt(int flags);
376 PythonQt(int flags, const QByteArray& pythonQtModuleName);
375 377 ~PythonQt();
376 378
377 379 static PythonQt* _self;
@@ -430,7 +432,7 public:
430 432 //! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well)
431 433 /* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject,
432 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 437 //! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants
436 438 //! (ownership of wrapper is passed to PythonQt)
@@ -440,7 +442,7 public:
440 442 All slots that take a pointer to typeName as the first argument will be callable from Python on
441 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 447 //! as an alternative to registerClass, you can tell PythonQt the names of QObject derived classes
446 448 //! and it will register the classes when it first sees a pointer to such a derived class
@@ -450,7 +452,7 public:
450 452 void addDecorators(QObject* o, int decoTypes);
451 453
452 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 457 //! create a new instance of the given enum type with given value (returns a new reference)
456 458 static PyObject* createEnumValueInstance(PyObject* enumType, unsigned int enumValue);
@@ -487,7 +489,7 private:
487 489 void setupSharedLibrarySuffixes();
488 490
489 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 494 //! get/create new package module (the returned object is a borrowed reference)
493 495 PyObject* packageByName(const char* name);
@@ -510,6 +512,9 private:
510 512 //! the PythonQt python module
511 513 PythonQtObjectPtr _pythonQtModule;
512 514
515 //! the name of the PythonQt python module
516 QByteArray _pythonQtModuleName;
517
513 518 //! the importer interface (if set)
514 519 PythonQtImportFileInterface* _importInterface;
515 520
General Comments 0
You need to be logged in to leave comments. Login now