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