##// END OF EJS Templates
added error printing...
florianlink -
r130:b69fb3df3713
parent child
Show More
@@ -1,204 +1,210
1 #ifndef _PYTHONQTCONVERSION_H
1 #ifndef _PYTHONQTCONVERSION_H
2 #define _PYTHONQTCONVERSION_H
2 #define _PYTHONQTCONVERSION_H
3
3
4 /*
4 /*
5 *
5 *
6 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
6 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
7 *
7 *
8 * This library is free software; you can redistribute it and/or
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
11 * version 2.1 of the License, or (at your option) any later version.
12 *
12 *
13 * This library is distributed in the hope that it will be useful,
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
16 * Lesser General Public License for more details.
17 *
17 *
18 * Further, this software is distributed without any warranty that it is
18 * Further, this software is distributed without any warranty that it is
19 * free of the rightful claim of any third person regarding infringement
19 * free of the rightful claim of any third person regarding infringement
20 * or the like. Any license provided herein, whether implied or
20 * or the like. Any license provided herein, whether implied or
21 * otherwise, applies only to this software file. Patent licenses, if
21 * otherwise, applies only to this software file. Patent licenses, if
22 * any, provided herein do not apply to combinations of this program with
22 * any, provided herein do not apply to combinations of this program with
23 * other software, or any other product whatsoever.
23 * other software, or any other product whatsoever.
24 *
24 *
25 * You should have received a copy of the GNU Lesser General Public
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
28 *
29 * Contact information: MeVis Research GmbH, Universitaetsallee 29,
29 * Contact information: MeVis Research GmbH, Universitaetsallee 29,
30 * 28359 Bremen, Germany or:
30 * 28359 Bremen, Germany or:
31 *
31 *
32 * http://www.mevis.de
32 * http://www.mevis.de
33 *
33 *
34 */
34 */
35
35
36 //----------------------------------------------------------------------------------
36 //----------------------------------------------------------------------------------
37 /*!
37 /*!
38 // \file PythonQtConversion.h
38 // \file PythonQtConversion.h
39 // \author Florian Link
39 // \author Florian Link
40 // \author Last changed by $Author: florian $
40 // \author Last changed by $Author: florian $
41 // \date 2006-05
41 // \date 2006-05
42 */
42 */
43 //----------------------------------------------------------------------------------
43 //----------------------------------------------------------------------------------
44
44
45 #include "PythonQt.h"
45 #include "PythonQt.h"
46 #include "PythonQtMisc.h"
46 #include "PythonQtMisc.h"
47 #include "PythonQtClassInfo.h"
47 #include "PythonQtClassInfo.h"
48 #include "PythonQtMethodInfo.h"
48 #include "PythonQtMethodInfo.h"
49
49
50 #include <QWidget>
50 #include <QWidget>
51 #include <QList>
51 #include <QList>
52 #include <vector>
52 #include <vector>
53
53
54 typedef PyObject* PythonQtConvertMetaTypeToPythonCB(const void* inObject, int metaTypeId);
54 typedef PyObject* PythonQtConvertMetaTypeToPythonCB(const void* inObject, int metaTypeId);
55 typedef bool PythonQtConvertPythonToMetaTypeCB(PyObject* inObject, void* outObject, int metaTypeId, bool strict);
55 typedef bool PythonQtConvertPythonToMetaTypeCB(PyObject* inObject, void* outObject, int metaTypeId, bool strict);
56
56
57 #define PythonQtRegisterListTemplateConverter(type, innertype) \
57 #define PythonQtRegisterListTemplateConverter(type, innertype) \
58 { int typeId = qRegisterMetaType<type<innertype> >(#type"<"#innertype">"); \
58 { int typeId = qRegisterMetaType<type<innertype> >(#type"<"#innertype">"); \
59 PythonQtConv::registerPythonToMetaTypeConverter(typeId, PythonQtConvertPythonListToListOfValueType<type<innertype>, innertype>); \
59 PythonQtConv::registerPythonToMetaTypeConverter(typeId, PythonQtConvertPythonListToListOfValueType<type<innertype>, innertype>); \
60 PythonQtConv::registerMetaTypeToPythonConverter(typeId, PythonQtConvertListOfValueTypeToPythonList<type<innertype>, innertype>); \
60 PythonQtConv::registerMetaTypeToPythonConverter(typeId, PythonQtConvertListOfValueTypeToPythonList<type<innertype>, innertype>); \
61 }
61 }
62
62
63 #define PythonQtRegisterToolClassesTemplateConverter(innertype) \
63 #define PythonQtRegisterToolClassesTemplateConverter(innertype) \
64 PythonQtRegisterListTemplateConverter(QList, innertype); \
64 PythonQtRegisterListTemplateConverter(QList, innertype); \
65 PythonQtRegisterListTemplateConverter(QVector, innertype); \
65 PythonQtRegisterListTemplateConverter(QVector, innertype); \
66 PythonQtRegisterListTemplateConverter(std::vector, innertype);
66 PythonQtRegisterListTemplateConverter(std::vector, innertype);
67 // TODO: add QHash etc. here!
67 // TODO: add QHash etc. here!
68
68
69 //! a static class that offers methods for type conversion
69 //! a static class that offers methods for type conversion
70 class PYTHONQT_EXPORT PythonQtConv {
70 class PYTHONQT_EXPORT PythonQtConv {
71
71
72 public:
72 public:
73
73
74 //! get a ref counted True or False Python object
74 //! get a ref counted True or False Python object
75 static PyObject* GetPyBool(bool val);
75 static PyObject* GetPyBool(bool val);
76
76
77 //! converts the Qt parameter given in \c data, interpreting it as a \c info parameter, into a Python object,
77 //! converts the Qt parameter given in \c data, interpreting it as a \c info parameter, into a Python object,
78 static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data);
78 static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data);
79
79
80 //! convert python object to Qt (according to the given parameter) and if the conversion should be strict (classInfo is currently not used anymore)
80 //! convert python object to Qt (according to the given parameter) and if the conversion should be strict (classInfo is currently not used anymore)
81 static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* classInfo, void* alreadyAllocatedCPPObject = NULL);
81 static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* classInfo, void* alreadyAllocatedCPPObject = NULL);
82
82
83 //! creates a data storage for the passed parameter type and returns a void pointer to be set as arg[0] of qt_metacall
83 //! creates a data storage for the passed parameter type and returns a void pointer to be set as arg[0] of qt_metacall
84 static void* CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info);
84 static void* CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info);
85
85
86 //! converts QString to Python string (unicode!)
86 //! converts QString to Python string (unicode!)
87 static PyObject* QStringToPyObject(const QString& str);
87 static PyObject* QStringToPyObject(const QString& str);
88
88
89 //! converts QStringList to Python tuple
89 //! converts QStringList to Python tuple
90 static PyObject* QStringListToPyObject(const QStringList& list);
90 static PyObject* QStringListToPyObject(const QStringList& list);
91
91
92 //! converts QStringList to Python list
92 //! converts QStringList to Python list
93 static PyObject* QStringListToPyList(const QStringList& list);
93 static PyObject* QStringListToPyList(const QStringList& list);
94
94
95 //! get string representation of py object
95 //! get string representation of py object
96 static QString PyObjGetRepresentation(PyObject* val);
96 static QString PyObjGetRepresentation(PyObject* val);
97
97
98 //! get string value from py object
98 //! get string value from py object
99 static QString PyObjGetString(PyObject* val) { bool ok; QString s = PyObjGetString(val, false, ok); return s; }
99 static QString PyObjGetString(PyObject* val) { bool ok; QString s = PyObjGetString(val, false, ok); return s; }
100 //! get string value from py object
100 //! get string value from py object
101 static QString PyObjGetString(PyObject* val, bool strict, bool &ok);
101 static QString PyObjGetString(PyObject* val, bool strict, bool &ok);
102 //! get bytes from py object
102 //! get bytes from py object
103 static QByteArray PyObjGetBytes(PyObject* val, bool strict, bool &ok);
103 static QByteArray PyObjGetBytes(PyObject* val, bool strict, bool &ok);
104 //! get int from py object
104 //! get int from py object
105 static int PyObjGetInt(PyObject* val, bool strict, bool &ok);
105 static int PyObjGetInt(PyObject* val, bool strict, bool &ok);
106 //! get int64 from py object
106 //! get int64 from py object
107 static qint64 PyObjGetLongLong(PyObject* val, bool strict, bool &ok);
107 static qint64 PyObjGetLongLong(PyObject* val, bool strict, bool &ok);
108 //! get int64 from py object
108 //! get int64 from py object
109 static quint64 PyObjGetULongLong(PyObject* val, bool strict, bool &ok);
109 static quint64 PyObjGetULongLong(PyObject* val, bool strict, bool &ok);
110 //! get double from py object
110 //! get double from py object
111 static double PyObjGetDouble(PyObject* val, bool strict, bool &ok);
111 static double PyObjGetDouble(PyObject* val, bool strict, bool &ok);
112 //! get bool from py object
112 //! get bool from py object
113 static bool PyObjGetBool(PyObject* val, bool strict, bool &ok);
113 static bool PyObjGetBool(PyObject* val, bool strict, bool &ok);
114
114
115 //! create a string list from python sequence
115 //! create a string list from python sequence
116 static QStringList PyObjToStringList(PyObject* val, bool strict, bool& ok);
116 static QStringList PyObjToStringList(PyObject* val, bool strict, bool& ok);
117
117
118 //! convert python object to qvariant, if type is given it will try to create a qvariant of that type, otherwise
118 //! convert python object to qvariant, if type is given it will try to create a qvariant of that type, otherwise
119 //! it will guess from the python type
119 //! it will guess from the python type
120 static QVariant PyObjToQVariant(PyObject* val, int type = -1);
120 static QVariant PyObjToQVariant(PyObject* val, int type = -1);
121
121
122 //! convert QVariant from PyObject
122 //! convert QVariant from PyObject
123 static PyObject* QVariantToPyObject(const QVariant& v);
123 static PyObject* QVariantToPyObject(const QVariant& v);
124
124
125 static PyObject* QVariantMapToPyObject(const QVariantMap& m);
125 static PyObject* QVariantMapToPyObject(const QVariantMap& m);
126 static PyObject* QVariantListToPyObject(const QVariantList& l);
126 static PyObject* QVariantListToPyObject(const QVariantList& l);
127
127
128 //! get human readable string from CPP object (when the metatype is known)
128 //! get human readable string from CPP object (when the metatype is known)
129 static QString CPPObjectToString(int type, const void* data);
129 static QString CPPObjectToString(int type, const void* data);
130
130
131 //! register a converter callback from python to cpp for given metatype
131 //! register a converter callback from python to cpp for given metatype
132 static void registerPythonToMetaTypeConverter(int metaTypeId, PythonQtConvertPythonToMetaTypeCB* cb) { _pythonToMetaTypeConverters.insert(metaTypeId, cb); }
132 static void registerPythonToMetaTypeConverter(int metaTypeId, PythonQtConvertPythonToMetaTypeCB* cb) { _pythonToMetaTypeConverters.insert(metaTypeId, cb); }
133
133
134 //! register a converter callback from cpp to python for given metatype
134 //! register a converter callback from cpp to python for given metatype
135 static void registerMetaTypeToPythonConverter(int metaTypeId, PythonQtConvertMetaTypeToPythonCB* cb) { _metaTypeToPythonConverters.insert(metaTypeId, cb); }
135 static void registerMetaTypeToPythonConverter(int metaTypeId, PythonQtConvertMetaTypeToPythonCB* cb) { _metaTypeToPythonConverters.insert(metaTypeId, cb); }
136
136
137 //! returns the inner type id of a simple template of the form SomeObject<InnerType>
137 //! returns the inner type id of a simple template of the form SomeObject<InnerType>
138 static int getInnerTemplateMetaType(const QByteArray& typeName);
138 static int getInnerTemplateMetaType(const QByteArray& typeName);
139
139
140 //! converts the Qt parameter given in \c data, interpreting it as a \c type registered qvariant/meta type, into a Python object,
140 //! converts the Qt parameter given in \c data, interpreting it as a \c type registered qvariant/meta type, into a Python object,
141 static PyObject* ConvertQtValueToPythonInternal(int type, const void* data);
141 static PyObject* ConvertQtValueToPythonInternal(int type, const void* data);
142
142
143 public:
143 public:
144
144
145 static PythonQtValueStorage<qint64, 128> global_valueStorage;
145 static PythonQtValueStorage<qint64, 128> global_valueStorage;
146 static PythonQtValueStorage<void*, 128> global_ptrStorage;
146 static PythonQtValueStorage<void*, 128> global_ptrStorage;
147 static PythonQtValueStorage<QVariant, 32> global_variantStorage;
147 static PythonQtValueStorage<QVariant, 32> global_variantStorage;
148
148
149 protected:
149 protected:
150 static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
150 static QHash<int, PythonQtConvertMetaTypeToPythonCB*> _metaTypeToPythonConverters;
151 static QHash<int, PythonQtConvertPythonToMetaTypeCB*> _pythonToMetaTypeConverters;
151 static QHash<int, PythonQtConvertPythonToMetaTypeCB*> _pythonToMetaTypeConverters;
152
152
153 //! handle automatic conversion of some special types (QColor, QBrush, ...)
153 //! handle automatic conversion of some special types (QColor, QBrush, ...)
154 static void* handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject);
154 static void* handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject);
155
155
156 //! converts the list of pointers of given type to Python
156 //! converts the list of pointers of given type to Python
157 static PyObject* ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& type);
157 static PyObject* ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& type);
158 //! tries to convert the python object to a QList of pointers to \c type objects, returns true on success
158 //! tries to convert the python object to a QList of pointers to \c type objects, returns true on success
159 static bool ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool strict);
159 static bool ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool strict);
160
160
161 //! cast wrapper to given className if possible
161 //! cast wrapper to given className if possible
162 static void* castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok);
162 static void* castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok);
163 };
163 };
164
164
165 template<class ListType, class T>
165 template<class ListType, class T>
166 PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* /*QList<T>* */ inList, int metaTypeId)
166 PyObject* PythonQtConvertListOfValueTypeToPythonList(const void* /*QList<T>* */ inList, int metaTypeId)
167 {
167 {
168 ListType* list = (ListType*)inList;
168 ListType* list = (ListType*)inList;
169 static const int innerType = PythonQtConv::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId)));
169 static const int innerType = PythonQtConv::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId)));
170 if (innerType == QVariant::Invalid) {
171 std::cerr << "PythonQtConvertListOfValueTypeToPythonList: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl;
172 }
170 PyObject* result = PyTuple_New(list->size());
173 PyObject* result = PyTuple_New(list->size());
171 int i = 0;
174 int i = 0;
172 foreach (const T& value, *list) {
175 foreach (const T& value, *list) {
173 PyTuple_SET_ITEM(result, i, PythonQtConv::ConvertQtValueToPythonInternal(innerType, &value));
176 PyTuple_SET_ITEM(result, i, PythonQtConv::ConvertQtValueToPythonInternal(innerType, &value));
174 i++;
177 i++;
175 }
178 }
176 return result;
179 return result;
177 }
180 }
178
181
179 template<class ListType, class T>
182 template<class ListType, class T>
180 bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* /*QList<T>* */ outList, int metaTypeId, bool /*strict*/)
183 bool PythonQtConvertPythonListToListOfValueType(PyObject* obj, void* /*QList<T>* */ outList, int metaTypeId, bool /*strict*/)
181 {
184 {
182 ListType* list = (ListType*)outList;
185 ListType* list = (ListType*)outList;
183 static const int innerType = PythonQtConv::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId)));
186 static const int innerType = PythonQtConv::getInnerTemplateMetaType(QByteArray(QMetaType::typeName(metaTypeId)));
187 if (innerType == QVariant::Invalid) {
188 std::cerr << "PythonQtConvertPythonListToListOfValueType: unknown inner type " << QMetaType::typeName(metaTypeId) << std::endl;
189 }
184 bool result = false;
190 bool result = false;
185 if (PySequence_Check(obj)) {
191 if (PySequence_Check(obj)) {
186 result = true;
192 result = true;
187 int count = PySequence_Size(obj);
193 int count = PySequence_Size(obj);
188 PyObject* value;
194 PyObject* value;
189 for (int i = 0;i<count;i++) {
195 for (int i = 0;i<count;i++) {
190 value = PySequence_GetItem(obj,i);
196 value = PySequence_GetItem(obj,i);
191 // this is quite some overhead, but it avoids having another large switch...
197 // this is quite some overhead, but it avoids having another large switch...
192 QVariant v = PythonQtConv::PyObjToQVariant(value, innerType);
198 QVariant v = PythonQtConv::PyObjToQVariant(value, innerType);
193 if (v.isValid()) {
199 if (v.isValid()) {
194 list->push_back(qVariantValue<T>(v));
200 list->push_back(qVariantValue<T>(v));
195 } else {
201 } else {
196 result = false;
202 result = false;
197 break;
203 break;
198 }
204 }
199 }
205 }
200 }
206 }
201 return result;
207 return result;
202 }
208 }
203
209
204 #endif
210 #endif
General Comments 0
You need to be logged in to leave comments. Login now