@@ -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