##// END OF EJS Templates
performance improvement (merged from MeVisLab PythonQt)...
performance improvement (merged from MeVisLab PythonQt) git-svn-id: svn://svn.code.sf.net/p/pythonqt/code/trunk@239 ea8d5007-eb21-0410-b261-ccb3ea6e24a9

File last commit:

r198:0dcd933258e0
r198:0dcd933258e0
Show More
PythonQt.cpp
1795 lines | 59.0 KiB | text/x-c | CppLexer
ezust
reorganized SVN tree into branches, tags and trunk...
r0 /*
*
florianlink
updated old license information and current date...
r133 * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
ezust
reorganized SVN tree into branches, tags and trunk...
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
updated old license information and current date...
r133 * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
ezust
reorganized SVN tree into branches, tags and trunk...
r0 * 28359 Bremen, Germany or:
*
* http://www.mevis.de
*
*/
//----------------------------------------------------------------------------------
/*!
// \file PythonQt.cpp
// \author Florian Link
// \author Last changed by $Author: florian $
// \date 2006-05
*/
//----------------------------------------------------------------------------------
#include "PythonQt.h"
#include "PythonQtImporter.h"
#include "PythonQtClassInfo.h"
#include "PythonQtMethodInfo.h"
florianlink
Updated from current MeVisLab development...
r173 #include "PythonQtSignal.h"
ezust
reorganized SVN tree into branches, tags and trunk...
r0 #include "PythonQtSignalReceiver.h"
#include "PythonQtConversion.h"
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 #include "PythonQtStdIn.h"
ezust
reorganized SVN tree into branches, tags and trunk...
r0 #include "PythonQtStdOut.h"
#include "PythonQtCppWrapperFactory.h"
#include "PythonQtVariants.h"
#include "PythonQtStdDecorators.h"
florianlink
- removed warnings...
r8 #include "PythonQtQFileImporter.h"
ezust
reorganized SVN tree into branches, tags and trunk...
r0 #include <pydebug.h>
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 #include <vector>
ezust
reorganized SVN tree into branches, tags and trunk...
r0
PythonQt* PythonQt::_self = NULL;
florianlink
merged in features from the MeVisLab repository...
r4 int PythonQt::_uniqueModuleCount = 0;
ezust
reorganized SVN tree into branches, tags and trunk...
r0
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 void PythonQt_init_QtGuiBuiltin(PyObject*);
void PythonQt_init_QtCoreBuiltin(PyObject*);
florianlink
updated to newly generated files...
r98
florianlink
added support for QStringRef as return value...
r191
PyObject* PythonQtConvertFromStringRef(const void* inObject, int /*metaTypeId*/)
{
return PythonQtConv::QStringToPyObject(((QStringRef*)inObject)->toString());
}
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 void PythonQt::init(int flags, const QByteArray& pythonQtModuleName)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
if (!_self) {
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 _self = new PythonQt(flags, pythonQtModuleName);
florianlink
moved setupSharedLibrarySuffixes() to a place where PythonQt::self() is initialized...
r194
PythonQt::priv()->setupSharedLibrarySuffixes();
ezust
reorganized SVN tree into branches, tags and trunk...
r0
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PythonQtMethodInfo::addParameterTypeAlias("QObjectList", "QList<QObject*>");
qRegisterMetaType<QList<QObject*> >("QList<void*>");
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added support for QStringRef as return value...
r191 int stringRefId = qRegisterMetaType<QStringRef>("QStringRef");
PythonQtConv::registerMetaTypeToPythonConverter(stringRefId, PythonQtConvertFromStringRef);
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PythonQtRegisterToolClassesTemplateConverter(int);
PythonQtRegisterToolClassesTemplateConverter(float);
PythonQtRegisterToolClassesTemplateConverter(double);
PythonQtRegisterToolClassesTemplateConverter(qint32);
PythonQtRegisterToolClassesTemplateConverter(quint32);
PythonQtRegisterToolClassesTemplateConverter(qint64);
PythonQtRegisterToolClassesTemplateConverter(quint64);
// TODO: which other POD types should be available for QList etc.
ezust
reorganized SVN tree into branches, tags and trunk...
r0
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PythonQt_init_QtCoreBuiltin(NULL);
PythonQt_init_QtGuiBuiltin(NULL);
florianlink
updated to upstream state in MeVisLab repository...
r157
florianlink
merged various changes from MeVisLab repository...
r180 PythonQt::self()->addDecorators(new PythonQtStdDecorators());
PythonQt::self()->registerCPPClass("QMetaObject",0, "QtCore", PythonQtCreateObject<PythonQtWrapper_QMetaObject>);
florianlink
removed implicit conversion of QByteArray to python str, use str() to convert to Python string or QByteArray::data()...
r125 PythonQtRegisterToolClassesTemplateConverter(QByteArray);
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PythonQtRegisterToolClassesTemplateConverter(QDate);
PythonQtRegisterToolClassesTemplateConverter(QTime);
PythonQtRegisterToolClassesTemplateConverter(QDateTime);
PythonQtRegisterToolClassesTemplateConverter(QUrl);
PythonQtRegisterToolClassesTemplateConverter(QLocale);
PythonQtRegisterToolClassesTemplateConverter(QRect);
PythonQtRegisterToolClassesTemplateConverter(QRectF);
PythonQtRegisterToolClassesTemplateConverter(QSize);
PythonQtRegisterToolClassesTemplateConverter(QSizeF);
PythonQtRegisterToolClassesTemplateConverter(QLine);
PythonQtRegisterToolClassesTemplateConverter(QLineF);
PythonQtRegisterToolClassesTemplateConverter(QPoint);
PythonQtRegisterToolClassesTemplateConverter(QPointF);
PythonQtRegisterToolClassesTemplateConverter(QRegExp);
PythonQtRegisterToolClassesTemplateConverter(QFont);
PythonQtRegisterToolClassesTemplateConverter(QPixmap);
PythonQtRegisterToolClassesTemplateConverter(QBrush);
PythonQtRegisterToolClassesTemplateConverter(QColor);
PythonQtRegisterToolClassesTemplateConverter(QPalette);
PythonQtRegisterToolClassesTemplateConverter(QIcon);
PythonQtRegisterToolClassesTemplateConverter(QImage);
PythonQtRegisterToolClassesTemplateConverter(QPolygon);
PythonQtRegisterToolClassesTemplateConverter(QRegion);
PythonQtRegisterToolClassesTemplateConverter(QBitmap);
PythonQtRegisterToolClassesTemplateConverter(QCursor);
PythonQtRegisterToolClassesTemplateConverter(QSizePolicy);
PythonQtRegisterToolClassesTemplateConverter(QKeySequence);
PythonQtRegisterToolClassesTemplateConverter(QPen);
PythonQtRegisterToolClassesTemplateConverter(QTextLength);
PythonQtRegisterToolClassesTemplateConverter(QTextFormat);
PythonQtRegisterToolClassesTemplateConverter(QMatrix);
PyObject* pack = PythonQt::priv()->packageByName("QtCore");
PyObject* pack2 = PythonQt::priv()->packageByName("Qt");
PyObject* qtNamespace = PythonQt::priv()->getClassInfo("Qt")->pythonQtClassWrapper();
const char* names[16] = {"SIGNAL", "SLOT", "qAbs", "qBound","qDebug","qWarning","qCritical","qFatal"
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 ,"qFuzzyCompare", "qMax","qMin","qRound","qRound64","qVersion","qrand","qsrand"};
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 for (unsigned int i = 0;i<16; i++) {
PyObject* obj = PyObject_GetAttrString(qtNamespace, names[i]);
if (obj) {
PyModule_AddObject(pack, names[i], obj);
Py_INCREF(obj);
PyModule_AddObject(pack2, names[i], obj);
} else {
std::cerr << "method not found " << names[i];
}
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 }
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQt::cleanup()
{
if (_self) {
delete _self;
_self = NULL;
}
}
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 PythonQt* PythonQt::self() { return _self; }
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
_p = new PythonQtPrivate;
_p->_initFlags = flags;
_p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr");
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added missing parenthesis...
r150 if ((flags & PythonAlreadyInitialized) == 0) {
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 Py_SetProgramName(const_cast<char*>("PythonQt"));
florianlink
improved docs...
r144 if (flags & IgnoreSiteModule) {
// this prevents the automatic importing of Python site files
Py_NoSiteFlag = 1;
}
Py_Initialize();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
updated to upstream state in MeVisLab repository...
r157
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // add our own python object types for qt object slots
if (PyType_Ready(&PythonQtSlotFunction_Type) < 0) {
std::cerr << "could not initialize PythonQtSlotFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
}
Py_INCREF(&PythonQtSlotFunction_Type);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
Updated from current MeVisLab development...
r173 if (PyType_Ready(&PythonQtSignalFunction_Type) < 0) {
std::cerr << "could not initialize PythonQtSignalFunction_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
}
Py_INCREF(&PythonQtSignalFunction_Type);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 // according to Python docs, set the type late here, since it can not safely be stored in the struct when declaring it
PythonQtClassWrapper_Type.tp_base = &PyType_Type;
// add our own python object types for classes
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 if (PyType_Ready(&PythonQtClassWrapper_Type) < 0) {
std::cerr << "could not initialize PythonQtClassWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 Py_INCREF(&PythonQtClassWrapper_Type);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18
// add our own python object types for CPP instances
if (PyType_Ready(&PythonQtInstanceWrapper_Type) < 0) {
PythonQt::handleError();
std::cerr << "could not initialize PythonQtInstanceWrapper_Type" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
}
Py_INCREF(&PythonQtInstanceWrapper_Type);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // add our own python object types for redirection of stdout
if (PyType_Ready(&PythonQtStdOutRedirectType) < 0) {
std::cerr << "could not initialize PythonQtStdOutRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
}
Py_INCREF(&PythonQtStdOutRedirectType);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 // add our own python object types for redirection of stdin
if (PyType_Ready(&PythonQtStdInRedirectType) < 0) {
std::cerr << "could not initialize PythonQtStdInRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
}
Py_INCREF(&PythonQtStdInRedirectType);
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 initPythonQtModule(flags & RedirectStdOut, pythonQtModuleName);
ezust
reorganized SVN tree into branches, tags and trunk...
r0
}
PythonQt::~PythonQt() {
delete _p;
_p = NULL;
}
PythonQtPrivate::~PythonQtPrivate() {
florianlink
- removed warnings...
r8 delete _defaultImporter;
_defaultImporter = NULL;
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24
florianlink
- removed warnings...
r8 {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 QHashIterator<QByteArray, PythonQtClassInfo *> i(_knownClassInfos);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 while (i.hasNext()) {
delete i.next().value();
}
}
PythonQtConv::global_valueStorage.clear();
PythonQtConv::global_ptrStorage.clear();
PythonQtConv::global_variantStorage.clear();
PythonQtMethodInfo::cleanupCachedMethodInfos();
}
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void * callbackData)
{
if (!callback)
{
std::cerr << "PythonQt::setRedirectStdInCallback - callback parameter is NULL !" << std::endl;
return;
}
PythonQtObjectPtr sys;
PythonQtObjectPtr in;
sys.setNewRef(PyImport_ImportModule("sys"));
// Backup original 'sys.stdin' if not yet done
PyRun_SimpleString("if not hasattr(sys, 'pythonqt_original_stdin'):"
"sys.pythonqt_original_stdin = sys.stdin");
in = PythonQtStdInRedirectType.tp_new(&PythonQtStdInRedirectType, NULL, NULL);
((PythonQtStdInRedirect*)in.object())->_cb = callback;
((PythonQtStdInRedirect*)in.object())->_callData = callbackData;
// replace the built in file objects with our own objects
PyModule_AddObject(sys, "stdin", in);
// Backup custom 'stdin' into 'pythonqt_stdin'
PyRun_SimpleString("sys.pythonqt_stdin = sys.stdin");
}
void PythonQt::setRedirectStdInCallbackEnabled(bool enabled)
{
if (enabled)
{
PyRun_SimpleString("if hasattr(sys, 'pythonqt_stdin'):"
"sys.stdin = sys.pythonqt_stdin");
}
else
{
PyRun_SimpleString("if hasattr(sys,'pythonqt_original_stdin'):"
"sys.stdin = sys.pythonqt_original_stdin");
}
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PythonQtImportFileInterface* PythonQt::importInterface()
{
florianlink
- removed warnings...
r8 return _self->_p->_importInterface?_self->_p->_importInterface:_self->_p->_defaultImporter;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
merged in features from the MeVisLab repository...
r4 void PythonQt::qObjectNoLongerWrappedCB(QObject* o)
{
if (_self->_p->_noLongerWrappedCB) {
(*_self->_p->_noLongerWrappedCB)(o);
};
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 void PythonQt::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 _p->registerClass(metaobject, package, wrapperCreator, shell);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
florianlink
added support for operators and rich compare...
r119 void PythonQtPrivate::registerClass(const QMetaObject* metaobject, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell, PyObject* module, int typeSlots)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
// we register all classes in the hierarchy
const QMetaObject* m = metaobject;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 bool first = true;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 while (m) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(m->className());
if (!info->pythonQtClassWrapper()) {
florianlink
added support for operators and rich compare...
r119 info->setTypeSlots(typeSlots);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 info->setupQObject(m);
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 createPythonQtClassWrapper(info, package, module);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (m->superClass()) {
PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(m->superClass()->className());
info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo));
}
florianlink
updated to upstream state in MeVisLab repository...
r157 } else if (first && module) {
// There is a wrapper already, but if we got a module, we want to place the wrapper into that module as well,
// since it might have been placed into "private" earlier on.
// If the wrapper was already added to module before, it is just readded, which does no harm.
PyObject* classWrapper = info->pythonQtClassWrapper();
// AddObject steals a reference, so we need to INCREF
Py_INCREF(classWrapper);
PyModule_AddObject(module, info->className(), classWrapper);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
if (first) {
first = false;
if (wrapperCreator) {
info->setDecoratorProvider(wrapperCreator);
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (shell) {
info->setShellSetInstanceWrapperCB(shell);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
m = m->superClass();
}
}
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const char* package, PyObject* module)
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 {
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PyObject* pack = module?module:packageByName(package);
PyObject* pyobj = (PyObject*)createNewPythonQtClassWrapper(info, pack);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PyModule_AddObject(pack, info->className(), pyobj);
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 if (!module && package && strncmp(package,"Qt",2)==0) {
florianlink
fixed bad reference counting and borrowed references...
r19 // since PyModule_AddObject steals the reference, we need a incref once more...
Py_INCREF(pyobj);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 // put all qt objects into Qt as well
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PyModule_AddObject(packageByName("Qt"), info->className(), pyobj);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 }
info->setPythonQtClassWrapper(pyobj);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PyObject* PythonQtPrivate::wrapQObject(QObject* obj)
{
if (!obj) {
Py_INCREF(Py_None);
return Py_None;
}
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(obj);
florianlink
merged from MeVisLab: fixed wrong reuse of C++ wrappers, added unicode print support to sys.stdout redirection...
r183 if (wrap && wrap->_wrappedPtr) {
// uh oh, we want to wrap a QObject, but have a C++ wrapper at that
// address, so probably that C++ wrapper has been deleted earlier and
// now we see a QObject with the same address.
// Do not use the old wrapper anymore.
wrap = NULL;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (!wrap) {
// smuggling it in...
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* classInfo = _knownClassInfos.value(obj->metaObject()->className());
if (!classInfo || classInfo->pythonQtClassWrapper()==NULL) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 registerClass(obj->metaObject());
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 classInfo = _knownClassInfos.value(obj->metaObject()->className());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 wrap = createNewPythonQtInstanceWrapper(obj, classInfo);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 // mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
Py_INCREF(wrap);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 // mlabDebugConst("MLABPython","qobject wrapper reused " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
return (PyObject*)wrap;
}
PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
{
if (!ptr) {
Py_INCREF(Py_None);
return Py_None;
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 PythonQtInstanceWrapper* wrap = findWrapperAndRemoveUnused(ptr);
florianlink
merged from MeVisLab: fixed wrong reuse of C++ wrappers, added unicode print support to sys.stdout redirection...
r183 PythonQtInstanceWrapper* possibleStillAliveWrapper = NULL;
if (wrap && wrap->_wrappedPtr) {
// we have a previous C++ wrapper... if the wrapper is for a C++ object,
// we are not sure if it may have been deleted earlier and we just see the same C++
// pointer once again. To make sure that we do not reuse a wrapper of the wrong type,
// we compare the classInfo() pointer and only reuse the wrapper if it has the same
// info. This is only needed for non-QObjects, since we know it when a QObject gets deleted.
possibleStillAliveWrapper = wrap;
wrap = NULL;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (!wrap) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* info = _knownClassInfos.value(name);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (!info) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 // maybe it is a PyObject, which we can return directly
if (name == "PyObject") {
PyObject* p = (PyObject*)ptr;
Py_INCREF(p);
return p;
}
florianlink
merged from MeVisLab: fixed wrong reuse of C++ wrappers, added unicode print support to sys.stdout redirection...
r183 // we do not know the metaobject yet, but we might know it by its name:
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (_knownQObjectClassNames.find(name)!=_knownQObjectClassNames.end()) {
// yes, we know it, so we can convert to QObject
QObject* qptr = (QObject*)ptr;
registerClass(qptr->metaObject());
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 info = _knownClassInfos.value(qptr->metaObject()->className());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (info && info->isQObject()) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QObject* qptr = (QObject*)ptr;
// if the object is a derived object, we want to switch the class info to the one of the derived class:
if (name!=(qptr->metaObject()->className())) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 info = _knownClassInfos.value(qptr->metaObject()->className());
florianlink
performance improvement (merged from MeVisLab PythonQt)...
r198 if (!info) {
registerClass(qptr->metaObject());
info = _knownClassInfos.value(qptr->metaObject()->className());
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 wrap = createNewPythonQtInstanceWrapper(qptr, info);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 // mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 return (PyObject*)wrap;
}
florianlink
added initial version of foreign wrappers, needs testing...
r167 // not a known QObject, try to wrap via foreign wrapper factories
PyObject* foreignWrapper = NULL;
for (int i=0; i<_foreignWrapperFactories.size(); i++) {
foreignWrapper = _foreignWrapperFactories.at(i)->wrap(name, ptr);
if (foreignWrapper) {
return foreignWrapper;
}
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 // not a known QObject, so try our wrapper factory:
QObject* wrapper = NULL;
for (int i=0; i<_cppWrapperFactories.size(); i++) {
wrapper = _cppWrapperFactories.at(i)->create(name, ptr);
if (wrapper) {
break;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
added support for downcasting via polymorphic handlers...
r26
if (info) {
// try to downcast in the class hierarchy, which will modify info and ptr if it is successfull
ptr = info->castDownIfPossible(ptr, &info);
florianlink
Updated from current MeVisLab development...
r173
// if downcasting found out that the object is a QObject,
// handle it like one:
if (info && info->isQObject()) {
QObject* qptr = (QObject*)ptr;
// if the object is a derived object, we want to switch the class info to the one of the derived class:
if (name!=(qptr->metaObject()->className())) {
registerClass(qptr->metaObject());
info = _knownClassInfos.value(qptr->metaObject()->className());
}
wrap = createNewPythonQtInstanceWrapper(qptr, info);
// mlabDebugConst("MLABPython","new qobject wrapper added " << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
return (PyObject*)wrap;
}
florianlink
added support for downcasting via polymorphic handlers...
r26 }
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (!info || info->pythonQtClassWrapper()==NULL) {
// still unknown, register as CPP class
registerCPPClass(name.constData());
info = _knownClassInfos.value(name);
}
if (wrapper && (info->metaObject() != wrapper->metaObject())) {
// if we a have a QObject wrapper and the metaobjects do not match, set the metaobject again!
info->setMetaObject(wrapper->metaObject());
}
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161
florianlink
merged from MeVisLab: fixed wrong reuse of C++ wrappers, added unicode print support to sys.stdout redirection...
r183 if (possibleStillAliveWrapper && possibleStillAliveWrapper->classInfo() == info) {
wrap = possibleStillAliveWrapper;
Py_INCREF(wrap);
} else {
wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
Py_INCREF(wrap);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 //mlabDebugConst("MLABPython","c++ wrapper reused " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
return (PyObject*)wrap;
}
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 PyObject* PythonQtPrivate::dummyTuple() {
static PyObject* dummyTuple = NULL;
if (dummyTuple==NULL) {
dummyTuple = PyTuple_New(1);
PyTuple_SET_ITEM(dummyTuple, 0 , PyString_FromString("dummy"));
}
return dummyTuple;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 PythonQtInstanceWrapper* PythonQtPrivate::createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr) {
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 // call the associated class type to create a new instance...
PythonQtInstanceWrapper* result = (PythonQtInstanceWrapper*)PyObject_Call(info->pythonQtClassWrapper(), dummyTuple(), NULL);
ezust
reorganized SVN tree into branches, tags and trunk...
r0
florianlink
merged in features from the MeVisLab repository...
r4 result->setQObject(obj);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 result->_wrappedPtr = wrappedPtr;
result->_ownedByPythonQt = false;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 result->_useQMetaTypeDestroy = false;
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (wrappedPtr) {
_wrappedObjects.insert(wrappedPtr, result);
} else {
_wrappedObjects.insert(obj, result);
florianlink
merged in features from the MeVisLab repository...
r4 if (obj->parent()== NULL && _wrappedCB) {
// tell someone who is interested that the qobject is wrapped the first time, if it has no parent
(*_wrappedCB)(obj);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
return result;
}
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtClassInfo* info, PyObject* parentModule) {
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 PythonQtClassWrapper* result;
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18
PyObject* className = PyString_FromString(info->className());
PyObject* baseClasses = PyTuple_New(1);
PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PythonQtInstanceWrapper_Type);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 PyObject* typeDict = PyDict_New();
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 PyObject* moduleName = PyObject_GetAttrString(parentModule, "__name__");
PyDict_SetItemString(typeDict, "__module__", moduleName);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18
PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
// set the class info so that PythonQtClassWrapper_new can read it
_currentClassInfoForClassWrapperCreation = info;
// create the new type object by calling the type
result = (PythonQtClassWrapper *)PyObject_Call((PyObject *)&PythonQtClassWrapper_Type, args, NULL);
Py_DECREF(baseClasses);
Py_DECREF(typeDict);
Py_DECREF(args);
Py_DECREF(className);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 return result;
}
florianlink
support enum values on signals as well, all tests should succeed now...
r56 PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned int enumValue)
{
PyObject* args = Py_BuildValue("(i)", enumValue);
PyObject* result = PyObject_Call(enumType, args, NULL);
Py_DECREF(args);
return result;
}
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
PyObject* result;
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 PyObject* className = PyString_FromString(enumName);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 PyObject* baseClasses = PyTuple_New(1);
PyTuple_SET_ITEM(baseClasses, 0, (PyObject*)&PyInt_Type);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 PyObject* module = PyObject_GetAttrString(parentObject, "__module__");
PyObject* typeDict = PyDict_New();
PyDict_SetItemString(typeDict, "__module__", module);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 PyObject* args = Py_BuildValue("OOO", className, baseClasses, typeDict);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 // create the new int derived type object by calling the core type
result = PyObject_Call((PyObject *)&PyType_Type, args, NULL);
Py_DECREF(baseClasses);
Py_DECREF(typeDict);
Py_DECREF(args);
Py_DECREF(className);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
added enum wrapper classes derived from python int, so that enums are distinguishable from normal python integers. This will allow better overload handling e.g. of QColor constructors in the future...
r51 return result;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0
PythonQtSignalReceiver* PythonQt::getSignalReceiver(QObject* obj)
{
PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
if (!r) {
r = new PythonQtSignalReceiver(obj);
_p->_signalReceivers.insert(obj, r);
}
return r;
}
bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname)
{
bool flag = false;
PythonQtObjectPtr callable = lookupCallable(module, objectname);
if (callable) {
PythonQtSignalReceiver* r = getSignalReceiver(obj);
flag = r->addSignalHandler(signal, callable);
if (!flag) {
// signal not found
}
} else {
// callable not found
}
return flag;
}
bool PythonQt::addSignalHandler(QObject* obj, const char* signal, PyObject* receiver)
{
bool flag = false;
PythonQtSignalReceiver* r = getSignalReceiver(obj);
if (r) {
flag = r->addSignalHandler(signal, receiver);
}
return flag;
}
bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* module, const QString& objectname)
{
bool flag = false;
PythonQtObjectPtr callable = lookupCallable(module, objectname);
if (callable) {
PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
if (r) {
flag = r->removeSignalHandler(signal, callable);
}
} else {
// callable not found
}
return flag;
}
bool PythonQt::removeSignalHandler(QObject* obj, const char* signal, PyObject* receiver)
{
bool flag = false;
PythonQtSignalReceiver* r = _p->_signalReceivers[obj];
if (r) {
flag = r->removeSignalHandler(signal, receiver);
}
return flag;
}
PythonQtObjectPtr PythonQt::lookupCallable(PyObject* module, const QString& name)
{
PythonQtObjectPtr p = lookupObject(module, name);
if (p) {
if (PyCallable_Check(p)) {
return p;
}
}
PyErr_Clear();
return NULL;
}
PythonQtObjectPtr PythonQt::lookupObject(PyObject* module, const QString& name)
{
QStringList l = name.split('.');
PythonQtObjectPtr p = module;
PythonQtObjectPtr prev;
QByteArray b;
for (QStringList::ConstIterator i = l.begin(); i!=l.end() && p; ++i) {
prev = p;
b = (*i).toLatin1();
florianlink
changed to support dicts for variable lookup and eval...
r25 if (PyDict_Check(p)) {
p = PyDict_GetItemString(p, b.data());
} else {
p.setNewRef(PyObject_GetAttrString(p, b.data()));
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
PyErr_Clear();
return p;
}
PythonQtObjectPtr PythonQt::getMainModule() {
//both borrowed
PythonQtObjectPtr dict = PyImport_GetModuleDict();
return PyDict_GetItemString(dict, "__main__");
}
florianlink
improved docs...
r144 PythonQtObjectPtr PythonQt::importModule(const QString& name)
{
PythonQtObjectPtr mod;
mod.setNewRef(PyImport_ImportModule(name.toLatin1().constData()));
return mod;
}
florianlink
changed to support dicts for variable lookup and eval...
r25 QVariant PythonQt::evalCode(PyObject* object, PyObject* pycode) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QVariant result;
if (pycode) {
florianlink
changed to support dicts for variable lookup and eval...
r25 PyObject* dict = NULL;
florianlink
added support for QStringRef as return value...
r191 PyObject* globals = NULL;
florianlink
changed to support dicts for variable lookup and eval...
r25 if (PyModule_Check(object)) {
dict = PyModule_GetDict(object);
florianlink
added support for QStringRef as return value...
r191 globals = dict;
florianlink
changed to support dicts for variable lookup and eval...
r25 } else if (PyDict_Check(object)) {
dict = object;
florianlink
added support for QStringRef as return value...
r191 globals = dict;
} else {
dict = PyObject_GetAttrString(object, "__dict__");
globals = PyObject_GetAttrString(PyImport_ImportModule(PyString_AS_STRING(PyObject_GetAttrString(object, "__module__"))),"__dict__");
florianlink
changed to support dicts for variable lookup and eval...
r25 }
PyObject* r = NULL;
if (dict) {
florianlink
added support for QStringRef as return value...
r191 r = PyEval_EvalCode((PyCodeObject*)pycode, globals , dict);
florianlink
changed to support dicts for variable lookup and eval...
r25 }
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (r) {
result = PythonQtConv::PyObjToQVariant(r);
Py_DECREF(r);
} else {
handleError();
}
} else {
handleError();
}
return result;
}
florianlink
changed to support dicts for variable lookup and eval...
r25 QVariant PythonQt::evalScript(PyObject* object, const QString& script, int start)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
QVariant result;
PythonQtObjectPtr p;
florianlink
changed to support dicts for variable lookup and eval...
r25 PyObject* dict = NULL;
if (PyModule_Check(object)) {
dict = PyModule_GetDict(object);
} else if (PyDict_Check(object)) {
dict = object;
}
if (dict) {
p.setNewRef(PyRun_String(script.toLatin1().data(), start, dict, dict));
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (p) {
result = PythonQtConv::PyObjToQVariant(p);
} else {
handleError();
}
return result;
}
void PythonQt::evalFile(PyObject* module, const QString& filename)
{
PythonQtObjectPtr code = parseFile(filename);
if (code) {
evalCode(module, code);
} else {
handleError();
}
}
PythonQtObjectPtr PythonQt::parseFile(const QString& filename)
{
PythonQtObjectPtr p;
p.setNewRef(PythonQtImport::getCodeFromPyc(filename));
if (!p) {
handleError();
}
return p;
}
florianlink
merged in features from the MeVisLab repository...
r4 PythonQtObjectPtr PythonQt::createModuleFromFile(const QString& name, const QString& filename)
{
PythonQtObjectPtr code = parseFile(filename);
PythonQtObjectPtr module = _p->createModule(name, code);
return module;
}
PythonQtObjectPtr PythonQt::createModuleFromScript(const QString& name, const QString& script)
{
PyErr_Clear();
QString scriptCode = script;
if (scriptCode.isEmpty()) {
// we always need at least a linefeed
scriptCode = "\n";
}
PythonQtObjectPtr pycode;
pycode.setNewRef(Py_CompileString((char*)scriptCode.toLatin1().data(), "", Py_file_input));
PythonQtObjectPtr module = _p->createModule(name, pycode);
return module;
}
PythonQtObjectPtr PythonQt::createUniqueModule()
{
static QString pyQtStr("PythonQt_module");
QString moduleName = pyQtStr+QString::number(_uniqueModuleCount++);
return createModuleFromScript(moduleName);
}
florianlink
changed to support dicts for variable lookup and eval...
r25 void PythonQt::addObject(PyObject* object, const QString& name, QObject* qObject)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
changed to support dicts for variable lookup and eval...
r25 if (PyModule_Check(object)) {
PyModule_AddObject(object, name.toLatin1().data(), _p->wrapQObject(qObject));
} else if (PyDict_Check(object)) {
PyDict_SetItemString(object, name.toLatin1().data(), _p->wrapQObject(qObject));
} else {
PyObject_SetAttrString(object, name.toLatin1().data(), _p->wrapQObject(qObject));
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
changed to support dicts for variable lookup and eval...
r25 void PythonQt::addVariable(PyObject* object, const QString& name, const QVariant& v)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
changed to support dicts for variable lookup and eval...
r25 if (PyModule_Check(object)) {
PyModule_AddObject(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
} else if (PyDict_Check(object)) {
PyDict_SetItemString(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
} else {
PyObject_SetAttrString(object, name.toLatin1().data(), PythonQtConv::QVariantToPyObject(v));
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
changed to support dicts for variable lookup and eval...
r25 void PythonQt::removeVariable(PyObject* object, const QString& name)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
changed to support dicts for variable lookup and eval...
r25 if (PyDict_Check(object)) {
PyDict_DelItemString(object, name.toLatin1().data());
} else {
PyObject_DelAttrString(object, name.toLatin1().data());
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
changed to support dicts for variable lookup and eval...
r25 QVariant PythonQt::getVariable(PyObject* object, const QString& objectname)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
QVariant result;
florianlink
changed to support dicts for variable lookup and eval...
r25 PythonQtObjectPtr obj = lookupObject(object, objectname);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (obj) {
result = PythonQtConv::PyObjToQVariant(obj);
}
return result;
}
QStringList PythonQt::introspection(PyObject* module, const QString& objectname, PythonQt::ObjectType type)
{
QStringList results;
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PythonQtObjectPtr object;
if (objectname.isEmpty()) {
object = module;
} else {
object = lookupObject(module, objectname);
if (!object && type == CallOverloads) {
PyObject* dict = lookupObject(module, "__builtins__");
if (dict) {
object = PyDict_GetItemString(dict, objectname.toLatin1().constData());
}
}
}
if (object) {
florianlink
Updated from current MeVisLab development...
r173 results = introspectObject(object, type);
}
return results;
}
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
florianlink
Updated from current MeVisLab development...
r173 QStringList PythonQt::introspectObject(PyObject* object, ObjectType type)
{
QStringList results;
if (type == CallOverloads) {
if (PythonQtSlotFunction_Check(object)) {
PythonQtSlotFunctionObject* o = (PythonQtSlotFunctionObject*)object;
PythonQtSlotInfo* info = o->m_ml;
while (info) {
results << info->fullSignature();
info = info->nextInfo();
}
} else if (PythonQtSignalFunction_Check(object)) {
PythonQtSignalFunctionObject* o = (PythonQtSignalFunctionObject*)object;
PythonQtSlotInfo* info = o->m_ml;
while (info) {
results << info->fullSignature();
info = info->nextInfo();
}
} else if (object->ob_type == &PythonQtClassWrapper_Type) {
PythonQtClassWrapper* o = (PythonQtClassWrapper*)object;
PythonQtSlotInfo* info = o->classInfo()->constructors();
while (info) {
results << info->fullSignature();
info = info->nextInfo();
}
} else {
QString signature = _p->getSignature(object);
if (!signature.isEmpty()) {
results << signature;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
PyObject* doc = PyObject_GetAttrString(object, "__doc__");
if (doc) {
results << PyString_AsString(doc);
Py_DECREF(doc);
}
}
florianlink
Updated from current MeVisLab development...
r173 }
} else {
PyObject* keys = NULL;
bool isDict = false;
if (PyDict_Check(object)) {
keys = PyDict_Keys(object);
isDict = true;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
florianlink
Updated from current MeVisLab development...
r173 keys = PyObject_Dir(object);
}
if (keys) {
int count = PyList_Size(keys);
PyObject* key;
PyObject* value;
QString keystr;
for (int i = 0;i<count;i++) {
key = PyList_GetItem(keys,i);
if (isDict) {
value = PyDict_GetItem(object, key);
Py_INCREF(value);
} else {
value = PyObject_GetAttr(object, key);
}
if (!value) continue;
keystr = PyString_AsString(key);
static const QString underscoreStr("__tmp");
if (!keystr.startsWith(underscoreStr)) {
switch (type) {
case Anything:
results << keystr;
break;
case Class:
if (value->ob_type == &PyClass_Type || value->ob_type == &PyType_Type) {
results << keystr;
}
break;
case Variable:
if (value->ob_type != &PyClass_Type
&& value->ob_type != &PyCFunction_Type
&& value->ob_type != &PyFunction_Type
&& value->ob_type != &PyMethod_Type
&& value->ob_type != &PyModule_Type
&& value->ob_type != &PyType_Type
&& value->ob_type != &PythonQtSlotFunction_Type
) {
results << keystr;
}
break;
case Function:
if (value->ob_type == &PyCFunction_Type ||
value->ob_type == &PyFunction_Type ||
value->ob_type == &PyMethod_Type ||
value->ob_type == &PythonQtSlotFunction_Type
) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 results << keystr;
}
florianlink
Updated from current MeVisLab development...
r173 break;
case Module:
if (value->ob_type == &PyModule_Type) {
results << keystr;
}
break;
default:
std::cerr << "PythonQt: introspection: unknown case" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
Updated from current MeVisLab development...
r173 Py_DECREF(value);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
Updated from current MeVisLab development...
r173 Py_DECREF(keys);
}
florianlink
merged various changes from MeVisLab repository...
r180 if ((type == Anything) || (type == Variable)) {
if (object->ob_type == &PythonQtClassWrapper_Type) {
PythonQtClassWrapper* o = (PythonQtClassWrapper*)object;
PythonQtClassInfo* info = o->classInfo();
results += info->propertyList();
}
}
florianlink
Updated from current MeVisLab development...
r173 }
return results;
}
PyObject* PythonQt::getObjectByType(const QString& typeName)
{
PythonQtObjectPtr sys;
sys.setNewRef(PyImport_ImportModule("sys"));
PythonQtObjectPtr modules = lookupObject(sys, "modules");
Q_ASSERT(PyDict_Check(modules));
QStringList tmp = typeName.split(".");
QString simpleTypeName = tmp.takeLast();
QString moduleName = tmp.join(".");
PyObject* object = NULL;
PyObject* moduleObject = PyDict_GetItemString(modules, moduleName.toLatin1().constData());
if (moduleObject) {
object = PyObject_GetAttrString(moduleObject, simpleTypeName.toLatin1().constData());
}
if (!object) {
moduleObject = PyDict_GetItemString(modules, "__builtin__");
if (moduleObject) {
object = PyObject_GetAttrString(moduleObject, simpleTypeName.toLatin1().constData());
}
}
return object;
}
QStringList PythonQt::introspectType(const QString& typeName, ObjectType type)
{
QStringList results;
PyObject* object = getObjectByType(typeName);
if (!object) {
// the last item may be a member, split it away and try again
QStringList tmp = typeName.split(".");
QString memberName = tmp.takeLast();
florianlink
merged various changes from MeVisLab repository...
r180 QString typeName;
if (tmp.isEmpty()) {
typeName = memberName;
memberName.clear();
} else {
typeName = tmp.takeLast();
}
florianlink
Updated from current MeVisLab development...
r173 PyObject* typeObject = getObjectByType(typeName);
if (typeObject) {
object = PyObject_GetAttrString(typeObject, memberName.toLatin1().constData());
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
Updated from current MeVisLab development...
r173 if (object) {
results = introspectObject(object, type);
Py_DECREF(object);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 return results;
}
florianlink
added support for kwargs on call() methods...
r189 QVariant PythonQt::call(PyObject* object, const QString& name, const QVariantList& args, const QVariantMap& kwargs)
florianlink
- added call method that does a direct call on the ObjectType...
r36 {
PythonQtObjectPtr callable = lookupCallable(object, name);
if (callable) {
florianlink
added support for kwargs on call() methods...
r189 return call(callable, args, kwargs);
florianlink
- added call method that does a direct call on the ObjectType...
r36 } else {
return QVariant();
}
}
florianlink
added support for kwargs on call() methods...
r189 QVariant PythonQt::call(PyObject* callable, const QVariantList& args, const QVariantMap& kwargs)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
QVariant r;
florianlink
added sharedLibrarySuffixes and callAndReturnPyObject methods...
r82 PythonQtObjectPtr result;
florianlink
added support for kwargs on call() methods...
r189 result.setNewRef(callAndReturnPyObject(callable, args, kwargs));
florianlink
added sharedLibrarySuffixes and callAndReturnPyObject methods...
r82 if (result) {
r = PythonQtConv::PyObjToQVariant(result);
} else {
PythonQt::self()->handleError();
}
return r;
}
florianlink
added support for kwargs on call() methods...
r189 PyObject* PythonQt::callAndReturnPyObject(PyObject* callable, const QVariantList& args, const QVariantMap& kwargs)
florianlink
added sharedLibrarySuffixes and callAndReturnPyObject methods...
r82 {
PyObject* result = NULL;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (callable) {
florianlink
added support for kwargs on call() methods...
r189 bool err = false;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PythonQtObjectPtr pargs;
int count = args.size();
florianlink
added support for kwargs on call() methods...
r189 if ((count > 0) || (kwargs.count() > 0)) { // create empty tuple if kwargs are given
ezust
reorganized SVN tree into branches, tags and trunk...
r0 pargs.setNewRef(PyTuple_New(count));
florianlink
added support for kwargs on call() methods...
r189
// transform QVariant arguments to Python
for (int i = 0; i < count; i++) {
PyObject* arg = PythonQtConv::QVariantToPyObject(args.at(i));
if (arg) {
// steals reference, no unref
PyTuple_SetItem(pargs, i,arg);
} else {
err = true;
break;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
if (!err) {
florianlink
added support for kwargs on call() methods...
r189 if (kwargs.isEmpty()) {
// do a direct call if we have no keyword arguments
PyErr_Clear();
result = PyObject_CallObject(callable, pargs);
} else {
// convert keyword arguments to Python
PythonQtObjectPtr pkwargs;
pkwargs.setNewRef(PyDict_New());
QMapIterator<QString, QVariant> it(kwargs);
while (it.hasNext()) {
it.next();
PyObject* arg = PythonQtConv::QVariantToPyObject(it.value());
if (arg) {
PyDict_SetItemString(pkwargs, it.key().toLatin1().constData(), arg);
} else {
err = true;
break;
}
}
if (!err) {
// call with arguments and keyword arguments
PyErr_Clear();
result = PyObject_Call(callable, pargs, pkwargs);
}
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
added sharedLibrarySuffixes and callAndReturnPyObject methods...
r82 return result;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQt::addInstanceDecorators(QObject* o)
{
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 _p->addDecorators(o, PythonQtPrivate::InstanceDecorator);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQt::addClassDecorators(QObject* o)
{
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 _p->addDecorators(o, PythonQtPrivate::StaticDecorator | PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQt::addDecorators(QObject* o)
{
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 _p->addDecorators(o, PythonQtPrivate::AllDecorators);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQt::registerQObjectClassNames(const QStringList& names)
{
_p->registerQObjectClassNames(names);
}
void PythonQt::setImporter(PythonQtImportFileInterface* importInterface)
{
florianlink
- removed warnings...
r8 _p->_importInterface = importInterface;
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 PythonQtImport::init();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
void PythonQt::setImporterIgnorePaths(const QStringList& paths)
{
_p->_importIgnorePaths = paths;
}
const QStringList& PythonQt::getImporterIgnorePaths()
{
return _p->_importIgnorePaths;
}
void PythonQt::addWrapperFactory(PythonQtCppWrapperFactory* factory)
{
_p->_cppWrapperFactories.append(factory);
}
florianlink
added initial version of foreign wrappers, needs testing...
r167 void PythonQt::addWrapperFactory( PythonQtForeignWrapperFactory* factory )
{
_p->_foreignWrapperFactories.append(factory);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 //---------------------------------------------------------------------------------------------------
PythonQtPrivate::PythonQtPrivate()
{
_importInterface = NULL;
florianlink
- removed warnings...
r8 _defaultImporter = new PythonQtQFileImporter;
florianlink
merged in features from the MeVisLab repository...
r4 _noLongerWrappedCB = NULL;
_wrappedCB = NULL;
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 _currentClassInfoForClassWrapperCreation = NULL;
florianlink
updated to upstream state in MeVisLab repository...
r157 _profilingCB = NULL;
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 }
florianlink
added sharedLibrarySuffixes and callAndReturnPyObject methods...
r82 void PythonQtPrivate::setupSharedLibrarySuffixes()
{
_sharedLibrarySuffixes.clear();
PythonQtObjectPtr imp;
imp.setNewRef(PyImport_ImportModule("imp"));
int cExtensionCode = imp.getVariable("C_EXTENSION").toInt();
QVariant result = imp.call("get_suffixes");
florianlink
updated to upstream state in MeVisLab repository...
r157 #ifdef __linux
#ifdef _DEBUG
// First look for shared libraries with the '_d' suffix in debug mode on Linux.
// This is a workaround, because python does not append the '_d' suffix on Linux
// and would always load the release library otherwise.
_sharedLibrarySuffixes << "_d.so";
#endif
#endif
florianlink
added sharedLibrarySuffixes and callAndReturnPyObject methods...
r82 foreach (QVariant entry, result.toList()) {
QVariantList suffixEntry = entry.toList();
if (suffixEntry.count()==3) {
int code = suffixEntry.at(2).toInt();
if (code == cExtensionCode) {
_sharedLibrarySuffixes << suffixEntry.at(0).toString();
}
}
}
}
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 PythonQtClassInfo* PythonQtPrivate::currentClassInfoForClassWrapperCreation()
{
PythonQtClassInfo* info = _currentClassInfoForClassWrapperCreation;
_currentClassInfoForClassWrapperCreation = NULL;
return info;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
o->setParent(this);
int numMethods = o->metaObject()->methodCount();
for (int i = 0; i < numMethods; i++) {
QMetaMethod m = o->metaObject()->method(i);
if ((m.methodType() == QMetaMethod::Method ||
m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) {
if (qstrncmp(m.signature(), "new_", 4)==0) {
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 if ((decoTypes & ConstructorDecorator) == 0) continue;
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (info->parameters().at(0).pointerCount == 1) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QByteArray signature = m.signature();
QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 classInfo->addConstructor(newSlot);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
} else if (qstrncmp(m.signature(), "delete_", 7)==0) {
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 if ((decoTypes & DestructorDecorator) == 0) continue;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QByteArray signature = m.signature();
QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 classInfo->setDestructor(newSlot);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else if (qstrncmp(m.signature(), "static_", 7)==0) {
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 if ((decoTypes & StaticDecorator) == 0) continue;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QByteArray signature = m.signature();
florianlink
adapted to new generator files...
r193 QByteArray nameOfClass = signature.mid(7);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_'));
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 classInfo->addDecoratorSlot(newSlot);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 if ((decoTypes & InstanceDecorator) == 0) continue;
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (info->parameters().count()>1) {
PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (p.pointerCount==1) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name);
florianlink
cleanup of code and addition of (yet unused) classinfo passed to method/slot info to allow local enum support on creation...
r54 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::InstanceDecorator);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 classInfo->addDecoratorSlot(newSlot);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
}
}
}
}
void PythonQtPrivate::registerQObjectClassNames(const QStringList& names)
{
foreach(QString name, names) {
_knownQObjectClassNames.insert(name.toLatin1(), true);
}
}
florianlink
merged in features from the MeVisLab repository...
r4 void PythonQtPrivate::removeSignalEmitter(QObject* obj)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
merged in features from the MeVisLab repository...
r4 _signalReceivers.remove(obj);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
bool PythonQt::handleError()
{
bool flag = false;
if (PyErr_Occurred()) {
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // currently we just print the error and the stderr handler parses the errors
PyErr_Print();
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
ezust
reorganized SVN tree into branches, tags and trunk...
r0 /*
// EXTRA: the format of the ptype and ptraceback is not really documented, so I use PyErr_Print() above
PyObject *ptype;
PyObject *pvalue;
PyObject *ptraceback;
PyErr_Fetch( &ptype, &pvalue, &ptraceback);
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84
ezust
reorganized SVN tree into branches, tags and trunk...
r0 Py_XDECREF(ptype);
Py_XDECREF(pvalue);
Py_XDECREF(ptraceback);
*/
PyErr_Clear();
flag = true;
}
return flag;
}
florianlink
added PyLauncher example...
r14 void PythonQt::addSysPath(const QString& path)
{
PythonQtObjectPtr sys;
sys.setNewRef(PyImport_ImportModule("sys"));
PythonQtObjectPtr obj = lookupObject(sys, "path");
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 PyList_Insert(obj, 0, PythonQtConv::QStringToPyObject(path));
florianlink
added PyLauncher example...
r14 }
ezust
reorganized SVN tree into branches, tags and trunk...
r0 void PythonQt::overwriteSysPath(const QStringList& paths)
{
PythonQtObjectPtr sys;
sys.setNewRef(PyImport_ImportModule("sys"));
PyModule_AddObject(sys, "path", PythonQtConv::QStringListToPyList(paths));
}
void PythonQt::setModuleImportPath(PyObject* module, const QStringList& paths)
{
PyModule_AddObject(module, "__path__", PythonQtConv::QStringListToPyList(paths));
}
void PythonQt::stdOutRedirectCB(const QString& str)
{
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 if (!PythonQt::self()) {
std::cout << str.toLatin1().data() << std::endl;
return;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 emit PythonQt::self()->pythonStdOut(str);
}
void PythonQt::stdErrRedirectCB(const QString& str)
{
florianlink
merged contributions from https://github.com/commontk/PythonQt/compare/svn-mirror...patched...
r161 if (!PythonQt::self()) {
std::cerr << str.toLatin1().data() << std::endl;
return;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 emit PythonQt::self()->pythonStdErr(str);
}
florianlink
merged in features from the MeVisLab repository...
r4 void PythonQt::setQObjectWrappedCallback(PythonQtQObjectWrappedCB* cb)
{
_p->_wrappedCB = cb;
}
void PythonQt::setQObjectNoLongerWrappedCallback(PythonQtQObjectNoLongerWrappedCB* cb)
{
_p->_noLongerWrappedCB = cb;
}
florianlink
updated to upstream state in MeVisLab repository...
r157 void PythonQt::setProfilingCallback(ProfilingCB* cb)
{
_p->_profilingCB = cb;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0
static PyMethodDef PythonQtMethods[] = {
{NULL, NULL, 0, NULL}
};
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 void PythonQt::initPythonQtModule(bool redirectStdOut, const QByteArray& pythonQtModuleName)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 QByteArray name = "PythonQt";
if (!pythonQtModuleName.isEmpty()) {
name = pythonQtModuleName;
}
_p->_pythonQtModule = Py_InitModule(name.constData(), PythonQtMethods);
_p->_pythonQtModuleName = name;
florianlink
updated to upstream state in MeVisLab repository...
r157
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (redirectStdOut) {
PythonQtObjectPtr sys;
PythonQtObjectPtr out;
PythonQtObjectPtr err;
sys.setNewRef(PyImport_ImportModule("sys"));
// create a redirection object for stdout and stderr
out = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
((PythonQtStdOutRedirect*)out.object())->_cb = stdOutRedirectCB;
err = PythonQtStdOutRedirectType.tp_new(&PythonQtStdOutRedirectType,NULL, NULL);
((PythonQtStdOutRedirect*)err.object())->_cb = stdErrRedirectCB;
// replace the built in file objects with our own objects
PyModule_AddObject(sys, "stdout", out);
PyModule_AddObject(sys, "stderr", err);
}
}
florianlink
Updated from current MeVisLab development...
r173 QString PythonQt::getReturnTypeOfWrappedMethod(PyObject* module, const QString& name)
{
QStringList tmp = name.split(".");
QString methodName = tmp.takeLast();
QString variableName = tmp.join(".");
// TODO: the variableName may be a type name, this needs to be handled differently,
// because it is not necessarily known in the module context
PythonQtObjectPtr variableObject = lookupObject(module, variableName);
if (variableObject.isNull()) {
return "";
}
return getReturnTypeOfWrappedMethodHelper(variableObject, methodName, name);
}
QString PythonQt::getReturnTypeOfWrappedMethod(const QString& typeName, const QString& methodName)
{
PythonQtObjectPtr typeObject = getObjectByType(typeName);
if (typeObject.isNull()) {
return "";
}
return getReturnTypeOfWrappedMethodHelper(typeObject, methodName, typeName + "." + methodName);
}
QString PythonQt::getReturnTypeOfWrappedMethodHelper(const PythonQtObjectPtr& variableObject, const QString& methodName, const QString& context)
{
PythonQtObjectPtr methodObject;
if (PyDict_Check(variableObject)) {
methodObject = PyDict_GetItemString(variableObject, methodName.toLatin1().constData());
} else {
methodObject.setNewRef(PyObject_GetAttrString(variableObject, methodName.toLatin1().constData()));
}
if (methodObject.isNull()) {
return "";
}
QString type;
if (methodObject->ob_type == &PyClass_Type || methodObject->ob_type == &PyType_Type) {
// the methodObject is not a method, but the name of a type/class. This means
// a constructor is called. Return the context.
type = context;
} else if (methodObject->ob_type == &PythonQtSlotFunction_Type) {
QString className;
if (PyObject_TypeCheck(variableObject, &PythonQtInstanceWrapper_Type)) {
// the type name of wrapped instance is the class name
className = variableObject->ob_type->tp_name;
} else {
PyObject* classNameObject = PyObject_GetAttrString(variableObject, "__name__");
if (classNameObject) {
Q_ASSERT(PyString_Check(classNameObject));
className = PyString_AsString(classNameObject);
Py_DECREF(classNameObject);
}
}
if (!className.isEmpty()) {
PythonQtClassInfo* info = _p->_knownClassInfos.value(className.toLatin1().constData());
if (info) {
PythonQtSlotInfo* slotInfo = info->member(methodName.toLatin1().constData())._slot;
if (slotInfo) {
if (slotInfo->metaMethod()) {
type = slotInfo->metaMethod()->typeName();
if (!type.isEmpty()) {
QChar c = type.at(type.length()-1);
while (c == '*' || c == '&') {
type.truncate(type.length()-1);
if (!type.isEmpty()) {
c = type.at(type.length()-1);
} else {
break;
}
}
// split away template arguments
type = type.split("<").first();
// split away const
type = type.split(" ").last().trimmed();
// if the type is a known class info, then create the full type name, i.e. include the
// module name. For example, the slot may return a QDate, then this looks up the
// name _PythonQt.QtCore.QDate.
PythonQtClassInfo* typeInfo = _p->_knownClassInfos.value(type.toLatin1().constData());
if (typeInfo && typeInfo->pythonQtClassWrapper()) {
PyObject* s = PyObject_GetAttrString(typeInfo->pythonQtClassWrapper(), "__module__");
Q_ASSERT(PyString_Check(s));
type = QString(PyString_AsString(s)) + "." + type;
Py_DECREF(s);
s = PyObject_GetAttrString(typeInfo->pythonQtClassWrapper(), "__name__");
Q_ASSERT(PyString_Check(s));
Py_DECREF(s);
}
}
}
}
}
}
}
return type;
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 void PythonQt::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 _p->registerCPPClass(typeName, parentTypeName, package, wrapperCreator, shell);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const char* typeName)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtClassInfo* info = _knownClassInfos.value(typeName);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (!info) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 info = new PythonQtClassInfo();
info->setupCPPObject(typeName);
_knownClassInfos.insert(typeName, info);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 return info;
}
florianlink
added support for downcasting via polymorphic handlers...
r26 void PythonQt::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
{
_p->addPolymorphicHandler(typeName, cb);
}
void PythonQtPrivate::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
{
PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
info->addPolymorphicHandler(cb);
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
{
return _p->addParentClass(typeName, parentTypeName, upcastingOffset);
}
bool PythonQtPrivate::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
{
PythonQtClassInfo* info = _knownClassInfos.value(typeName);
if (info) {
PythonQtClassInfo* parentInfo = lookupClassInfoAndCreateIfNotPresent(parentTypeName);
info->addParentClass(PythonQtClassInfo::ParentClassInfo(parentInfo, upcastingOffset));
return true;
} else {
return false;
}
}
florianlink
added support for operators and rich compare...
r119 void PythonQtPrivate::registerCPPClass(const char* typeName, const char* parentTypeName, const char* package, PythonQtQObjectCreatorFunctionCB* wrapperCreator, PythonQtShellSetInstanceWrapperCB* shell, PyObject* module, int typeSlots)
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 {
PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
if (!info->pythonQtClassWrapper()) {
florianlink
added support for operators and rich compare...
r119 info->setTypeSlots(typeSlots);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 info->setupCPPObject(typeName);
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 createPythonQtClassWrapper(info, package, module);
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 }
if (parentTypeName && strcmp(parentTypeName,"")!=0) {
addParentClass(typeName, parentTypeName, 0);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
if (wrapperCreator) {
info->setDecoratorProvider(wrapperCreator);
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (shell) {
info->setShellSetInstanceWrapperCB(shell);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
fixed bad reference counting and borrowed references...
r19 PyObject* PythonQtPrivate::packageByName(const char* name)
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 {
if (name==NULL || name[0]==0) {
florianlink
- putting classes without given package into "PythonQt.private" instead of into PythonQt directly....
r101 name = "private";
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
florianlink
fixed bad reference counting and borrowed references...
r19 PyObject* v = _packages.value(name);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (!v) {
florianlink
added support for passing a parent python module when registering a class and allow to change the name of the PythonQt module...
r109 v = PyImport_AddModule((_pythonQtModuleName + "." + name).constData());
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 _packages.insert(name, v);
florianlink
fixed bad reference counting and borrowed references...
r19 // AddObject steals the reference, so increment it!
Py_INCREF(v);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 PyModule_AddObject(_pythonQtModule, name, v);
}
return v;
}
florianlink
added error handling for virtual method overloads, added more global functions (qsrand etc.), added support for exec_ etc (python keyword overlap resolution), change virtual method handling, this will require code regeneration (I will do that tomorrow)...
r67 void PythonQtPrivate::handleVirtualOverloadReturnError(const char* signature, const PythonQtMethodInfo* methodInfo, PyObject* result)
{
QString error = "Return value '" + PythonQtConv::PyObjGetString(result) + "' can not be converted to expected C++ type '" + methodInfo->parameters().at(0).name + "' as return value of virtual method " + signature;
PyErr_SetString(PyExc_AttributeError, error.toLatin1().data());
PythonQt::self()->handleError();
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PyObject* PythonQt::helpCalled(PythonQtClassInfo* info)
florianlink
fixed initialization order, the importer needs to be store BEFORE the import module is initialized...
r84 {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (_p->_initFlags & ExternalHelp) {
emit pythonHelpRequest(QByteArray(info->className()));
return Py_BuildValue("");
} else {
return PyString_FromString(info->help().toLatin1().data());
}
}
florianlink
merged in features from the MeVisLab repository...
r4
florianlink
updated to upstream state in MeVisLab repository...
r157 void PythonQt::clearNotFoundCachedMembers()
{
foreach(PythonQtClassInfo* info, _p->_knownClassInfos) {
info->clearNotFoundCachedMembers();
}
}
florianlink
added remove method for wrapper factories...
r168 void PythonQt::removeWrapperFactory( PythonQtCppWrapperFactory* factory )
{
_p->_cppWrapperFactories.removeAll(factory);
}
void PythonQt::removeWrapperFactory( PythonQtForeignWrapperFactory* factory )
{
_p->_foreignWrapperFactories.removeAll(factory);
}
florianlink
merged in features from the MeVisLab repository...
r4 void PythonQtPrivate::removeWrapperPointer(void* obj)
{
_wrappedObjects.remove(obj);
}
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 void PythonQtPrivate::addWrapperPointer(void* obj, PythonQtInstanceWrapper* wrapper)
{
_wrappedObjects.insert(obj, wrapper);
}
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 PythonQtInstanceWrapper* PythonQtPrivate::findWrapperAndRemoveUnused(void* obj)
florianlink
merged in features from the MeVisLab repository...
r4 {
florianlink
code cleanup and rename of PythonQtWrapper to PythonQtInstanceWrapper and PythonQtMetaObjectWrapper to PythonQtClassWrapper, since these names match much better what these classes wrap, regarding that we are wrapping CPP objects as well...
r16 PythonQtInstanceWrapper* wrap = _wrappedObjects.value(obj);
florianlink
merged in features from the MeVisLab repository...
r4 if (wrap && !wrap->_wrappedPtr && wrap->_obj == NULL) {
// this is a wrapper whose QObject was already removed due to destruction
// so the obj pointer has to be a new QObject with the same address...
// we remove the old one and set the copy to NULL
wrap->_objPointerCopy = NULL;
removeWrapperPointer(obj);
wrap = NULL;
}
return wrap;
}
PythonQtObjectPtr PythonQtPrivate::createModule(const QString& name, PyObject* pycode)
{
PythonQtObjectPtr result;
if (pycode) {
result.setNewRef(PyImport_ExecCodeModule((char*)name.toLatin1().data(), pycode));
} else {
PythonQt::self()->handleError();
}
return result;
}
florianlink
added initial version of foreign wrappers, needs testing...
r167
void* PythonQtPrivate::unwrapForeignWrapper( const QByteArray& classname, PyObject* obj )
{
void* foreignObject = NULL;
for (int i=0; i<_foreignWrapperFactories.size(); i++) {
foreignObject = _foreignWrapperFactories.at(i)->unwrap(classname, obj);
if (foreignObject) {
return foreignObject;
}
}
return NULL;
florianlink
Updated from current MeVisLab development...
r173 }
bool PythonQtPrivate::isMethodDescriptor(PyObject* object) const
{
// This implementation is the same as in inspect.ismethoddescriptor(), inspect.py.
if (PyObject_HasAttrString(object, "__get__") &&
!PyObject_HasAttrString(object, "__set__") &&
!PyMethod_Check(object) &&
!PyFunction_Check(object) &&
!PyClass_Check(object)) {
return true;
}
return false;
}
QString PythonQtPrivate::getSignature(PyObject* object)
{
QString signature;
if (object) {
PyMethodObject* method = NULL;
PyFunctionObject* func = NULL;
bool decrefMethod = false;
if (object->ob_type == &PyClass_Type || object->ob_type == &PyType_Type) {
method = (PyMethodObject*)PyObject_GetAttrString(object, "__init__");
decrefMethod = true;
} else if (object->ob_type == &PyFunction_Type) {
func = (PyFunctionObject*)object;
} else if (object->ob_type == &PyMethod_Type) {
method = (PyMethodObject*)object;
}
if (method) {
if (PyFunction_Check(method->im_func)) {
func = (PyFunctionObject*)method->im_func;
} else if (isMethodDescriptor((PyObject*)method)) {
QString docstr;
PyObject* doc = PyObject_GetAttrString(object, "__doc__");
if (doc) {
docstr = PyString_AsString(doc);
Py_DECREF(doc);
}
PyObject* s = PyObject_GetAttrString(object, "__name__");
if (s) {
Q_ASSERT(PyString_Check(s));
signature = PyString_AsString(s);
if (docstr.startsWith(signature + "(")) {
signature = docstr;
} else {
signature += "(...)";
if (!docstr.isEmpty()) {
signature += "\n\n" + docstr;
}
}
Py_DECREF(s);
}
}
}
if (func) {
QString funcName;
PyObject* s = PyObject_GetAttrString((PyObject*)func, "__name__");
if (s) {
Q_ASSERT(PyString_Check(s));
funcName = PyString_AsString(s);
Py_DECREF(s);
}
if (method && funcName == "__init__") {
PyObject* s = PyObject_GetAttrString(object, "__name__");
if (s) {
Q_ASSERT(PyString_Check(s));
funcName = PyString_AsString(s);
Py_DECREF(s);
}
}
QStringList arguments;
QStringList defaults;
QString varargs;
QString varkeywords;
// NOTE: This implementation is based on function getargs() in inspect.py.
// inspect.getargs() can handle anonymous (tuple) arguments, while this code does not.
// It can be implemented, but it may be rarely needed and not necessary.
PyCodeObject* code = (PyCodeObject*)func->func_code;
if (code->co_varnames) {
int nargs = code->co_argcount;
Q_ASSERT(PyTuple_Check(code->co_varnames));
for (int i=0; i<nargs; i++) {
PyObject* name = PyTuple_GetItem(code->co_varnames, i);
Q_ASSERT(PyString_Check(name));
arguments << PyString_AsString(name);
}
if (code->co_flags & CO_VARARGS) {
PyObject* s = PyTuple_GetItem(code->co_varnames, nargs);
Q_ASSERT(PyString_Check(s));
varargs = PyString_AsString(s);
nargs += 1;
}
if (code->co_flags & CO_VARKEYWORDS) {
PyObject* s = PyTuple_GetItem(code->co_varnames, nargs);
Q_ASSERT(PyString_Check(s));
varkeywords = PyString_AsString(s);
}
}
PyObject* defaultsTuple = func->func_defaults;
if (defaultsTuple) {
Q_ASSERT(PyTuple_Check(defaultsTuple));
for (Py_ssize_t i=0; i<PyTuple_Size(defaultsTuple); i++) {
PyObject* d = PyTuple_GetItem(defaultsTuple, i);
PyObject* s = PyObject_Repr(d);
Q_ASSERT(PyString_Check(s));
defaults << PyString_AsString(s);
Py_DECREF(s);
}
}
int firstdefault = arguments.size() - defaults.size();
for (int i=0; i<arguments.size(); i++) {
if (!signature.isEmpty()) { signature += ", "; }
if (!method || i>0 || arguments[i] != "self") {
signature += arguments[i];
if (i >= firstdefault) {
signature += "=" + defaults[i-firstdefault];
}
}
}
if (!varargs.isEmpty()) {
if (!signature.isEmpty()) { signature += ", "; }
signature += "*" + varargs;
}
if (!varkeywords.isEmpty()) {
if (!signature.isEmpty()) { signature += ", "; }
signature += "**" + varkeywords;
}
signature = funcName + "(" + signature + ")";
}
if (method && decrefMethod) {
Py_DECREF(method);
}
}
return signature;
}
florianlink
merged various changes from MeVisLab repository...
r180
void PythonQtPrivate::shellClassDeleted( void* shellClass )
{
PythonQtInstanceWrapper* wrap = _wrappedObjects.value(shellClass);
if (wrap && wrap->_wrappedPtr) {
// this is a pure C++ wrapper and the shell has gone, so we need
// to set the _wrappedPtr to NULL on the wrapper
wrap->_wrappedPtr = NULL;
// and then we remove the wrapper, since the wrapped class is gone
_wrappedObjects.remove(shellClass);
}
// if the wrapper is a QObject, we do not handle this here,
// it will be handled by the QPointer<> to the QObject, which becomes NULL
// via the QObject destructor.
florianlink
adapted to new generator files...
r193 }
PyObject* PythonQtPrivate::wrapMemoryAsBuffer( const void* data, Py_ssize_t size )
{
// P3K port needed later on!
return PyBuffer_FromMemory((void*)data, size);
}
PyObject* PythonQtPrivate::wrapMemoryAsBuffer( void* data, Py_ssize_t size )
{
// P3K port needed later on!
return PyBuffer_FromReadWriteMemory(data, size);
florianlink
merged various changes from MeVisLab repository...
r180 }