00001 #ifndef _PYTHONQTCONVERSION_H
00002 #define _PYTHONQTCONVERSION_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00043
00044
00045 #include "PythonQt.h"
00046 #include "PythonQtMisc.h"
00047 #include "PythonQtClassInfo.h"
00048 #include "PythonQtMethodInfo.h"
00049
00050 #include <QWidget>
00051 #include <QList>
00052 #include <vector>
00053
00054 typedef PyObject* PythonQtConvertMetaTypeToPythonCB(const void* inObject, int metaTypeId);
00055 typedef bool PythonQtConvertPythonToMetaTypeCB(PyObject* inObject, void* outObject, int metaTypeId, bool strict);
00056
00057 #define PythonQtRegisterListTemplateConverter(type, innertype) \
00058 { int typeId = qRegisterMetaType<type<innertype> >(#type"<"#innertype">"); \
00059 PythonQtConv::registerPythonToMetaTypeConverter(typeId, PythonQtConvertPythonListToListOfValueType<type<innertype>, innertype>); \
00060 PythonQtConv::registerMetaTypeToPythonConverter(typeId, PythonQtConvertListOfValueTypeToPythonList<type<innertype>, innertype>); \
00061 }
00062
00063 #define PythonQtRegisterToolClassesTemplateConverter(innertype) \
00064 PythonQtRegisterListTemplateConverter(QList, innertype); \
00065 PythonQtRegisterListTemplateConverter(QVector, innertype); \
00066 PythonQtRegisterListTemplateConverter(std::vector, innertype);
00067
00068
00070 class PYTHONQT_EXPORT PythonQtConv {
00071
00072 public:
00073
00075 static PyObject* GetPyBool(bool val);
00076
00078 static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data);
00079
00081 static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* classInfo, void* alreadyAllocatedCPPObject = NULL);
00082
00084 static void* CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info);
00085
00087 static PyObject* QStringToPyObject(const QString& str);
00088
00090 static PyObject* QStringListToPyObject(const QStringList& list);
00091
00093 static PyObject* QStringListToPyList(const QStringList& list);
00094
00096 static QString PyObjGetRepresentation(PyObject* val);
00097
00099 static QString PyObjGetString(PyObject* val) { bool ok; QString s = PyObjGetString(val, false, ok); return s; }
00101 static QString PyObjGetString(PyObject* val, bool strict, bool &ok);
00103 static QByteArray PyObjGetBytes(PyObject* val, bool strict, bool &ok);
00105 static int PyObjGetInt(PyObject* val, bool strict, bool &ok);
00107 static qint64 PyObjGetLongLong(PyObject* val, bool strict, bool &ok);
00109 static quint64 PyObjGetULongLong(PyObject* val, bool strict, bool &ok);
00111 static double PyObjGetDouble(PyObject* val, bool strict, bool &ok);
00113 static bool PyObjGetBool(PyObject* val, bool strict, bool &ok);
00114
00116 static QStringList PyObjToStringList(PyObject* val, bool strict, bool& ok);
00117
00120 static QVariant PyObjToQVariant(PyObject* val, int type = -1);
00121
00123 static PyObject* QVariantToPyObject(const QVariant& v);
00124
00125 static PyObject* QVariantMapToPyObject(const QVariantMap& m);
00126 static PyObject* QVariantListToPyObject(const QVariantList& l);
00127
00129 static QString CPPObjectToString(int type, const void* data);
00130
00132 static void registerPythonToMetaTypeConverter(int metaTypeId, PythonQtConvertPythonToMetaTypeCB* cb) { _pythonToMetaTypeConverters.insert(metaTypeId, cb); }
00133
00135 static void registerMetaTypeToPythonConverter(int metaTypeId, PythonQtConvertMetaTypeToPythonCB* cb) { _metaTypeToPythonConverters.insert(metaTypeId, cb); }
00136
00138 static int getInnerTemplateMetaType(const QByteArray& typeName);
00139
00141 static PyObject* ConvertQtValueToPythonInternal(int type, const void* data);
00142
00143 public:
00144
00145 static PythonQtValueStorage<qint64, 128> global_valueStorage;
00146 static PythonQtValueStorage<void*, 128> global_ptrStorage;
00147 static PythonQtValueStorage<QVariant, 32> global_variantStorage;
00148
00149 protected:
00150 static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
00151 static QHash<int, PythonQtConvertPythonToMetaTypeCB*> _pythonToMetaTypeConverters;
00152
00154 static void* handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject);
00155
00157 static PyObject* ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& type);
00159 static bool ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool strict);
00160
00162 static void* castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok);
00163 };
00164
00165 template<class ListType, class T>
00166 PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* inList, int metaTypeId)
00167 {
00168 ListType* list = (ListType*)inList;
00169 static const int innerType = PythonQtConv::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId)));
00170 if (innerType == QVariant::Invalid) {
00171 std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl;
00172 }
00173 PyObject* result = PyTuple_New(list->size());
00174 int i = 0;
00175 foreach (const T& value, *list) {
00176 PyTuple_SET_ITEM(result, i, PythonQtConv::ConvertQtValueToPythonInternal(innerType, &value));
00177 i++;
00178 }
00179 return result;
00180 }
00181
00182 template<class ListType, class T>
00183 bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* outList, int metaTypeId, bool )
00184 {
00185 ListType* list = (ListType*)outList;
00186 static const int innerType = PythonQtConv::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId)));
00187 if (innerType == QVariant::Invalid) {
00188 std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl;
00189 }
00190 bool result = false;
00191 if (PySequence_Check(obj)) {
00192 result = true;
00193 int count = PySequence_Size(obj);
00194 PyObject* value;
00195 for (int i = 0;i<count;i++) {
00196 value = PySequence_GetItem(obj,i);
00197
00198 QVariant v = PythonQtConv::PyObjToQVariant(value, innerType);
00199 if (v.isValid()) {
00200 list->push_back(qVariantValue<T>(v));
00201 } else {
00202 result = false;
00203 break;
00204 }
00205 }
00206 }
00207 return result;
00208 }
00209
00210 #endif