##// 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,79 +56,79
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 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
69 qRegisterMetaType<QList<QObject*> >("QList<void*>");
67 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
68 qRegisterMetaType<QList<QObject*> >("QList<void*>");
70 69
71 PythonQtRegisterToolClassesTemplateConverter(int);
72 PythonQtRegisterToolClassesTemplateConverter(float);
73 PythonQtRegisterToolClassesTemplateConverter(double);
74 PythonQtRegisterToolClassesTemplateConverter(qint32);
75 PythonQtRegisterToolClassesTemplateConverter(quint32);
76 PythonQtRegisterToolClassesTemplateConverter(qint64);
77 PythonQtRegisterToolClassesTemplateConverter(quint64);
78 // TODO: which other POD types should be available for QList etc.
70 PythonQtRegisterToolClassesTemplateConverter(int);
71 PythonQtRegisterToolClassesTemplateConverter(float);
72 PythonQtRegisterToolClassesTemplateConverter(double);
73 PythonQtRegisterToolClassesTemplateConverter(qint32);
74 PythonQtRegisterToolClassesTemplateConverter(quint32);
75 PythonQtRegisterToolClassesTemplateConverter(qint64);
76 PythonQtRegisterToolClassesTemplateConverter(quint64);
77 // TODO: which other POD types should be available for QList etc.
79 78
80 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
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 PythonQtRegisterToolClassesTemplateConverter(QDate);
86 PythonQtRegisterToolClassesTemplateConverter(QTime);
87 PythonQtRegisterToolClassesTemplateConverter(QDateTime);
88 PythonQtRegisterToolClassesTemplateConverter(QUrl);
89 PythonQtRegisterToolClassesTemplateConverter(QLocale);
90 PythonQtRegisterToolClassesTemplateConverter(QRect);
91 PythonQtRegisterToolClassesTemplateConverter(QRectF);
92 PythonQtRegisterToolClassesTemplateConverter(QSize);
93 PythonQtRegisterToolClassesTemplateConverter(QSizeF);
94 PythonQtRegisterToolClassesTemplateConverter(QLine);
95 PythonQtRegisterToolClassesTemplateConverter(QLineF);
96 PythonQtRegisterToolClassesTemplateConverter(QPoint);
97 PythonQtRegisterToolClassesTemplateConverter(QPointF);
98 PythonQtRegisterToolClassesTemplateConverter(QRegExp);
99
100 PythonQtRegisterToolClassesTemplateConverter(QFont);
101 PythonQtRegisterToolClassesTemplateConverter(QPixmap);
102 PythonQtRegisterToolClassesTemplateConverter(QBrush);
103 PythonQtRegisterToolClassesTemplateConverter(QColor);
104 PythonQtRegisterToolClassesTemplateConverter(QPalette);
105 PythonQtRegisterToolClassesTemplateConverter(QIcon);
106 PythonQtRegisterToolClassesTemplateConverter(QImage);
107 PythonQtRegisterToolClassesTemplateConverter(QPolygon);
108 PythonQtRegisterToolClassesTemplateConverter(QRegion);
109 PythonQtRegisterToolClassesTemplateConverter(QBitmap);
110 PythonQtRegisterToolClassesTemplateConverter(QCursor);
111 PythonQtRegisterToolClassesTemplateConverter(QSizePolicy);
112 PythonQtRegisterToolClassesTemplateConverter(QKeySequence);
113 PythonQtRegisterToolClassesTemplateConverter(QPen);
114 PythonQtRegisterToolClassesTemplateConverter(QTextLength);
115 PythonQtRegisterToolClassesTemplateConverter(QTextFormat);
116 PythonQtRegisterToolClassesTemplateConverter(QMatrix);
117
118
119 PyObject* pack = PythonQt::priv()->packageByName("QtCore");
120 PyObject* pack2 = PythonQt::priv()->packageByName("Qt");
121 PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper();
122 const char* names[16] = {"SIGNAL", "SLOT", "qAbs", "qBound","qDebug","qWarning","qCritical","qFatal"
84 PythonQtRegisterToolClassesTemplateConverter(QDate);
85 PythonQtRegisterToolClassesTemplateConverter(QTime);
86 PythonQtRegisterToolClassesTemplateConverter(QDateTime);
87 PythonQtRegisterToolClassesTemplateConverter(QUrl);
88 PythonQtRegisterToolClassesTemplateConverter(QLocale);
89 PythonQtRegisterToolClassesTemplateConverter(QRect);
90 PythonQtRegisterToolClassesTemplateConverter(QRectF);
91 PythonQtRegisterToolClassesTemplateConverter(QSize);
92 PythonQtRegisterToolClassesTemplateConverter(QSizeF);
93 PythonQtRegisterToolClassesTemplateConverter(QLine);
94 PythonQtRegisterToolClassesTemplateConverter(QLineF);
95 PythonQtRegisterToolClassesTemplateConverter(QPoint);
96 PythonQtRegisterToolClassesTemplateConverter(QPointF);
97 PythonQtRegisterToolClassesTemplateConverter(QRegExp);
98
99 PythonQtRegisterToolClassesTemplateConverter(QFont);
100 PythonQtRegisterToolClassesTemplateConverter(QPixmap);
101 PythonQtRegisterToolClassesTemplateConverter(QBrush);
102 PythonQtRegisterToolClassesTemplateConverter(QColor);
103 PythonQtRegisterToolClassesTemplateConverter(QPalette);
104 PythonQtRegisterToolClassesTemplateConverter(QIcon);
105 PythonQtRegisterToolClassesTemplateConverter(QImage);
106 PythonQtRegisterToolClassesTemplateConverter(QPolygon);
107 PythonQtRegisterToolClassesTemplateConverter(QRegion);
108 PythonQtRegisterToolClassesTemplateConverter(QBitmap);
109 PythonQtRegisterToolClassesTemplateConverter(QCursor);
110 PythonQtRegisterToolClassesTemplateConverter(QSizePolicy);
111 PythonQtRegisterToolClassesTemplateConverter(QKeySequence);
112 PythonQtRegisterToolClassesTemplateConverter(QPen);
113 PythonQtRegisterToolClassesTemplateConverter(QTextLength);
114 PythonQtRegisterToolClassesTemplateConverter(QTextFormat);
115 PythonQtRegisterToolClassesTemplateConverter(QMatrix);
116
117
118 PyObject* pack = PythonQt::priv()->packageByName("QtCore");
119 PyObject* pack2 = PythonQt::priv()->packageByName("Qt");
120 PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper();
121 const char* names[16] = {"SIGNAL", "SLOT", "qAbs", "qBound","qDebug","qWarning","qCritical","qFatal"
123 122 ,"qFuzzyCompare", "qMax","qMin","qRound","qRound64","qVersion","qrand","qsrand"};
124 for (unsigned int i = 0;i<16; i++) {
125 PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]);
126 if (obj) {
127 PyModule_AddObject(pack, names[i], obj);
128 Py_INCREF(obj);
129 PyModule_AddObject(pack2, names[i], obj);
130 } else {
131 std::cerr << "method not found " << names[i];
123 for (unsigned int i = 0;i<16; i++) {
124 PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]);
125 if (obj) {
126 PyModule_AddObject(pack, names[i], obj);
127 Py_INCREF(obj);
128 PyModule_AddObject(pack2, names[i], obj);
129 } else {
130 std::cerr << "method not found " << names[i];
131 }
132 132 }
133 133 }
134 134 }
@@ -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,10 +1060,15 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);
1070
1065 QByteArray name = "PythonQt";
1066 if (!pythonQtModuleName.isEmpty()) {
1067 name = pythonQtModuleName;
1068 }
1069 _p->_pythonQtModule = Py_InitModule(name.constData(), PythonQtMethods);
1070 _p->_pythonQtModuleName = name;
1071
1071 1072 if (redirectStdOut) {
1072 1073 PythonQtObjectPtr sys;
1073 1074 PythonQtObjectPtr out;
@@ -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