PythonQt.h
579 lines
| 24.3 KiB
| text/x-c
|
CLexer
/ src / PythonQt.h
ezust
|
r0 | #ifndef _PYTHONQT_H | ||
#define _PYTHONQT_H | ||||
/* | ||||
* | ||||
florianlink
|
r133 | * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved. | ||
ezust
|
r0 | * | ||
* This library is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU Lesser General Public | ||||
* License as published by the Free Software Foundation; either | ||||
* version 2.1 of the License, or (at your option) any later version. | ||||
* | ||||
* This library is distributed in the hope that it will be useful, | ||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||||
* Lesser General Public License for more details. | ||||
* | ||||
* Further, this software is distributed without any warranty that it is | ||||
* free of the rightful claim of any third person regarding infringement | ||||
* or the like. Any license provided herein, whether implied or | ||||
* otherwise, applies only to this software file. Patent licenses, if | ||||
* any, provided herein do not apply to combinations of this program with | ||||
* other software, or any other product whatsoever. | ||||
* | ||||
* You should have received a copy of the GNU Lesser General Public | ||||
* License along with this library; if not, write to the Free Software | ||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
* | ||||
florianlink
|
r133 | * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29, | ||
ezust
|
r0 | * 28359 Bremen, Germany or: | ||
* | ||||
* http://www.mevis.de | ||||
* | ||||
*/ | ||||
//---------------------------------------------------------------------------------- | ||||
/*! | ||||
// \file PythonQt.h | ||||
// \author Florian Link | ||||
// \author Last changed by $Author: florian $ | ||||
// \date 2006-05 | ||||
*/ | ||||
//---------------------------------------------------------------------------------- | ||||
#include "PythonQtSystem.h" | ||||
florianlink
|
r16 | #include "PythonQtInstanceWrapper.h" | ||
#include "PythonQtClassWrapper.h" | ||||
ezust
|
r0 | #include "PythonQtSlot.h" | ||
#include "PythonQtObjectPtr.h" | ||||
#include <QObject> | ||||
#include <QVariant> | ||||
#include <QList> | ||||
#include <QHash> | ||||
#include <QByteArray> | ||||
#include <QStringList> | ||||
#include <QtDebug> | ||||
#include <iostream> | ||||
class PythonQtClassInfo; | ||||
class PythonQtPrivate; | ||||
class PythonQtMethodInfo; | ||||
class PythonQtSignalReceiver; | ||||
class PythonQtImportFileInterface; | ||||
class PythonQtCppWrapperFactory; | ||||
florianlink
|
r8 | class PythonQtQFileImporter; | ||
ezust
|
r0 | |||
florianlink
|
r26 | typedef void PythonQtQObjectWrappedCB(QObject* object); | ||
typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object); | ||||
typedef void* PythonQtPolymorphicHandlerCB(const void *ptr, char **class_name); | ||||
florianlink
|
r4 | |||
florianlink
|
r24 | typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper); | ||
template<class T> void PythonQtSetInstanceWrapperOnShell(void* object, PythonQtInstanceWrapper* wrapper) { ((T*)object)->_wrapper = wrapper; }; | ||||
//! returns the offset that needs to be added to upcast an object of type T1 to T2 | ||||
template<class T1, class T2> int PythonQtUpcastingOffset() { | ||||
return (((char*)(static_cast<T2*>(reinterpret_cast<T1*>(0x100)))) - ((char*)reinterpret_cast<T1*>(0x100))); | ||||
} | ||||
//! callback to create a QObject lazily | ||||
florianlink
|
r10 | typedef QObject* PythonQtQObjectCreatorFunctionCB(); | ||
//! helper template to create a derived QObject class | ||||
template<class T> QObject* PythonQtCreateObject() { return new T(); }; | ||||
ezust
|
r0 | //! the main interface to the Python Qt binding, realized as a singleton | ||
class PYTHONQT_EXPORT PythonQt : public QObject { | ||||
Q_OBJECT | ||||
public: | ||||
enum InitFlags { | ||||
RedirectStdOut = 1, //!<< sets if the std out/err is redirected to pythonStdOut() and pythonStdErr() signals | ||||
IgnoreSiteModule = 2, //!<< sets if Python should ignore the site module | ||||
ExternalHelp = 4 //!<< sets if help() calls on PythonQt modules are forwarded to the pythonHelpRequest() signal | ||||
}; | ||||
florianlink
|
r119 | //! flags that tell PythonQt which operators to expect on the registered type | ||
enum TypeSlots { | ||||
Type_Add = 1, | ||||
Type_Subtract = 1 << 1, | ||||
Type_Multiply = 1 << 2, | ||||
Type_Divide = 1 << 3, | ||||
Type_Mod = 1 << 4, | ||||
Type_And = 1 << 5, | ||||
Type_Or = 1 << 6, | ||||
Type_Xor = 1 << 7, | ||||
Type_LShift = 1 << 8, | ||||
Type_RShift = 1 << 9, | ||||
Type_InplaceAdd = 1 << 10, | ||||
Type_InplaceSubtract = 1 << 11, | ||||
Type_InplaceMultiply = 1 << 12, | ||||
Type_InplaceDivide = 1 << 13, | ||||
Type_InplaceMod = 1 << 14, | ||||
Type_InplaceAnd = 1 << 15, | ||||
Type_InplaceOr = 1 << 16, | ||||
Type_InplaceXor = 1 << 17, | ||||
Type_InplaceLShift = 1 << 18, | ||||
Type_InplaceRShift = 1 << 19, | ||||
// Not yet needed/nicely mappable/generated... | ||||
//Type_Positive = 1 << 29, | ||||
//Type_Negative = 1 << 29, | ||||
//Type_Abs = 1 << 29, | ||||
//Type_Hash = 1 << 29, | ||||
Type_Invert = 1 << 29, | ||||
Type_RichCompare = 1 << 30, | ||||
Type_NonZero = 1 << 31, | ||||
}; | ||||
florianlink
|
r109 | //! initialize the python qt binding (flags are a or combination of InitFlags), if \c pythonQtModuleName is given | ||
//! it defines the name of the python module that PythonQt will add, otherwise "PythonQt" is used. | ||||
//! This can be used to e.g. pass in PySide or PyQt4 to make it more compatible. | ||||
static void init(int flags = IgnoreSiteModule | RedirectStdOut, const QByteArray& pythonQtModuleName = QByteArray()); | ||||
ezust
|
r0 | |||
//! cleanup | ||||
static void cleanup(); | ||||
//! get the singleton instance | ||||
static PythonQt* self() { return _self; } | ||||
//----------------------------------------------------------------------------- | ||||
// Public API: | ||||
//! defines the object types for introspection | ||||
enum ObjectType { | ||||
Class, | ||||
Function, | ||||
Variable, | ||||
Module, | ||||
Anything, | ||||
CallOverloads | ||||
}; | ||||
//! overwrite the python sys path (call this directly after PythonQt::init() if you want to change the std python sys path) | ||||
void overwriteSysPath(const QStringList& paths); | ||||
florianlink
|
r14 | //! prepend a path to sys.path to allow importing from it | ||
void addSysPath(const QString& path); | ||||
ezust
|
r0 | //! sets the __path__ list of a module to the given list (important for local imports) | ||
void setModuleImportPath(PyObject* module, const QStringList& paths); | ||||
//! get the __main__ module of python | ||||
PythonQtObjectPtr getMainModule(); | ||||
//! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well) | ||||
/* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject, | ||||
florianlink
|
r10 | you MUST register all your QObject derived classes here when you want them to be detected in signal and slot calls */ | ||
florianlink
|
r24 | void registerClass(const QMetaObject* metaobject, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL); | ||
florianlink
|
r10 | |||
//! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants | ||||
//! (ownership of wrapper is passed to PythonQt) | ||||
/*! Make sure that you have done a qRegisterMetaType first, if typeName is a user type! | ||||
This will add a wrapper object that is used to make calls to the given classname \c typeName. | ||||
All slots that take a pointer to typeName as the first argument will be callable from Python on | ||||
a variant object that contains such a type. | ||||
*/ | ||||
florianlink
|
r24 | void registerCPPClass(const char* typeName, const char* parentTypeName = NULL, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL); | ||
ezust
|
r0 | |||
//! as an alternative to registerClass, you can tell PythonQt the names of QObject derived classes | ||||
//! and it will register the classes when it first sees a pointer to such a derived class | ||||
void registerQObjectClassNames(const QStringList& names); | ||||
florianlink
|
r24 | //! add a parent class relation to the \c given typeName, the upcastingOffset is needed for multiple inheritance | ||
//! and can be calculated using PythonQtUpcastingOffset<type,parentType>(), which also verifies that | ||||
//! type is really derived from parentType. | ||||
//! Returns false if the typeName was not yet registered. | ||||
bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset=0); | ||||
florianlink
|
r26 | //! add a handler for polymorphic downcasting | ||
void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb); | ||||
ezust
|
r0 | //! parses the given file and returns the python code object, this can then be used to call evalCode() | ||
PythonQtObjectPtr parseFile(const QString& filename); | ||||
//! evaluates the given code and returns the result value (use Py_Compile etc. to create pycode from string) | ||||
//! If pycode is NULL, a python error is printed. | ||||
florianlink
|
r25 | QVariant evalCode(PyObject* object, PyObject* pycode); | ||
ezust
|
r0 | |||
//! evaluates the given script code and returns the result value | ||||
florianlink
|
r25 | QVariant evalScript(PyObject* object, const QString& script, int start = Py_file_input); | ||
ezust
|
r0 | |||
//! evaluates the given script code from file | ||||
florianlink
|
r25 | void evalFile(PyObject* object, const QString& filename); | ||
ezust
|
r0 | |||
florianlink
|
r4 | //! creates the new module \c name and evaluates the given file in the context of that module | ||
//! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code | ||||
//! to a module later on. | ||||
//! The user needs to make sure that the \c name is unique in the python module dictionary. | ||||
PythonQtObjectPtr createModuleFromFile(const QString& name, const QString& filename); | ||||
//! creates the new module \c name and evaluates the given script in the context of that module. | ||||
//! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code | ||||
//! to a module later on. | ||||
//! The user needs to make sure that the \c name is unique in the python module dictionary. | ||||
PythonQtObjectPtr createModuleFromScript(const QString& name, const QString& script = QString()); | ||||
//! create a uniquely named module, you can use evalFile or evalScript to populate the module with | ||||
//! script code | ||||
PythonQtObjectPtr createUniqueModule(); | ||||
ezust
|
r0 | //@{ Signal handlers | ||
//! add a signal handler to the given \c signal of \c obj and connect it to a callable \c objectname in module | ||||
bool addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname); | ||||
//! remove a signal handler from the given \c signal of \c obj | ||||
bool removeSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname); | ||||
//! add a signal handler to the given \c signal of \c obj and connect it to a callable \c receiver | ||||
bool addSignalHandler(QObject* obj, const char* signal, PyObject* receiver); | ||||
//! remove a signal handler from the given \c signal of \c obj | ||||
bool removeSignalHandler(QObject* obj, const char* signal, PyObject* receiver); | ||||
//@} | ||||
//@{ Variable access | ||||
florianlink
|
r25 | //! add the given \c qObject to the python \c object as a variable with \c name (it can be removed via clearVariable) | ||
void addObject(PyObject* object, const QString& name, QObject* qObject); | ||||
ezust
|
r0 | |||
florianlink
|
r25 | //! add the given variable to the object | ||
void addVariable(PyObject* object, const QString& name, const QVariant& v); | ||||
ezust
|
r0 | |||
//! remove the given variable | ||||
void removeVariable(PyObject* module, const QString& name); | ||||
florianlink
|
r25 | //! get the variable with the \c name of the \c object, returns an invalid QVariant on error | ||
QVariant getVariable(PyObject* object, const QString& name); | ||||
ezust
|
r0 | |||
florianlink
|
r25 | //! read vars etc. in scope of an \c object, optional looking inside of an object \c objectname | ||
QStringList introspection(PyObject* object, const QString& objectname, ObjectType type); | ||||
ezust
|
r0 | |||
//! returns the found callable object or NULL | ||||
//! @return new reference | ||||
florianlink
|
r25 | PythonQtObjectPtr lookupCallable(PyObject* object, const QString& name); | ||
ezust
|
r0 | |||
//@} | ||||
//@{ Calling of python callables | ||||
florianlink
|
r36 | //! call the given python \c callable in the scope of object, returns the result converted to a QVariant | ||
QVariant call(PyObject* object, const QString& callable, const QVariantList& args = QVariantList()); | ||||
//! call the given python object, returns the result converted to a QVariant | ||||
QVariant call(PyObject* callable, const QVariantList& args = QVariantList()); | ||||
ezust
|
r0 | |||
florianlink
|
r82 | //! call the given python object, returns the result as new PyObject | ||
PyObject* callAndReturnPyObject(PyObject* callable, const QVariantList& args = QVariantList()); | ||||
ezust
|
r0 | //@} | ||
//@{ Decorations, constructors, wrappers... | ||||
//! add an object whose slots will be used as decorator slots for | ||||
//! other QObjects or CPP classes. The slots need to follow the | ||||
//! convention that the first argument is a pointer to the wrapped object. | ||||
//! (ownership is passed to PythonQt) | ||||
/*! | ||||
Example: | ||||
A slot with the signature | ||||
\code | ||||
bool doSomething(QWidget* w, int a) | ||||
\endcode | ||||
will extend QWidget instances (and derived classes) with a "bool doSomething(int a)" slot | ||||
that will be called with the concrete instance as first argument. | ||||
So in Python you can now e.g. call | ||||
\code | ||||
someWidget.doSomething(12) | ||||
\endcode | ||||
without QWidget really having this method. This allows to easily make normal methods | ||||
of Qt classes callable by forwarding them with such decorator slots | ||||
or to make CPP classes (which are not derived from QObject) callable from Python. | ||||
*/ | ||||
void addInstanceDecorators(QObject* o); | ||||
//! add an object whose slots will be used as decorator slots for | ||||
//! class objects (ownership is passed to PythonQt) | ||||
/*! | ||||
The slots need to follow the following convention: | ||||
- SomeClass* new_SomeClass(...) | ||||
- QVariant new_SomeClass(...) | ||||
- void delete_SomeClass(SomeClass*) | ||||
- ... static_SomeClass_someName(...) | ||||
This will add: | ||||
- a constructor | ||||
- a constructor which generates a QVariant | ||||
- a destructor (only useful for CPP objects) | ||||
- a static decorator slot which will be available on the MetaObject (visible in PythonQt module) | ||||
*/ | ||||
void addClassDecorators(QObject* o); | ||||
//! this will add the object both as class and instance decorator (ownership is passed to PythonQt) | ||||
void addDecorators(QObject* o); | ||||
//! add the given factory to PythonQt (ownership stays with caller) | ||||
void addWrapperFactory(PythonQtCppWrapperFactory* factory); | ||||
//@} | ||||
//@{ Custom importer (to replace internal import implementation of python) | ||||
//! replace the internal import implementation and use the supplied interface to load files (both py and pyc files) | ||||
//! (this method should be called directly after initialization of init() and before calling overwriteSysPath(). | ||||
florianlink
|
r8 | //! On the first call to this method, it will install a generic PythonQt importer in Pythons "path_hooks". | ||
//! This is not reversible, so even setting setImporter(NULL) afterwards will | ||||
//! keep the custom PythonQt importer with a QFile default import interface. | ||||
//! Subsequent python import calls will make use of the passed importInterface | ||||
//! which forwards all import calls to the given \c importInterface. | ||||
//! Passing NULL will install a default QFile importer. | ||||
//! (\c importInterface ownership stays with caller) | ||||
ezust
|
r0 | void setImporter(PythonQtImportFileInterface* importInterface); | ||
florianlink
|
r8 | //! this installs the default QFile importer (which effectively does a setImporter(NULL)) | ||
//! (without calling setImporter or installDefaultImporter at least once, the default python import | ||||
//! mechanism is in place) | ||||
//! the default importer allows to import files from anywhere QFile can read from, | ||||
//! including the Qt resource system using ":". Keep in mind that you need to extend | ||||
//! "sys.path" with ":" to be able to import from the Qt resources. | ||||
void installDefaultImporter() { setImporter(NULL); } | ||||
ezust
|
r0 | //! set paths that the importer should ignore | ||
void setImporterIgnorePaths(const QStringList& paths); | ||||
//! get paths that the importer should ignore | ||||
const QStringList& getImporterIgnorePaths(); | ||||
//@} | ||||
//! get access to internal data (should not be used on the public API, but is used by some C functions) | ||||
static PythonQtPrivate* priv() { return _self->_p; } | ||||
//! get access to the file importer (if set) | ||||
static PythonQtImportFileInterface* importInterface(); | ||||
//! handle a python error, call this when a python function fails. If no error occurred, it returns false. | ||||
//! The error is currently just output to the python stderr, future version might implement better trace printing | ||||
bool handleError(); | ||||
florianlink
|
r4 | //! set a callback that is called when a QObject with parent == NULL is wrapped by pythonqt | ||
void setQObjectWrappedCallback(PythonQtQObjectWrappedCB* cb); | ||||
//! set a callback that is called when a QObject with parent == NULL is no longer wrapped by pythonqt | ||||
void setQObjectNoLongerWrappedCallback(PythonQtQObjectNoLongerWrappedCB* cb); | ||||
//! call the callback if it is set | ||||
static void qObjectNoLongerWrappedCB(QObject* o); | ||||
ezust
|
r0 | signals: | ||
//! emitted when python outputs something to stdout (and redirection is turned on) | ||||
void pythonStdOut(const QString& str); | ||||
//! emitted when python outputs something to stderr (and redirection is turned on) | ||||
void pythonStdErr(const QString& str); | ||||
//! emitted when help() is called on a PythonQt object and \c ExternalHelp is enabled | ||||
void pythonHelpRequest(const QByteArray& cppClassName); | ||||
public: | ||||
//! called by internal help methods | ||||
PyObject* helpCalled(PythonQtClassInfo* info); | ||||
//! returns the found object or NULL | ||||
//! @return new reference | ||||
PythonQtObjectPtr lookupObject(PyObject* module, const QString& name); | ||||
private: | ||||
florianlink
|
r109 | void initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName); | ||
ezust
|
r0 | |||
//! callback for stdout redirection, emits pythonStdOut signal | ||||
static void stdOutRedirectCB(const QString& str); | ||||
//! callback for stderr redirection, emits pythonStdErr signal | ||||
static void stdErrRedirectCB(const QString& str); | ||||
//! get (and create if not available) the signal receiver of that QObject, signal receiver is made child of the passed \c obj | ||||
PythonQtSignalReceiver* getSignalReceiver(QObject* obj); | ||||
florianlink
|
r109 | PythonQt(int flags, const QByteArray& pythonQtModuleName); | ||
ezust
|
r0 | ~PythonQt(); | ||
static PythonQt* _self; | ||||
florianlink
|
r4 | static int _uniqueModuleCount; | ||
ezust
|
r0 | |||
PythonQtPrivate* _p; | ||||
}; | ||||
//! internal PythonQt details | ||||
florianlink
|
r24 | class PYTHONQT_EXPORT PythonQtPrivate : public QObject { | ||
ezust
|
r0 | |||
Q_OBJECT | ||||
public: | ||||
PythonQtPrivate(); | ||||
~PythonQtPrivate(); | ||||
florianlink
|
r10 | enum DecoratorTypes { | ||
StaticDecorator = 1, | ||||
ConstructorDecorator = 2, | ||||
DestructorDecorator = 4, | ||||
InstanceDecorator = 8, | ||||
AllDecorators = 0xffff | ||||
}; | ||||
florianlink
|
r82 | |||
//! get the suffixes that are used for shared libraries | ||||
const QStringList& sharedLibrarySuffixes() { return _sharedLibrarySuffixes; } | ||||
ezust
|
r0 | //! returns if the id is the id for PythonQtObjectPtr | ||
bool isPythonQtObjectPtrMetaId(int id) { return _PythonQtObjectPtr_metaId == id; } | ||||
florianlink
|
r18 | //! add the wrapper pointer (for reuse if the same obj appears while wrapper still exists) | ||
void addWrapperPointer(void* obj, PythonQtInstanceWrapper* wrapper); | ||||
ezust
|
r0 | //! remove the wrapper ptr again | ||
florianlink
|
r4 | void removeWrapperPointer(void* obj); | ||
florianlink
|
r24 | //! add parent class relation | ||
bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset); | ||||
florianlink
|
r26 | //! add a handler for polymorphic downcasting | ||
void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb); | ||||
florianlink
|
r24 | //! lookup existing classinfo and return new if not yet present | ||
PythonQtClassInfo* lookupClassInfoAndCreateIfNotPresent(const char* typeName); | ||||
florianlink
|
r4 | //! called when a signal emitting QObject is destroyed to remove the signal handler from the hash map | ||
void removeSignalEmitter(QObject* obj); | ||||
ezust
|
r0 | |||
//! wrap the given QObject into a Python object (or return existing wrapper!) | ||||
PyObject* wrapQObject(QObject* obj); | ||||
//! wrap the given ptr into a Python object (or return existing wrapper!) if there is a known QObject of that name or a known wrapper in the factory | ||||
PyObject* wrapPtr(void* ptr, const QByteArray& name); | ||||
//! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well) | ||||
/* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject, | ||||
you MUST register all your QObject derived classes here when you want them to be detected in signal and slot calls */ | ||||
florianlink
|
r119 | void registerClass(const QMetaObject* metaobject, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL, PyObject* module = NULL, int typeSlots = 0); | ||
ezust
|
r0 | |||
florianlink
|
r10 | //! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants | ||
//! (ownership of wrapper is passed to PythonQt) | ||||
/*! Make sure that you have done a qRegisterMetaType first, if typeName is a user type! | ||||
This will add a wrapper object that is used to make calls to the given classname \c typeName. | ||||
All slots that take a pointer to typeName as the first argument will be callable from Python on | ||||
a variant object that contains such a type. | ||||
*/ | ||||
florianlink
|
r119 | void registerCPPClass(const char* typeName, const char* parentTypeName = NULL, const char* package = NULL, PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL, PythonQtShellSetInstanceWrapperCB* shell = NULL, PyObject* module = NULL, int typeSlots = 0); | ||
florianlink
|
r10 | |||
ezust
|
r0 | //! as an alternative to registerClass, you can tell PythonQt the names of QObject derived classes | ||
//! and it will register the classes when it first sees a pointer to such a derived class | ||||
void registerQObjectClassNames(const QStringList& names); | ||||
//! add a decorator object | ||||
florianlink
|
r10 | void addDecorators(QObject* o, int decoTypes); | ||
ezust
|
r0 | |||
florianlink
|
r56 | //! helper method that creates a PythonQtClassWrapper object (returns a new reference) | ||
florianlink
|
r109 | PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, PyObject* module); | ||
ezust
|
r0 | |||
florianlink
|
r56 | //! create a new instance of the given enum type with given value (returns a new reference) | ||
static PyObject* createEnumValueInstance(PyObject* enumType, unsigned int enumValue); | ||||
//! helper that creates a new int derived class that represents the enum of the given name (returns a new reference) | ||||
static PyObject* createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject); | ||||
florianlink
|
r51 | |||
florianlink
|
r16 | //! helper method that creates a PythonQtInstanceWrapper object and registers it in the object map | ||
PythonQtInstanceWrapper* createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr = NULL); | ||||
ezust
|
r0 | |||
//! get the class info for a meta object (if available) | ||||
florianlink
|
r24 | PythonQtClassInfo* getClassInfo(const QMetaObject* meta) { return _knownClassInfos.value(meta->className()); } | ||
ezust
|
r0 | |||
florianlink
|
r10 | //! get the class info for a meta object (if available) | ||
florianlink
|
r24 | PythonQtClassInfo* getClassInfo(const QByteArray& className) { return _knownClassInfos.value(className); } | ||
ezust
|
r0 | |||
florianlink
|
r4 | //! creates the new module from the given pycode | ||
PythonQtObjectPtr createModule(const QString& name, PyObject* pycode); | ||||
ezust
|
r0 | |||
florianlink
|
r18 | //! get the current class info (for the next PythonQtClassWrapper that is created) and reset it to NULL again | ||
PythonQtClassInfo* currentClassInfoForClassWrapperCreation(); | ||||
//! the dummy tuple (which is empty and may be used to detected that a wrapper is called from internal wrapper creation | ||||
static PyObject* dummyTuple(); | ||||
florianlink
|
r67 | //! called by virtual overloads when a python return value can not be converted to the required Qt type | ||
void handleVirtualOverloadReturnError(const char* signature, const PythonQtMethodInfo* methodInfo, PyObject* result); | ||||
florianlink
|
r101 | //! get access to the PythonQt module | ||
PythonQtObjectPtr pythonQtModule() const { return _pythonQtModule; } | ||||
ezust
|
r0 | private: | ||
florianlink
|
r82 | //! Setup the shared library suffixes by getting them from the "imp" module. | ||
void setupSharedLibrarySuffixes(); | ||||
florianlink
|
r18 | |||
florianlink
|
r24 | //! create a new pythonqt class wrapper and place it in the pythonqt module | ||
florianlink
|
r109 | void createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package, PyObject* module = NULL); | ||
florianlink
|
r18 | |||
florianlink
|
r19 | //! get/create new package module (the returned object is a borrowed reference) | ||
PyObject* packageByName(const char* name); | ||||
ezust
|
r0 | |||
florianlink
|
r4 | //! get the wrapper for a given pointer (and remove a wrapper of an already destroyed qobject) | ||
florianlink
|
r16 | PythonQtInstanceWrapper* findWrapperAndRemoveUnused(void* obj); | ||
florianlink
|
r4 | |||
ezust
|
r0 | //! stores pointer to PyObject mapping of wrapped QObjects AND C++ objects | ||
florianlink
|
r24 | QHash<void* , PythonQtInstanceWrapper *> _wrappedObjects; | ||
ezust
|
r0 | |||
//! stores the meta info of known Qt classes | ||||
florianlink
|
r24 | QHash<QByteArray, PythonQtClassInfo *> _knownClassInfos; | ||
ezust
|
r0 | |||
//! names of qobject derived classes that can be casted to qobject savely | ||||
QHash<QByteArray, bool> _knownQObjectClassNames; | ||||
//! stores signal receivers for QObjects | ||||
QHash<QObject* , PythonQtSignalReceiver *> _signalReceivers; | ||||
//! the PythonQt python module | ||||
PythonQtObjectPtr _pythonQtModule; | ||||
florianlink
|
r109 | //! the name of the PythonQt python module | ||
QByteArray _pythonQtModuleName; | ||||
ezust
|
r0 | //! the importer interface (if set) | ||
PythonQtImportFileInterface* _importInterface; | ||||
florianlink
|
r8 | //! the default importer | ||
PythonQtQFileImporter* _defaultImporter; | ||||
florianlink
|
r4 | PythonQtQObjectNoLongerWrappedCB* _noLongerWrappedCB; | ||
PythonQtQObjectWrappedCB* _wrappedCB; | ||||
ezust
|
r0 | QStringList _importIgnorePaths; | ||
florianlink
|
r82 | QStringList _sharedLibrarySuffixes; | ||
ezust
|
r0 | |||
//! the cpp object wrapper factories | ||||
QList<PythonQtCppWrapperFactory*> _cppWrapperFactories; | ||||
florianlink
|
r19 | QHash<QByteArray, PyObject*> _packages; | ||
ezust
|
r0 | |||
florianlink
|
r18 | PythonQtClassInfo* _currentClassInfoForClassWrapperCreation; | ||
ezust
|
r0 | int _initFlags; | ||
int _PythonQtObjectPtr_metaId; | ||||
friend class PythonQt; | ||||
}; | ||||
#endif | ||||