Skip to content

Commit e03a0e6

Browse files
committed
improved docs
1 parent 08a6b85 commit e03a0e6

File tree

2 files changed

+115
-50
lines changed

2 files changed

+115
-50
lines changed

src/PythonQt.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,15 @@ PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
149149

150150
_p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr");
151151

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();
156159
}
157-
Py_Initialize();
158-
160+
159161
// add our own python object types for qt object slots
160162
if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) {
161163
std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
@@ -554,6 +556,14 @@ PythonQtObjectPtr PythonQt::getMainModule() {
554556
return PyDict_GetItemString(dict, "__main__");
555557
}
556558

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+
557567
QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
558568
QVariant result;
559569
if (pycode) {

src/PythonQt.h

Lines changed: 99 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,27 @@ typedef QObject* PythonQtQObjectCreatorFunctionCB();
8484
//! helper template to create a derived QObject class
8585
template<class T> QObject* PythonQtCreateObject() { return new T(); };
8686

87-
//! the main interface to the Python Qt binding, realized as a singleton
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+
*/
8896
class PYTHONQT_EXPORT PythonQt : public QObject {
8997

9098
Q_OBJECT
9199

92100
public:
101+
102+
//! flags that can be passed to PythonQt::init()
93103
enum InitFlags {
94104
RedirectStdOut = 1, //!<< sets if the std out/err is redirected to pythonStdOut() and pythonStdErr() signals
95105
IgnoreSiteModule = 2, //!<< sets if Python should ignore the site module
96-
ExternalHelp = 4 //!<< sets if help() calls on PythonQt modules are forwarded to the pythonHelpRequest() signal
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
97108
};
98109

99110
//! flags that tell PythonQt which operators to expect on the registered type
@@ -132,20 +143,23 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
132143

133144
};
134145

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
136151
//! it defines the name of the python module that PythonQt will add, otherwise "PythonQt" is used.
137152
//! This can be used to e.g. pass in PySide or PyQt4 to make it more compatible.
138153
static void init(int flags = IgnoreSiteModule | RedirectStdOut, const QByteArray& pythonQtModuleName = QByteArray());
139154

140-
//! cleanup
155+
//! cleanup of the singleton
141156
static void cleanup();
142157

143158
//! get the singleton instance
144159
static PythonQt* self() { return _self; }
145160

146-
//-----------------------------------------------------------------------------
147-
// Public API:
148-
161+
//@}
162+
149163
//! defines the object types for introspection
150164
enum ObjectType {
151165
Class,
@@ -156,6 +170,39 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
156170
CallOverloads
157171
};
158172

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+
159206
//! overwrite the python sys path (call this directly after PythonQt::init() if you want to change the std python sys path)
160207
void overwriteSysPath(const QStringList& paths);
161208

@@ -165,9 +212,12 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
165212
//! sets the __path__ list of a module to the given list (important for local imports)
166213
void setModuleImportPath(PyObject* module, const QStringList& paths);
167214

168-
//! get the __main__ module of python
169-
PythonQtObjectPtr getMainModule();
170-
215+
//@}
216+
217+
//---------------------------------------------------------------------------
218+
//! \name Registering Classes
219+
//@{
220+
171221
//! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well)
172222
/* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject,
173223
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 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
196246
//! add a handler for polymorphic downcasting
197247
void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb);
198248

249+
//@}
250+
251+
//---------------------------------------------------------------------------
252+
//! \name Script Parsing and Evaluation
253+
//@{
254+
199255
//! parses the given file and returns the python code object, this can then be used to call evalCode()
200256
PythonQtObjectPtr parseFile(const QString& filename);
201257

@@ -209,23 +265,11 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
209265
//! evaluates the given script code from file
210266
void evalFile(PyObject* object, const QString& filename);
211267

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+
//@}
227269

228-
//@{ Signal handlers
270+
//---------------------------------------------------------------------------
271+
//! \name Signal Handlers
272+
//@{
229273

230274
//! add a signal handler to the given \c signal of \c obj and connect it to a callable \c objectname in module
231275
bool addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname);
@@ -241,7 +285,9 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
241285

242286
//@}
243287

244-
//@{ Variable access
288+
//---------------------------------------------------------------------------
289+
//! \name Variable access
290+
//@{
245291

246292
//! add the given \c qObject to the python \c object as a variable with \c name (it can be removed via clearVariable)
247293
void addObject(PyObject* object, const QString& name, QObject* qObject);
@@ -264,7 +310,9 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
264310

265311
//@}
266312

267-
//@{ Calling of python callables
313+
//---------------------------------------------------------------------------
314+
//! \name Calling Python Objects
315+
//@{
268316

269317
//! call the given python \c callable in the scope of object, returns the result converted to a QVariant
270318
QVariant call(PyObject* object, const QString& callable, const QVariantList& args = QVariantList());
@@ -277,8 +325,9 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
277325

278326
//@}
279327

280-
//@{ Decorations, constructors, wrappers...
281-
328+
//---------------------------------------------------------------------------
329+
//! \name Decorations, Constructors, Wrappers...
330+
//@{
282331

283332
//! add an object whose slots will be used as decorator slots for
284333
//! other QObjects or CPP classes. The slots need to follow the
@@ -333,8 +382,10 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
333382

334383
//@}
335384

336-
//@{ Custom importer (to replace internal import implementation of python)
337-
385+
//---------------------------------------------------------------------------
386+
//! \name Custom Importer
387+
//@{
388+
338389
//! replace the internal import implementation and use the supplied interface to load files (both py and pyc files)
339390
//! (this method should be called directly after initialization of init() and before calling overwriteSysPath().
340391
//! On the first call to this method, it will install a generic PythonQt importer in Pythons "path_hooks".
@@ -360,14 +411,18 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
360411
//! get paths that the importer should ignore
361412
const QStringList& getImporterIgnorePaths();
362413

414+
//! get access to the file importer (if set)
415+
static PythonQtImportFileInterface* importInterface();
416+
363417
//@}
364418

419+
//---------------------------------------------------------------------------
420+
//! \name Other Stuff
421+
//@{
422+
365423
//! get access to internal data (should not be used on the public API, but is used by some C functions)
366424
static PythonQtPrivate* priv() { return _self->_p; }
367425

368-
//! get access to the file importer (if set)
369-
static PythonQtImportFileInterface* importInterface();
370-
371426
//! handle a python error, call this when a python function fails. If no error occurred, it returns false.
372427
//! The error is currently just output to the python stderr, future version might implement better trace printing
373428
bool handleError();
@@ -380,6 +435,15 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
380435
//! call the callback if it is set
381436
static void qObjectNoLongerWrappedCB(QObject* o);
382437

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+
383447
signals:
384448
//! emitted when python outputs something to stdout (and redirection is turned on)
385449
void pythonStdOut(const QString& str);
@@ -389,15 +453,6 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
389453
//! emitted when help() is called on a PythonQt object and \c ExternalHelp is enabled
390454
void pythonHelpRequest(const QByteArray& cppClassName);
391455

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-
401456
private:
402457
void initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName);
403458

0 commit comments

Comments
 (0)