##// END OF EJS Templates
integrated changes from https://github.com/commontk/PythonQt#patched-2 renamed errorOccurred() to hadError() renamed resetErrorFlag() to clearError() added optional system exit handler added iatty method git-svn-id: svn://svn.code.sf.net/p/pythonqt/code/trunk@242 ea8d5007-eb21-0410-b261-ccb3ea6e24a9

File last commit:

r197:31700bd9f8fe
r201:4443fddf8142
Show More
PythonQtConversion.cpp
1289 lines | 43.3 KiB | text/x-c | CppLexer
/ src / PythonQtConversion.cpp
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 PythonQtConversion.cpp
// \author Florian Link
// \author Last changed by $Author: florian $
// \date 2006-05
*/
//----------------------------------------------------------------------------------
#include "PythonQtConversion.h"
#include "PythonQtVariants.h"
#include <QDateTime>
#include <QTime>
#include <QDate>
PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
florianlink
updated to upstream state in MeVisLab repository...
r157 PythonQtValueStorageWithCleanup<QVariant, 128> PythonQtConv::global_variantStorage;
ezust
reorganized SVN tree into branches, tags and trunk...
r0
florianlink
fixed Uint conversion...
r80 QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
ezust
reorganized SVN tree into branches, tags and trunk...
r0
PyObject* PythonQtConv::GetPyBool(bool val)
{
PyObject* r = val?Py_True:Py_False;
Py_INCREF(r);
return r;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data) {
florianlink
support enum values on signals as well, all tests should succeed now...
r56 // is it an enum value?
if (info.enumWrapper) {
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (info.pointerCount==0) {
florianlink
support enum values on signals as well, all tests should succeed now...
r56 return PythonQtPrivate::createEnumValueInstance(info.enumWrapper, *((unsigned int*)data));
} else {
// we do not support pointers to enums (who needs them?)
Py_INCREF(Py_None);
return Py_None;
}
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (info.typeId == QMetaType::Void) {
Py_INCREF(Py_None);
return Py_None;
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else if ((info.pointerCount == 1) && (info.typeId == QMetaType::Char)) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // a char ptr will probably be a null terminated string, so we support that:
florianlink
improved conversion (merged from MeVisLab PythonQt)...
r197 char* charPtr = *((char**)data);
if (charPtr) {
return PyString_FromString(charPtr);
} else {
Py_INCREF(Py_None);
return Py_None;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 } else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) &&
info.name.startsWith("QList<")) {
// it is a QList template:
QByteArray innerType = info.name.mid(6,info.name.length()-7);
if (innerType.endsWith("*")) {
innerType.truncate(innerType.length()-1);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 QList<void*>* listPtr = NULL;
if (info.pointerCount == 1) {
florianlink
- fixed support for QList<AnyObject*>* (which occured with QObjectList* return values)...
r77 listPtr = *((QList<void*>**)data);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else if (info.pointerCount == 0) {
florianlink
- fixed support for QList<AnyObject*>* (which occured with QObjectList* return values)...
r77 listPtr = (QList<void*>*)data;
}
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (listPtr) {
return ConvertQListOfPointerTypeToPythonList(listPtr, innerType);
} else {
return NULL;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
fixed Uint conversion...
r80
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (info.typeId >= QMetaType::User) {
// if a converter is registered, we use is:
PythonQtConvertMetaTypeToPythonCB* converter = _metaTypeToPythonConverters.value(info.typeId);
if (converter) {
return (*converter)(data, info.typeId);
}
}
// special handling did not match, so we convert the usual way (either pointer or value version):
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (info.pointerCount == 1) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // convert the pointer to a Python Object (we can handle ANY C++ object, in the worst case we just know the type and the pointer)
return PythonQt::priv()->wrapPtr(*((void**)data), info.name);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else if (info.pointerCount == 0) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // handle values that are not yet handled and not pointers
return ConvertQtValueToPythonInternal(info.typeId, data);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else {
return NULL;
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* data) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 switch (type) {
case QMetaType::Void:
Py_INCREF(Py_None);
return Py_None;
case QMetaType::Char:
return PyInt_FromLong(*((char*)data));
case QMetaType::UChar:
return PyInt_FromLong(*((unsigned char*)data));
case QMetaType::Short:
return PyInt_FromLong(*((short*)data));
case QMetaType::UShort:
return PyInt_FromLong(*((unsigned short*)data));
case QMetaType::Long:
return PyInt_FromLong(*((long*)data));
case QMetaType::ULong:
// does not fit into simple int of python
return PyLong_FromUnsignedLong(*((unsigned long*)data));
case QMetaType::Bool:
return PythonQtConv::GetPyBool(*((bool*)data));
case QMetaType::Int:
return PyInt_FromLong(*((int*)data));
case QMetaType::UInt:
florianlink
fixed Uint conversion...
r80 // does not fit into simple int of python
return PyLong_FromUnsignedLong(*((unsigned int*)data));
ezust
reorganized SVN tree into branches, tags and trunk...
r0 case QMetaType::QChar:
return PyInt_FromLong(*((short*)data));
case QMetaType::Float:
return PyFloat_FromDouble(*((float*)data));
case QMetaType::Double:
return PyFloat_FromDouble(*((double*)data));
case QMetaType::LongLong:
return PyLong_FromLongLong(*((qint64*)data));
case QMetaType::ULongLong:
return PyLong_FromUnsignedLongLong(*((quint64*)data));
florianlink
removed implicit conversion of QByteArray to python str, use str() to convert to Python string or QByteArray::data()...
r125 // implicit conversion from QByteArray to str has been removed:
//case QMetaType::QByteArray: {
// QByteArray* v = (QByteArray*) data;
// return PyString_FromStringAndSize(*v, v->size());
// }
ezust
reorganized SVN tree into branches, tags and trunk...
r0 case QMetaType::QVariantMap:
return PythonQtConv::QVariantMapToPyObject(*((QVariantMap*)data));
case QMetaType::QVariantList:
return PythonQtConv::QVariantListToPyObject(*((QVariantList*)data));
case QMetaType::QString:
return PythonQtConv::QStringToPyObject(*((QString*)data));
case QMetaType::QStringList:
return PythonQtConv::QStringListToPyObject(*((QStringList*)data));
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 case PythonQtMethodInfo::Variant:
return PythonQtConv::QVariantToPyObject(*((QVariant*)data));
case QMetaType::QObjectStar:
case QMetaType::QWidgetStar:
return PythonQt::priv()->wrapQObject(*((QObject**)data));
default:
if (PythonQt::priv()->isPythonQtObjectPtrMetaId(type)) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // special case, it is a PythonQtObjectPtr which contains a PyObject, take it directly:
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PyObject* o = ((PythonQtObjectPtr*)data)->object();
Py_INCREF(o);
return o;
} else {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 if (type > 0) {
// if the type is known, we can construct it via QMetaType::construct
void* newCPPObject = QMetaType::construct(type, data);
// XXX this could be optimized by using metatypeid directly
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 = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type));
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 wrap->_ownedByPythonQt = true;
wrap->_useQMetaTypeDestroy = true;
return (PyObject*)wrap;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
std::cerr << "Unknown type that can not be converted to Python: " << type << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
}
}
Py_INCREF(Py_None);
return Py_None;
}
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) {
void* ptr = 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.pointerCount>1) {
return NULL;
} else if (info.pointerCount==1) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
florianlink
support enum values on signals as well, all tests should succeed now...
r56 } else if (info.enumWrapper) {
// create enum return value
PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
switch (info.typeId) {
case QMetaType::Char:
case QMetaType::UChar:
case QMetaType::Short:
case QMetaType::UShort:
case QMetaType::Long:
case QMetaType::ULong:
case QMetaType::Bool:
case QMetaType::Int:
case QMetaType::UInt:
case QMetaType::QChar:
case QMetaType::Float:
case QMetaType::Double:
florianlink
fixed Uint conversion...
r80 PythonQtValueStorage_ADD_VALUE(global_valueStorage, qint64, 0, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 break;
case PythonQtMethodInfo::Variant:
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, 0, ptr);
// return the ptr to the variant
break;
default:
if (info.typeId == PythonQtMethodInfo::Unknown) {
// check if we have a QList of pointers, which we can circumvent with a QList<void*>
if (info.name.startsWith("QList<")) {
QByteArray innerType = info.name.mid(6,info.name.length()-7);
if (innerType.endsWith("*")) {
static int id = QMetaType::type("QList<void*>");
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(id), ptr);
// return the constData pointer that will be filled with the result value later on
ptr = (void*)((QVariant*)ptr)->constData();
}
}
}
florianlink
moved return value creation AFTER the successful check of the call parameters, otherwise the return value allocation is done for nothing...
r45 if (!ptr && info.typeId!=PythonQtMethodInfo::Unknown) {
// everything else is stored in a QVariant, if we know the meta type...
ezust
reorganized SVN tree into branches, tags and trunk...
r0 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
// return the constData pointer that will be filled with the result value later on
ptr = (void*)((QVariant*)ptr)->constData();
}
}
}
return ptr;
}
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24
void* PythonQtConv::castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok)
{
void* object;
if (wrapper->classInfo()->isCPPWrapper()) {
object = wrapper->_wrappedPtr;
} else {
QObject* tmp = wrapper->_obj;
object = tmp;
}
if (object) {
// if we can be upcasted to the given name, we pass the casted pointer in:
object = wrapper->classInfo()->castTo(object, className);
ok = object!=NULL;
} else {
// if it is a NULL ptr, we need to check if it inherits, so that we might pass the NULL ptr
ok = wrapper->classInfo()->inherits(className);
}
return object;
}
florianlink
added automatic conversion to QColor,QPen,QCursor and QBrush from enums and colors...
r64 void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject)
{
void* ptr = alreadyAllocatedCPPObject;
florianlink
fixed Uint conversion...
r80
florianlink
added automatic conversion to QColor,QPen,QCursor and QBrush from enums and colors...
r64 static int penId = QMetaType::type("QPen");
static int brushId = QMetaType::type("QBrush");
static int cursorId = QMetaType::type("QCursor");
static int colorId = QMetaType::type("QColor");
static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL);
if (typeId == cursorId) {
static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
*((QCursor*)ptr) = QCursor(val);
return ptr;
}
} else if (typeId == penId) {
// brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
*((QPen*)ptr) = QPen(QColor(val));
return ptr;
} else if ((PyObject*)obj->ob_type == qtColorClass) {
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
*((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
return ptr;
}
} else if (typeId == brushId) {
// brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
*((QBrush*)ptr) = QBrush(QColor(val));
return ptr;
} else if ((PyObject*)obj->ob_type == qtColorClass) {
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
*((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
return ptr;
}
} else if (typeId == colorId) {
// colors can be created from Qt::GlobalColor (and from colors, but that's the default)
if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
if (!ptr) {
PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
*((QColor*)ptr) = QColor(val);
return ptr;
}
}
return NULL;
}
void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
florianlink
fixed bad initialization of ok, swapped QColor constructors to check the error in test...
r59 bool ok = false;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 void* ptr = NULL;
florianlink
added automatic conversion to QColor,QPen,QCursor and QBrush from enums and colors...
r64
// autoconversion of QPen/QBrush/QCursor/QColor from different type
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (info.pointerCount==0 && !strict) {
florianlink
added automatic conversion to QColor,QPen,QCursor and QBrush from enums and colors...
r64 ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
if (ptr) {
return ptr;
}
}
florianlink
fixed Uint conversion...
r80
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
// (the Variant case is handled below in a switch)
florianlink
fixed Uint conversion...
r80
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // a C++ wrapper (can be passed as pointer or reference)
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 = (PythonQtInstanceWrapper*)obj;
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 void* object = castWrapperTo(wrap, info.name, ok);
if (ok) {
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 if (info.pointerCount==1) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr);
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else if (info.pointerCount==0) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // store the wrapped pointer directly, since we are a reference
ptr = object;
}
} else {
florianlink
improved conversion (merged from MeVisLab PythonQt)...
r197 // not matching, maybe a PyObject*?
if (info.name == "PyObject" && info.pointerCount==1) {
// handle low level PyObject directly
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else if (info.pointerCount == 1) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // a pointer
if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
{
florianlink
merged various changes from MeVisLab repository...
r180 if (obj->ob_type == &PyString_Type) {
// take direct reference to string data
const char* data = PyString_AS_STRING(obj);
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)data, ptr);
} else {
// convert to string
QString str = PyObjGetString(obj, strict, ok);
if (ok) {
QByteArray bytes;
bytes = str.toUtf8();
if (ok) {
void* ptr2 = NULL;
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(bytes), ptr2);
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (((QByteArray*)((QVariant*)ptr2)->constData())->data()), ptr);
}
}
}
} else if (info.typeId == QMetaType::QString) {
// TODO: this is a special case for bad Qt APIs which take a QString*, like QtGui.QFileDialog.getSaveFileName
// In general we would need to decide to either support * args for all basic types (ignoring the fact that the
// result value is not useable in Python), or if all these APIs need to be wrapped manually/differently, like PyQt/PySide do.
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 QString str = PyObjGetString(obj, strict, ok);
if (ok) {
void* ptr2 = NULL;
florianlink
merged various changes from MeVisLab repository...
r180 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(str), ptr2);
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)((QVariant*)ptr2)->constData(), ptr);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
} else if (info.name == "PyObject") {
// handle low level PyObject directly
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
florianlink
added initial version of foreign wrappers, needs testing...
r167 } else if (obj == Py_None) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // None is treated as a NULL ptr
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 } else {
florianlink
added initial version of foreign wrappers, needs testing...
r167 void* foreignWrapper = PythonQt::priv()->unwrapForeignWrapper(info.name, obj);
if (foreignWrapper) {
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, foreignWrapper, ptr);
} else {
// if we are not strict, we try if we are passed a 0 integer
if (!strict) {
bool ok;
int value = PyObjGetInt(obj, true, ok);
if (ok && value==0) {
// TODOXXX is this wise? or should it be expected from the programmer to use None?
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 }
florianlink
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
r134 } else if (info.pointerCount == 0) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // not a pointer
switch (info.typeId) {
case QMetaType::Char:
{
int val = PyObjGetInt(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, char, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::UChar:
{
int val = PyObjGetInt(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned char, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::Short:
{
int val = PyObjGetInt(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::UShort:
{
int val = PyObjGetInt(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned short, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::Long:
{
long val = (long)PyObjGetLongLong(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, long, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::ULong:
{
unsigned long val = (unsigned long)PyObjGetLongLong(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned long, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::Bool:
{
bool val = PyObjGetBool(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, bool, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::Int:
{
int val = PyObjGetInt(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, int, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::UInt:
{
unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::QChar:
{
int val = PyObjGetInt(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::Float:
{
float val = (float)PyObjGetDouble(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, float, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::Double:
{
double val = (double)PyObjGetDouble(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, double, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::LongLong:
{
qint64 val = PyObjGetLongLong(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, qint64, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::ULongLong:
{
quint64 val = PyObjGetULongLong(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, quint64, val, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
break;
case QMetaType::QByteArray:
{
QByteArray bytes = PyObjGetBytes(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(bytes), ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 ptr = (void*)((QVariant*)ptr)->constData();
}
}
break;
case QMetaType::QString:
{
QString str = PyObjGetString(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str), ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 ptr = (void*)((QVariant*)ptr)->constData();
}
}
break;
case QMetaType::QStringList:
{
QStringList l = PyObjToStringList(obj, strict, ok);
if (ok) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(l), ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 ptr = (void*)((QVariant*)ptr)->constData();
}
}
break;
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 case PythonQtMethodInfo::Variant:
{
QVariant v = PyObjToQVariant(obj);
florianlink
allow to pass invalid QVariants as QVariant parameter of slots...
r90 // the only case where conversion can fail it None and we want to pass that to, e.g. setProperty(),
// so we do not check v.isValid() here
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
break;
default:
{
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 // check for enum case
if (info.enumWrapper) {
unsigned int val;
florianlink
fixed bad initialization of ok, swapped QColor constructors to check the error in test...
r59 ok = false;
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 if ((PyObject*)obj->ob_type == info.enumWrapper) {
florianlink
improved enum overload handling...
r57 // we have a exact enum type match:
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 val = PyInt_AS_LONG(obj);
ok = true;
florianlink
improved enum overload handling...
r57 } else if (!strict) {
// we try to get any integer, when not being strict. If we are strict, integers are not wanted because
florianlink
fixed Uint conversion...
r80 // we want an integer overload to be taken first!
florianlink
improved enum overload handling...
r57 val = (unsigned int)PyObjGetLongLong(obj, false, ok);
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55 }
if (ok) {
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
return ptr;
} else {
return NULL;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
florianlink
cache enumWrappers in method infos and make use of the extra information for better enum overloading...
r55
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
// check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
if (info.name.startsWith("QList<")) {
QByteArray innerType = info.name.mid(6,info.name.length()-7);
if (innerType.endsWith("*")) {
innerType.truncate(innerType.length()-1);
static int id = QMetaType::type("QList<void*>");
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (!alreadyAllocatedCPPObject) {
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(id), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
} else {
ptr = alreadyAllocatedCPPObject;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 ok = ConvertPythonListToQListOfPointerType(obj, (QList<void*>*)ptr, innerType, strict);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (ok) {
return ptr;
} else {
return NULL;
}
}
}
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // We only do this for registered type > QMetaType::User for performance reasons.
if (info.typeId >= QMetaType::User) {
// Maybe we have a special converter that is registered for that type:
PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(info.typeId);
if (converter) {
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 if (!alreadyAllocatedCPPObject) {
// create a new empty variant of concrete type:
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
ptr = (void*)((QVariant*)ptr)->constData();
} else {
ptr = alreadyAllocatedCPPObject;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // now call the converter, passing the internal object of the variant
ok = (*converter)(obj, ptr, info.typeId, strict);
if (ok) {
return ptr;
} else {
return NULL;
}
}
}
florianlink
removed wrong conversion to QVariant when the underlying type id is unknown...
r43 // if no type id is available, conversion to a QVariant makes no sense/is not possible
if (info.typeId != PythonQtMethodInfo::Unknown) {
// for all other types, we use the same qvariant conversion and pass out the constData of the variant:
QVariant v = PyObjToQVariant(obj, info.typeId);
if (v.isValid()) {
PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
ptr = (void*)((QVariant*)ptr)->constData();
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
}
}
return ptr;
}
QStringList PythonQtConv::PyObjToStringList(PyObject* val, bool strict, bool& ok) {
QStringList v;
ok = false;
// if we are strict, we do not want to convert a string to a stringlist
// (strings in python are detected to be sequences)
if (strict &&
(val->ob_type == &PyString_Type ||
PyUnicode_Check(val))) {
ok = false;
return v;
}
if (PySequence_Check(val)) {
int count = PySequence_Size(val);
for (int i = 0;i<count;i++) {
PyObject* value = PySequence_GetItem(val,i);
v.append(PyObjGetString(value,false,ok));
}
ok = true;
}
return v;
}
QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
{
QString r;
PyObject* str = PyObject_Repr(val);
if (str) {
r = QString(PyString_AS_STRING(str));
Py_DECREF(str);
}
return r;
}
QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
QString r;
ok = true;
if (val->ob_type == &PyString_Type) {
r = QString(PyString_AS_STRING(val));
} else if (PyUnicode_Check(val)) {
PyObject *ptmp = PyUnicode_AsUTF8String(val);
if(ptmp) {
r = QString::fromUtf8(PyString_AS_STRING(ptmp));
Py_DECREF(ptmp);
}
} else if (!strict) {
// EXTRA: could also use _Unicode, but why should we?
PyObject* str = PyObject_Str(val);
if (str) {
r = QString(PyString_AS_STRING(str));
Py_DECREF(str);
} else {
ok = false;
}
} else {
ok = false;
}
return r;
}
florianlink
- removed warnings...
r8 QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok) {
florianlink
removed implicit conversion of QByteArray to python str, use str() to convert to Python string or QByteArray::data()...
r125 // TODO: support buffer objects in general
ezust
reorganized SVN tree into branches, tags and trunk...
r0 QByteArray r;
ok = true;
if (val->ob_type == &PyString_Type) {
long size = PyString_GET_SIZE(val);
r = QByteArray(PyString_AS_STRING(val), size);
} else {
ok = false;
}
return r;
}
bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
bool d = false;
ok = false;
if (val == Py_False) {
d = false;
ok = true;
} else if (val == Py_True) {
d = true;
ok = true;
} else if (!strict) {
florianlink
made bool conversion more stable...
r190 int result = PyObject_IsTrue(val);
d = (result == 1);
// the result is -1 if an error occurred, handle this:
ok = (result != -1);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
return d;
}
int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
int d = 0;
ok = true;
if (val->ob_type == &PyInt_Type) {
d = PyInt_AS_LONG(val);
} else if (!strict) {
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 if (PyObject_TypeCheck(val, &PyInt_Type)) {
// support for derived int classes, e.g. for our enums
d = PyInt_AS_LONG(val);
} else if (val->ob_type == &PyFloat_Type) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 d = floor(PyFloat_AS_DOUBLE(val));
} else if (val->ob_type == &PyLong_Type) {
// handle error on overflow!
d = PyLong_AsLong(val);
} else if (val == Py_False) {
d = 0;
} else if (val == Py_True) {
d = 1;
} else {
florianlink
merged various changes from MeVisLab repository...
r180 PyErr_Clear();
// PyInt_AsLong will try conversion to an int if the object is not an int:
d = PyInt_AsLong(val);
if (PyErr_Occurred()) {
ok = false;
PyErr_Clear();
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
} else {
ok = false;
}
return d;
}
qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
qint64 d = 0;
ok = true;
florianlink
improved strictness when enum values are used...
r52 if (val->ob_type == &PyInt_Type) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 d = PyInt_AS_LONG(val);
} else if (val->ob_type == &PyLong_Type) {
d = PyLong_AsLongLong(val);
} else if (!strict) {
florianlink
improved strictness when enum values are used...
r52 if (PyObject_TypeCheck(val, &PyInt_Type)) {
// support for derived int classes, e.g. for our enums
d = PyInt_AS_LONG(val);
} else if (val->ob_type == &PyFloat_Type) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 d = floor(PyFloat_AS_DOUBLE(val));
} else if (val == Py_False) {
d = 0;
} else if (val == Py_True) {
d = 1;
} else {
florianlink
merged various changes from MeVisLab repository...
r180 PyErr_Clear();
// PyLong_AsLongLong will try conversion to an int if the object is not an int:
d = PyLong_AsLongLong(val);
if (PyErr_Occurred()) {
ok = false;
PyErr_Clear();
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
} else {
ok = false;
}
return d;
}
quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) {
quint64 d = 0;
ok = true;
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 if (PyObject_TypeCheck(val, &PyInt_Type)) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 d = PyInt_AS_LONG(val);
} else if (val->ob_type == &PyLong_Type) {
d = PyLong_AsLongLong(val);
} else if (!strict) {
florianlink
improved strictness when enum values are used...
r52 if (PyObject_TypeCheck(val, &PyInt_Type)) {
// support for derived int classes, e.g. for our enums
d = PyInt_AS_LONG(val);
} else if (val->ob_type == &PyFloat_Type) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 d = floor(PyFloat_AS_DOUBLE(val));
} else if (val == Py_False) {
d = 0;
} else if (val == Py_True) {
d = 1;
} else {
florianlink
merged various changes from MeVisLab repository...
r180 PyErr_Clear();
// PyLong_AsLongLong will try conversion to an int if the object is not an int:
d = PyLong_AsLongLong(val);
if (PyErr_Occurred()) {
PyErr_Clear();
ok = false;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
} else {
ok = false;
}
return d;
}
double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) {
double d = 0;
ok = true;
if (val->ob_type == &PyFloat_Type) {
d = PyFloat_AS_DOUBLE(val);
} else if (!strict) {
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 if (PyObject_TypeCheck(val, &PyInt_Type)) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 d = PyInt_AS_LONG(val);
} else if (val->ob_type == &PyLong_Type) {
d = PyLong_AsLong(val);
} else if (val == Py_False) {
d = 0;
} else if (val == Py_True) {
d = 1;
} else {
florianlink
merged various changes from MeVisLab repository...
r180 PyErr_Clear();
// PyFloat_AsDouble will try conversion to a double if the object is not a float:
d = PyFloat_AsDouble(val);
if (PyErr_Occurred()) {
PyErr_Clear();
ok = false;
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
} else {
ok = false;
}
return d;
}
QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
{
QVariant v;
bool ok = true;
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 if (type==-1) {
// no special type requested
if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) {
type = QVariant::String;
florianlink
improved conversion (merged from MeVisLab PythonQt)...
r197 } else if (val == Py_False || val == Py_True) {
type = QVariant::Bool;
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 } else if (PyObject_TypeCheck(val, &PyInt_Type)) {
ezust
reorganized SVN tree into branches, tags and trunk...
r0 type = QVariant::Int;
} else if (val->ob_type==&PyLong_Type) {
type = QVariant::LongLong;
} else if (val->ob_type==&PyFloat_Type) {
type = QVariant::Double;
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
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 = (PythonQtInstanceWrapper*)val;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // c++ wrapper, check if the class names of the c++ objects match
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 if (wrap->classInfo()->isCPPWrapper()) {
if (wrap->classInfo()->metaTypeId()>0) {
florianlink
- added call method that does a direct call on the ObjectType...
r36 // construct a new variant from the C++ object if it has a meta type (this will COPY the object!)
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 v = QVariant(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 } else {
florianlink
- added call method that does a direct call on the ObjectType...
r36 // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass
// the pointer here...
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // is this worth anything? we loose the knowledge of the cpp object type
v = qVariantFromValue(wrap->_wrappedPtr);
}
ezust
reorganized SVN tree into branches, tags and trunk...
r0 } else {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // this gives us a QObject pointer
florianlink
merged in features from the MeVisLab repository...
r4 QObject* myObject = wrap->_obj;
v = qVariantFromValue(myObject);
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
return v;
} else if (val->ob_type==&PyDict_Type) {
type = QVariant::Map;
} else if (val->ob_type==&PyList_Type || val->ob_type==&PyTuple_Type || PySequence_Check(val)) {
type = QVariant::List;
} else if (val == Py_None) {
// none is invalid
type = QVariant::Invalid;
} else {
// this used to be:
// type = QVariant::String;
// but now we want to transport the Python Objects directly:
PythonQtObjectPtr o(val);
v = qVariantFromValue(o);
return v;
}
}
// special type request:
switch (type) {
case QVariant::Invalid:
return v;
break;
case QVariant::Int:
{
int d = PyObjGetInt(val, false, ok);
if (ok) return QVariant(d);
}
break;
case QVariant::UInt:
{
int d = PyObjGetInt(val, false,ok);
if (ok) v = QVariant((unsigned int)d);
}
break;
case QVariant::Bool:
{
int d = PyObjGetBool(val,false,ok);
if (ok) v = QVariant((bool)(d!=0));
}
break;
case QVariant::Double:
{
double d = PyObjGetDouble(val,false,ok);
if (ok) v = QVariant(d);
break;
}
case QMetaType::Float:
{
float d = (float) PyObjGetDouble(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
case QMetaType::Long:
{
long d = (long) PyObjGetLongLong(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
case QMetaType::ULong:
{
unsigned long d = (unsigned long) PyObjGetLongLong(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
florianlink
fixed QVariant return value for ULongLong and LongLong...
r102 case QMetaType::LongLong:
{
qint64 d = PyObjGetLongLong(val, false, ok);
if (ok) v = qVariantFromValue(d);
}
break;
case QMetaType::ULongLong:
{
quint64 d = PyObjGetULongLong(val, false, ok);
if (ok) v = qVariantFromValue(d);
}
break;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 case QMetaType::Short:
{
short d = (short) PyObjGetInt(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
case QMetaType::UShort:
{
unsigned short d = (unsigned short) PyObjGetInt(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
case QMetaType::Char:
{
char d = (char) PyObjGetInt(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
case QMetaType::UChar:
{
unsigned char d = (unsigned char) PyObjGetInt(val,false,ok);
if (ok) v = qVariantFromValue(d);
break;
}
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 case QVariant::ByteArray:
case QVariant::String:
{
bool ok;
v = QVariant(PyObjGetString(val, false, ok));
}
break;
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 // these are important for MeVisLab
case QVariant::Map:
{
if (PyMapping_Check(val)) {
QMap<QString,QVariant> map;
PyObject* items = PyMapping_Items(val);
if (items) {
int count = PyList_Size(items);
PyObject* value;
PyObject* key;
PyObject* tuple;
for (int i = 0;i<count;i++) {
tuple = PyList_GetItem(items,i);
key = PyTuple_GetItem(tuple, 0);
value = PyTuple_GetItem(tuple, 1);
map.insert(PyObjGetString(key), PyObjToQVariant(value,-1));
}
Py_DECREF(items);
v = map;
}
}
}
break;
case QVariant::List:
if (PySequence_Check(val)) {
QVariantList list;
int count = PySequence_Size(val);
PyObject* value;
for (int i = 0;i<count;i++) {
value = PySequence_GetItem(val,i);
list.append(PyObjToQVariant(value, -1));
}
v = list;
}
break;
case QVariant::StringList:
{
bool ok;
QStringList l = PyObjToStringList(val, false, ok);
if (ok) {
v = l;
}
}
break;
florianlink
fixed Uint conversion...
r80
ezust
reorganized SVN tree into branches, tags and trunk...
r0 default:
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
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 = (PythonQtInstanceWrapper*)val;
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 // construct a new variant from the C++ object if it has the same meta type
v = QVariant(type, wrap->_wrappedPtr);
} else {
v = QVariant();
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
} else {
v = QVariant();
}
}
return v;
}
PyObject* PythonQtConv::QStringToPyObject(const QString& str)
{
if (str.isNull()) {
return PyString_FromString("");
} else {
return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
}
}
PyObject* PythonQtConv::QStringListToPyObject(const QStringList& list)
{
PyObject* result = PyTuple_New(list.count());
int i = 0;
QString str;
foreach (str, list) {
PyTuple_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(str));
i++;
}
// why is the error state bad after this?
PyErr_Clear();
return result;
}
PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
{
PyObject* result = PyList_New(list.count());
int i = 0;
for (QStringList::ConstIterator it = list.begin(); it!=list.end(); ++it) {
PyList_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(*it));
i++;
}
return result;
}
PyObject* PythonQtConv::QVariantToPyObject(const QVariant& v)
{
return ConvertQtValueToPythonInternal(v.userType(), (void*)v.constData());
}
PyObject* PythonQtConv::QVariantMapToPyObject(const QVariantMap& m) {
PyObject* result = PyDict_New();
QVariantMap::const_iterator t = m.constBegin();
PyObject* key;
PyObject* val;
for (;t!=m.end();t++) {
key = QStringToPyObject(t.key());
val = QVariantToPyObject(t.value());
PyDict_SetItem(result, key, val);
Py_DECREF(key);
Py_DECREF(val);
}
return result;
}
PyObject* PythonQtConv::QVariantListToPyObject(const QVariantList& l) {
PyObject* result = PyTuple_New(l.count());
int i = 0;
QVariant v;
foreach (v, l) {
PyTuple_SET_ITEM(result, i, PythonQtConv::QVariantToPyObject(v));
i++;
}
// why is the error state bad after this?
PyErr_Clear();
return result;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 PyObject* PythonQtConv::ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& typeName)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
PyObject* result = PyTuple_New(list->count());
int i = 0;
foreach (void* value, *list) {
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 PyTuple_SET_ITEM(result, i, PythonQt::priv()->wrapPtr(value, typeName));
ezust
reorganized SVN tree into branches, tags and trunk...
r0 i++;
}
return result;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool /*strict*/)
ezust
reorganized SVN tree into branches, tags and trunk...
r0 {
bool result = false;
if (PySequence_Check(obj)) {
result = true;
int count = PySequence_Size(obj);
PyObject* value;
for (int i = 0;i<count;i++) {
value = PySequence_GetItem(obj,i);
florianlink
- wrapped instances are now wrapped by class specific subtypes to facilitate future deriving from python...
r18 if (PyObject_TypeCheck(value, &PythonQtInstanceWrapper_Type)) {
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 = (PythonQtInstanceWrapper*)value;
florianlink
- added support for deriving CPP classes in Python and to override all public and protected virtual functions from PythonQt...
r24 bool ok;
void* object = castWrapperTo(wrap, type, ok);
if (ok) {
list->append(object);
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 } else {
result = false;
break;
ezust
reorganized SVN tree into branches, tags and trunk...
r0 }
}
}
}
return result;
}
florianlink
syncing with my current work, updating to 1.2, see changelog...
r10 int PythonQtConv::getInnerTemplateMetaType(const QByteArray& typeName)
{
int idx = typeName.indexOf("<");
if (idx>0) {
int idx2 = typeName.indexOf(">");
if (idx2>0) {
QByteArray innerType = typeName.mid(idx+1,idx2-idx-1);
return QMetaType::type(innerType.constData());
}
}
return QMetaType::Void;
}
QString PythonQtConv::CPPObjectToString(int type, const void* data) {
QString r;
switch (type) {
case QVariant::Size: {
const QSize* s = static_cast<const QSize*>(data);
r = QString::number(s->width()) + ", " + QString::number(s->height());
}
break;
case QVariant::SizeF: {
const QSizeF* s = static_cast<const QSizeF*>(data);
r = QString::number(s->width()) + ", " + QString::number(s->height());
}
break;
case QVariant::Point: {
const QPoint* s = static_cast<const QPoint*>(data);
r = QString::number(s->x()) + ", " + QString::number(s->y());
}
break;
case QVariant::PointF: {
const QPointF* s = static_cast<const QPointF*>(data);
r = QString::number(s->x()) + ", " + QString::number(s->y());
}
break;
case QVariant::Rect: {
const QRect* s = static_cast<const QRect*>(data);
r = QString::number(s->x()) + ", " + QString::number(s->y());
r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
}
break;
case QVariant::RectF: {
const QRectF* s = static_cast<const QRectF*>(data);
r = QString::number(s->x()) + ", " + QString::number(s->y());
r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
}
break;
case QVariant::Date: {
const QDate* s = static_cast<const QDate*>(data);
r = s->toString(Qt::ISODate);
}
break;
case QVariant::DateTime: {
const QDateTime* s = static_cast<const QDateTime*>(data);
r = s->toString(Qt::ISODate);
}
break;
case QVariant::Time: {
const QTime* s = static_cast<const QTime*>(data);
r = s->toString(Qt::ISODate);
}
break;
case QVariant::Pixmap:
{
const QPixmap* s = static_cast<const QPixmap*>(data);
r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height());
}
break;
case QVariant::Image:
{
const QImage* s = static_cast<const QImage*>(data);
r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height());
}
break;
case QVariant::Url:
{
const QUrl* s = static_cast<const QUrl*>(data);
r = s->toString();
}
break;
//TODO: add more printing for other variant types
default:
// this creates a copy, but that should not be expensive for typical simple variants
// (but we do not want to do this for our won user types!
if (type>0 && type < (int)QVariant::UserType) {
QVariant v(type, data);
r = v.toString();
}
}
return r;
}