@@ -75,7 +75,7 @@ template<class T> void PythonQtSetInstanceWrapperOnShell(void* object, PythonQtI
7575
7676// ! returns the offset that needs to be added to upcast an object of type T1 to T2
7777template <class T1 , class T2 > int PythonQtUpcastingOffset () {
78- return (((char *)(static_cast <T2*>(reinterpret_cast <T1*>(0x100 )))) - ((char *)reinterpret_cast <T1*>(0x100 )));
78+ return (((char *)(static_cast <T2*>(reinterpret_cast <T1*>(0x100 )))) - ((char *)reinterpret_cast <T1*>(0x100 )));
7979}
8080
8181// ! callback to create a QObject lazily
@@ -143,10 +143,20 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
143143
144144 };
145145
146+ // ! enum for profiling callback
147+ enum ProfilingCallbackState {
148+ Enter = 1 ,
149+ Leave = 2
150+ };
151+
152+ // ! callback for profiling. className and methodName are only passed when state == Enter, otherwise
153+ // ! they are NULL.
154+ typedef void ProfilingCB (ProfilingCallbackState state, const char * className, const char * methodName);
155+
146156 // ---------------------------------------------------------------------------
147157 // ! \name Singleton Initialization
148158 // @{
149-
159+
150160 // ! initialize the python qt binding (flags are a or combination of PythonQt::InitFlags), if \c pythonQtModuleName is given
151161 // ! it defines the name of the python module that PythonQt will add, otherwise "PythonQt" is used.
152162 // ! This can be used to e.g. pass in PySide or PyQt4 to make it more compatible.
@@ -159,7 +169,7 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
159169 static PythonQt* self () { return _self; }
160170
161171 // @}
162-
172+
163173 // ! defines the object types for introspection
164174 enum ObjectType {
165175 Class,
@@ -186,13 +196,13 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
186196 // ! to a module later on.
187197 // ! The user needs to make sure that the \c name is unique in the python module dictionary.
188198 PythonQtObjectPtr createModuleFromFile (const QString& name, const QString& filename);
189-
199+
190200 // ! creates the new module \c name and evaluates the given script in the context of that module.
191201 // ! If the \c script is empty, the module contains no initial code. You can use evalScript/evalCode to add code
192202 // ! to a module later on.
193203 // ! The user needs to make sure that the \c name is unique in the python module dictionary.
194204 PythonQtObjectPtr createModuleFromScript (const QString& name, const QString& script = QString());
195-
205+
196206 // ! create a uniquely named module, you can use evalFile or evalScript to populate the module with
197207 // ! script code
198208 PythonQtObjectPtr createUniqueModule ();
@@ -213,20 +223,20 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
213223 void setModuleImportPath (PyObject* module , const QStringList& paths);
214224
215225 // @}
216-
226+
217227 // ---------------------------------------------------------------------------
218228 // ! \name Registering Classes
219229 // @{
220-
230+
221231 // ! registers a QObject derived class to PythonQt (this is implicitly called by addObject as well)
222232 /* Since Qt4 does not offer a way to detect if a given classname is derived from QObject and thus has a QMetaObject,
223233 you MUST register all your QObject derived classes here when you want them to be detected in signal and slot calls */
224234 void registerClass (const QMetaObject* metaobject, const char * package = NULL , PythonQtQObjectCreatorFunctionCB* wrapperCreator = NULL , PythonQtShellSetInstanceWrapperCB* shell = NULL );
225-
235+
226236 // ! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants
227237 // ! (ownership of wrapper is passed to PythonQt)
228238 /* ! Make sure that you have done a qRegisterMetaType first, if typeName is a user type!
229-
239+
230240 This will add a wrapper object that is used to make calls to the given classname \c typeName.
231241 All slots that take a pointer to typeName as the first argument will be callable from Python on
232242 a variant object that contains such a type.
@@ -251,7 +261,7 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
251261 // ---------------------------------------------------------------------------
252262 // ! \name Script Parsing and Evaluation
253263 // @{
254-
264+
255265 // ! parses the given file and returns the python code object, this can then be used to call evalCode()
256266 PythonQtObjectPtr parseFile (const QString& filename);
257267
@@ -287,7 +297,7 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
287297
288298 // ---------------------------------------------------------------------------
289299 // ! \name Variable access
290- // @{
300+ // @{
291301
292302 // ! add the given \c qObject to the python \c object as a variable with \c name (it can be removed via clearVariable)
293303 void addObject (PyObject* object, const QString& name, QObject* qObject);
@@ -312,7 +322,7 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
312322
313323 // ---------------------------------------------------------------------------
314324 // ! \name Calling Python Objects
315- // @{
325+ // @{
316326
317327 // ! call the given python \c callable in the scope of object, returns the result converted to a QVariant
318328 QVariant call (PyObject* object, const QString& callable, const QVariantList& args = QVariantList());
@@ -385,10 +395,10 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
385395 // ---------------------------------------------------------------------------
386396 // ! \name Custom Importer
387397 // @{
388-
398+
389399 // ! replace the internal import implementation and use the supplied interface to load files (both py and pyc files)
390400 // ! (this method should be called directly after initialization of init() and before calling overwriteSysPath().
391- // ! On the first call to this method, it will install a generic PythonQt importer in Pythons "path_hooks".
401+ // ! On the first call to this method, it will install a generic PythonQt importer in Pythons "path_hooks".
392402 // ! This is not reversible, so even setting setImporter(NULL) afterwards will
393403 // ! keep the custom PythonQt importer with a QFile default import interface.
394404 // ! Subsequent python import calls will make use of the passed importInterface
@@ -427,6 +437,10 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
427437 // ! The error is currently just output to the python stderr, future version might implement better trace printing
428438 bool handleError ();
429439
440+ // ! clear all NotFound entries on all class infos, to ensure that
441+ // ! newly loaded wrappers can add methods even when the object was wrapped by PythonQt before the wrapper was loaded
442+ void clearNotFoundCachedMembers ();
443+
430444 // ! set a callback that is called when a QObject with parent == NULL is wrapped by pythonqt
431445 void setQObjectWrappedCallback (PythonQtQObjectWrappedCB* cb);
432446 // ! set a callback that is called when a QObject with parent == NULL is no longer wrapped by pythonqt
@@ -437,11 +451,14 @@ class PYTHONQT_EXPORT PythonQt : public QObject {
437451
438452 // ! called by internal help methods
439453 PyObject* helpCalled (PythonQtClassInfo* info);
440-
454+
441455 // ! returns the found object or NULL
442456 // ! @return new reference
443457 PythonQtObjectPtr lookupObject (PyObject* module , const QString& name);
444458
459+ // ! sets a callback that is called before and after function calls for profiling
460+ void setProfilingCallback (ProfilingCB* cb);
461+
445462 // @}
446463
447464signals:
@@ -507,7 +524,7 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject {
507524
508525 // ! add a handler for polymorphic downcasting
509526 void addPolymorphicHandler (const char * typeName, PythonQtPolymorphicHandlerCB* cb);
510-
527+
511528 // ! lookup existing classinfo and return new if not yet present
512529 PythonQtClassInfo* lookupClassInfoAndCreateIfNotPresent (const char * typeName);
513530
@@ -528,13 +545,13 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject {
528545 // ! add a wrapper object for the given QMetaType typeName, also does an addClassDecorators() to add constructors for variants
529546 // ! (ownership of wrapper is passed to PythonQt)
530547 /* ! Make sure that you have done a qRegisterMetaType first, if typeName is a user type!
531-
548+
532549 This will add a wrapper object that is used to make calls to the given classname \c typeName.
533550 All slots that take a pointer to typeName as the first argument will be callable from Python on
534551 a variant object that contains such a type.
535552 */
536553 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 );
537-
554+
538555 // ! as an alternative to registerClass, you can tell PythonQt the names of QObject derived classes
539556 // ! and it will register the classes when it first sees a pointer to such a derived class
540557 void registerQObjectClassNames (const QStringList& names);
@@ -571,10 +588,13 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject {
571588
572589 // ! called by virtual overloads when a python return value can not be converted to the required Qt type
573590 void handleVirtualOverloadReturnError (const char * signature, const PythonQtMethodInfo* methodInfo, PyObject* result);
574-
591+
575592 // ! get access to the PythonQt module
576593 PythonQtObjectPtr pythonQtModule () const { return _pythonQtModule; }
577594
595+ // ! returns the profiling callback, which may be NULL
596+ PythonQt::ProfilingCB* profilingCB () const { return _profilingCB; }
597+
578598private:
579599 // ! Setup the shared library suffixes by getting them from the "imp" module.
580600 void setupSharedLibrarySuffixes ();
@@ -605,13 +625,13 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject {
605625
606626 // ! the name of the PythonQt python module
607627 QByteArray _pythonQtModuleName;
608-
628+
609629 // ! the importer interface (if set)
610630 PythonQtImportFileInterface* _importInterface;
611631
612632 // ! the default importer
613633 PythonQtQFileImporter* _defaultImporter;
614-
634+
615635 PythonQtQObjectNoLongerWrappedCB* _noLongerWrappedCB;
616636 PythonQtQObjectWrappedCB* _wrappedCB;
617637
@@ -625,6 +645,8 @@ class PYTHONQT_EXPORT PythonQtPrivate : public QObject {
625645
626646 PythonQtClassInfo* _currentClassInfoForClassWrapperCreation;
627647
648+ PythonQt::ProfilingCB* _profilingCB;
649+
628650 int _initFlags;
629651 int _PythonQtObjectPtr_metaId;
630652
0 commit comments