@@ -149,13 +149,15 PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName) | |||
|
149 | 149 | |
|
150 | 150 | _p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr"); |
|
151 | 151 | |
|
152 | Py_SetProgramName("PythonQt"); | |
|
153 | if (flags & IgnoreSiteModule) { | |
|
154 | // this prevents the automatic importing of Python site files | |
|
155 | Py_NoSiteFlag = 1; | |
|
152 | if (flags & PythonAlreadyInitialized == 0) { | |
|
153 | Py_SetProgramName("PythonQt"); | |
|
154 | if (flags & IgnoreSiteModule) { | |
|
155 | // this prevents the automatic importing of Python site files | |
|
156 | Py_NoSiteFlag = 1; | |
|
157 | } | |
|
158 | Py_Initialize(); | |
|
156 | 159 | } |
|
157 | Py_Initialize(); | |
|
158 | ||
|
160 | ||
|
159 | 161 |
|
|
160 | 162 | if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) { |
|
161 | 163 | std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl; |
@@ -554,6 +556,14 PythonQtObjectPtr PythonQt::getMainModule() { | |||
|
554 | 556 | return PyDict_GetItemString(dict, "__main__"); |
|
555 | 557 | } |
|
556 | 558 | |
|
559 | PythonQtObjectPtr PythonQt::importModule(const QString& name) | |
|
560 | { | |
|
561 | PythonQtObjectPtr mod; | |
|
562 | mod.setNewRef(PyImport_ImportModule(name.toLatin1().constData())); | |
|
563 | return mod; | |
|
564 | } | |
|
565 | ||
|
566 | ||
|
557 | 567 | QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) { |
|
558 | 568 | QVariant result; |
|
559 | 569 | if (pycode) { |
@@ -84,16 +84,27 typedef QObject* PythonQtQObjectCreatorFunctionCB(); | |||
|
84 | 84 | //! helper template to create a derived QObject class |
|
85 | 85 | template<class T> QObject* PythonQtCreateObject() { return new T(); }; |
|
86 | 86 | |
|
87 |
//! |
|
|
87 | //! The main interface to the Python Qt binding, realized as a singleton | |
|
88 | /*! | |
|
89 | Use PythonQt::init() to initialize the singleton and PythonQt::self() to access it. | |
|
90 | While there can be only one PythonQt instance, you can have any number of Python context to do scripting in. | |
|
91 | One possibility is to use createModuleFromFile(), createModuleFromScript() or createUniqueModule() to get a context | |
|
92 | that is separated from the other contexts. Alternatively you can use Python dicts as contexts for script evaluation, | |
|
93 | but you will need to populate the dict with the __builtins__ instance to have all Pythons available when running | |
|
94 | code in the scope of a dict. | |
|
95 | */ | |
|
88 | 96 | class PYTHONQT_EXPORT PythonQt : public QObject { |
|
89 | 97 | |
|
90 | 98 | Q_OBJECT |
|
91 | 99 | |
|
92 | 100 | public: |
|
101 | ||
|
102 | //! flags that can be passed to PythonQt::init() | |
|
93 | 103 | enum InitFlags { |
|
94 | 104 | RedirectStdOut = 1, //!<< sets if the std out/err is redirected to pythonStdOut() and pythonStdErr() signals |
|
95 | 105 | IgnoreSiteModule = 2, //!<< sets if Python should ignore the site module |
|
96 |
ExternalHelp = 4 |
|
|
106 | ExternalHelp = 4, //!<< sets if help() calls on PythonQt modules are forwarded to the pythonHelpRequest() signal | |
|
107 | PythonAlreadyInitialized = 8 //!<< sets that PythonQt should not can PyInitialize, since it is already done | |
|
97 | 108 | }; |
|
98 | 109 | |
|
99 | 110 | //! flags that tell PythonQt which operators to expect on the registered type |
@@ -132,20 +143,23 public: | |||
|
132 | 143 | |
|
133 | 144 | }; |
|
134 | 145 | |
|
135 | //! initialize the python qt binding (flags are a or combination of InitFlags), if \c pythonQtModuleName is given | |
|
146 | //--------------------------------------------------------------------------- | |
|
147 | //! \name Singleton Initialization | |
|
148 | //@{ | |
|
149 | ||
|
150 | //! initialize the python qt binding (flags are a or combination of PythonQt::InitFlags), if \c pythonQtModuleName is given | |
|
136 | 151 | //! it defines the name of the python module that PythonQt will add, otherwise "PythonQt" is used. |
|
137 | 152 | //! This can be used to e.g. pass in PySide or PyQt4 to make it more compatible. |
|
138 | 153 | static void init(int flags = IgnoreSiteModule | RedirectStdOut, const QByteArray& pythonQtModuleName = QByteArray()); |
|
139 | 154 | |
|
140 | //! cleanup | |
|
155 | //! cleanup of the singleton | |
|
141 | 156 | static void cleanup(); |
|
142 | 157 | |
|
143 | 158 | //! get the singleton instance |
|
144 | 159 | static PythonQt* self() { return _self; } |
|
145 | 160 | |
|
146 | //----------------------------------------------------------------------------- | |
|
147 | // Public API: | |
|
148 | ||
|
161 | //@} | |
|
162 | ||
|
149 | 163 |
|
|
150 | 164 | enum ObjectType { |
|
151 | 165 | Class, |
@@ -156,6 +170,39 public: | |||
|
156 | 170 | CallOverloads |
|
157 | 171 | }; |
|
158 | 172 | |
|
173 | //--------------------------------------------------------------------------- | |
|
174 | //! \name Modules | |
|
175 | //@{ | |
|
176 | ||
|
177 | //! get the __main__ module of python | |
|
178 | PythonQtObjectPtr getMainModule(); | |
|
179 | ||
|
180 | //! import the given module and return a reference to it (useful to import e.g. "sys" and call something on it) | |
|
181 | //! If a module is already imported, this returns the already imported module. | |
|
182 | PythonQtObjectPtr importModule(const QString& name); | |
|
183 | ||
|
184 | //! creates the new module \c name and evaluates the given file in the context of that module | |
|
185 | //! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code | |
|
186 | //! to a module later on. | |
|
187 | //! The user needs to make sure that the \c name is unique in the python module dictionary. | |
|
188 | PythonQtObjectPtr createModuleFromFile(const QString& name, const QString& filename); | |
|
189 | ||
|
190 | //! creates the new module \c name and evaluates the given script in the context of that module. | |
|
191 | //! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code | |
|
192 | //! to a module later on. | |
|
193 | //! The user needs to make sure that the \c name is unique in the python module dictionary. | |
|
194 | PythonQtObjectPtr createModuleFromScript(const QString& name, const QString& script = QString()); | |
|
195 | ||
|
196 | //! create a uniquely named module, you can use evalFile or evalScript to populate the module with | |
|
197 | //! script code | |
|
198 | PythonQtObjectPtr createUniqueModule(); | |
|
199 | ||
|
200 | //@} | |
|
201 | ||
|
202 | //--------------------------------------------------------------------------- | |
|
203 | //! \name Importing/Paths | |
|
204 | //@{ | |
|
205 | ||
|
159 | 206 | //! overwrite the python sys path (call this directly after PythonQt::init() if you want to change the std python sys path) |
|
160 | 207 | void overwriteSysPath(const QStringList& paths); |
|
161 | 208 | |
@@ -165,9 +212,12 public: | |||
|
165 | 212 | //! sets the __path__ list of a module to the given list (important for local imports) |
|
166 | 213 | void setModuleImportPath(PyObject* module, const QStringList& paths); |
|
167 | 214 | |
|
168 | //! get the __main__ module of python | |
|
169 | PythonQtObjectPtr getMainModule(); | |
|
170 | ||
|
215 | //@} | |
|
216 | ||
|
217 | //--------------------------------------------------------------------------- | |
|
218 | //! \name Registering Classes | |
|
219 | //@{ | |
|
220 | ||
|
171 | 221 |
|
|
172 | 222 | /* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject, |
|
173 | 223 | you MUST register all your QObject derived classes here when you want them to be detected in signal and slot calls */ |
@@ -196,6 +246,12 public: | |||
|
196 | 246 | //! add a handler for polymorphic downcasting |
|
197 | 247 | void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb); |
|
198 | 248 | |
|
249 | //@} | |
|
250 | ||
|
251 | //--------------------------------------------------------------------------- | |
|
252 | //! \name Script Parsing and Evaluation | |
|
253 | //@{ | |
|
254 | ||
|
199 | 255 |
|
|
200 | 256 | PythonQtObjectPtr parseFile(const QString& filename); |
|
201 | 257 | |
@@ -209,23 +265,11 public: | |||
|
209 | 265 | //! evaluates the given script code from file |
|
210 | 266 | void evalFile(PyObject* object, const QString& filename); |
|
211 | 267 | |
|
212 | //! creates the new module \c name and evaluates the given file in the context of that module | |
|
213 | //! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code | |
|
214 | //! to a module later on. | |
|
215 | //! The user needs to make sure that the \c name is unique in the python module dictionary. | |
|
216 | PythonQtObjectPtr createModuleFromFile(const QString& name, const QString& filename); | |
|
217 | ||
|
218 | //! creates the new module \c name and evaluates the given script in the context of that module. | |
|
219 | //! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code | |
|
220 | //! to a module later on. | |
|
221 | //! The user needs to make sure that the \c name is unique in the python module dictionary. | |
|
222 | PythonQtObjectPtr createModuleFromScript(const QString& name, const QString& script = QString()); | |
|
223 | ||
|
224 | //! create a uniquely named module, you can use evalFile or evalScript to populate the module with | |
|
225 | //! script code | |
|
226 | PythonQtObjectPtr createUniqueModule(); | |
|
268 | //@} | |
|
227 | 269 | |
|
228 | //@{ Signal handlers | |
|
270 | //--------------------------------------------------------------------------- | |
|
271 | //! \name Signal Handlers | |
|
272 | //@{ | |
|
229 | 273 | |
|
230 | 274 | //! add a signal handler to the given \c signal of \c obj and connect it to a callable \c objectname in module |
|
231 | 275 | bool addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname); |
@@ -241,7 +285,9 public: | |||
|
241 | 285 | |
|
242 | 286 | //@} |
|
243 | 287 | |
|
244 | //@{ Variable access | |
|
288 | //--------------------------------------------------------------------------- | |
|
289 | //! \name Variable access | |
|
290 | //@{ | |
|
245 | 291 | |
|
246 | 292 | //! add the given \c qObject to the python \c object as a variable with \c name (it can be removed via clearVariable) |
|
247 | 293 | void addObject(PyObject* object, const QString& name, QObject* qObject); |
@@ -264,7 +310,9 public: | |||
|
264 | 310 | |
|
265 | 311 | //@} |
|
266 | 312 | |
|
267 | //@{ Calling of python callables | |
|
313 | //--------------------------------------------------------------------------- | |
|
314 | //! \name Calling Python Objects | |
|
315 | //@{ | |
|
268 | 316 | |
|
269 | 317 | //! call the given python \c callable in the scope of object, returns the result converted to a QVariant |
|
270 | 318 | QVariant call(PyObject* object, const QString& callable, const QVariantList& args = QVariantList()); |
@@ -277,8 +325,9 public: | |||
|
277 | 325 | |
|
278 | 326 | //@} |
|
279 | 327 | |
|
280 | //@{ Decorations, constructors, wrappers... | |
|
281 | ||
|
328 | //--------------------------------------------------------------------------- | |
|
329 | //! \name Decorations, Constructors, Wrappers... | |
|
330 | //@{ | |
|
282 | 331 | |
|
283 | 332 | //! add an object whose slots will be used as decorator slots for |
|
284 | 333 | //! other QObjects or CPP classes. The slots need to follow the |
@@ -333,8 +382,10 public: | |||
|
333 | 382 | |
|
334 | 383 | //@} |
|
335 | 384 | |
|
336 | //@{ Custom importer (to replace internal import implementation of python) | |
|
337 | ||
|
385 | //--------------------------------------------------------------------------- | |
|
386 | //! \name Custom Importer | |
|
387 | //@{ | |
|
388 | ||
|
338 | 389 |
|
|
339 | 390 | //! (this method should be called directly after initialization of init() and before calling overwriteSysPath(). |
|
340 | 391 | //! On the first call to this method, it will install a generic PythonQt importer in Pythons "path_hooks". |
@@ -360,14 +411,18 public: | |||
|
360 | 411 | //! get paths that the importer should ignore |
|
361 | 412 | const QStringList& getImporterIgnorePaths(); |
|
362 | 413 | |
|
414 | //! get access to the file importer (if set) | |
|
415 | static PythonQtImportFileInterface* importInterface(); | |
|
416 | ||
|
363 | 417 | //@} |
|
364 | 418 | |
|
419 | //--------------------------------------------------------------------------- | |
|
420 | //! \name Other Stuff | |
|
421 | //@{ | |
|
422 | ||
|
365 | 423 | //! get access to internal data (should not be used on the public API, but is used by some C functions) |
|
366 | 424 | static PythonQtPrivate* priv() { return _self->_p; } |
|
367 | 425 | |
|
368 | //! get access to the file importer (if set) | |
|
369 | static PythonQtImportFileInterface* importInterface(); | |
|
370 | ||
|
371 | 426 | //! handle a python error, call this when a python function fails. If no error occurred, it returns false. |
|
372 | 427 | //! The error is currently just output to the python stderr, future version might implement better trace printing |
|
373 | 428 | bool handleError(); |
@@ -380,6 +435,15 public: | |||
|
380 | 435 | //! call the callback if it is set |
|
381 | 436 | static void qObjectNoLongerWrappedCB(QObject* o); |
|
382 | 437 | |
|
438 | //! called by internal help methods | |
|
439 | PyObject* helpCalled(PythonQtClassInfo* info); | |
|
440 | ||
|
441 | //! returns the found object or NULL | |
|
442 | //! @return new reference | |
|
443 | PythonQtObjectPtr lookupObject(PyObject* module, const QString& name); | |
|
444 | ||
|
445 | //@} | |
|
446 | ||
|
383 | 447 | signals: |
|
384 | 448 | //! emitted when python outputs something to stdout (and redirection is turned on) |
|
385 | 449 | void pythonStdOut(const QString& str); |
@@ -389,15 +453,6 signals: | |||
|
389 | 453 | //! emitted when help() is called on a PythonQt object and \c ExternalHelp is enabled |
|
390 | 454 | void pythonHelpRequest(const QByteArray& cppClassName); |
|
391 | 455 | |
|
392 | ||
|
393 | public: | |
|
394 | //! called by internal help methods | |
|
395 | PyObject* helpCalled(PythonQtClassInfo* info); | |
|
396 | ||
|
397 | //! returns the found object or NULL | |
|
398 | //! @return new reference | |
|
399 | PythonQtObjectPtr lookupObject(PyObject* module, const QString& name); | |
|
400 | ||
|
401 | 456 | private: |
|
402 | 457 | void initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName); |
|
403 | 458 |
General Comments 0
You need to be logged in to leave comments.
Login now