##// END OF EJS Templates
support enum values on signals as well, all tests should succeed now...
florianlink -
r56:607d4eb3cb2d
parent child
Show More
@@ -431,6 +431,14 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla
431 431 return result;
432 432 }
433 433
434 PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned int enumValue)
435 {
436 PyObject* args = Py_BuildValue("(i)", enumValue);
437 PyObject* result = PyObject_Call(enumType, args, NULL);
438 Py_DECREF(args);
439 return result;
440 }
441
434 442 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
435 443 PyObject* result;
436 444
@@ -443,11 +443,14 public:
443 443 //! add a decorator object
444 444 void addDecorators(QObject* o, int decoTypes);
445 445
446 //! helper method that creates a PythonQtClassWrapper object
446 //! helper method that creates a PythonQtClassWrapper object (returns a new reference)
447 447 PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL);
448 448
449 //! helper that creates a new int derived class that represents the enum of the given name
450 PyObject* createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject);
449 //! create a new instance of the given enum type with given value (returns a new reference)
450 static PyObject* createEnumValueInstance(PyObject* enumType, unsigned int enumValue);
451
452 //! helper that creates a new int derived class that represents the enum of the given name (returns a new reference)
453 static PyObject* createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject);
451 454
452 455 //! helper method that creates a PythonQtInstanceWrapper object and registers it in the object map
453 456 PythonQtInstanceWrapper* createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr = NULL);
@@ -258,11 +258,8 bool PythonQtClassInfo::lookForEnumAndCache(const QMetaObject* meta, const char*
258 258 if (qstrcmp(e.key(j), memberName)==0) {
259 259 PyObject* enumType = findEnumWrapper(e.name());
260 260 if (enumType) {
261 PyObject* args = Py_BuildValue("(i)", e.value(j));
262 PyObject* enumValue = PyObject_Call(enumType, args, NULL);
263 Py_DECREF(args);
264 261 PythonQtObjectPtr enumValuePtr;
265 enumValuePtr.setNewRef(enumValue);
262 enumValuePtr.setNewRef(PythonQtPrivate::createEnumValueInstance(enumType, e.value(j)));
266 263 PythonQtMemberInfo newInfo(enumValuePtr);
267 264 _cachedMembers.insert(memberName, newInfo);
268 265 #ifdef PYTHONQT_DEBUG
@@ -784,7 +781,7 void PythonQtClassInfo::createEnumWrappers(const QMetaObject* meta)
784 781 for (int i = meta->enumeratorOffset();i<meta->enumeratorCount();i++) {
785 782 QMetaEnum e = meta->enumerator(i);
786 783 PythonQtObjectPtr p;
787 p.setNewRef(PythonQt::priv()->createNewPythonQtEnumWrapper(e.name(), _pythonQtClassWrapper));
784 p.setNewRef(PythonQtPrivate::createNewPythonQtEnumWrapper(e.name(), _pythonQtClassWrapper));
788 785 _enumWrappers.append(p);
789 786 }
790 787 }
@@ -806,6 +803,10 void PythonQtClassInfo::createEnumWrappers()
806 803 }
807 804
808 805 PyObject* PythonQtClassInfo::findEnumWrapper(const char* name) {
806 // force enum creation
807 if (!_enumsCreated) {
808 createEnumWrappers();
809 }
809 810 foreach(const PythonQtObjectPtr& p, _enumWrappers) {
810 811 const char* className = ((PyTypeObject*)p.object())->tp_name;
811 812 if (qstrcmp(className, name)==0) {
@@ -60,6 +60,17 PyObject* PythonQtConv::GetPyBool(bool val)
60 60 }
61 61
62 62 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data) {
63 // is it an enum value?
64 if (info.enumWrapper) {
65 if (!info.isPointer) {
66 return PythonQtPrivate::createEnumValueInstance(info.enumWrapper, *((unsigned int*)data));
67 } else {
68 // we do not support pointers to enums (who needs them?)
69 Py_INCREF(Py_None);
70 return Py_None;
71 }
72 }
73
63 74 if (info.typeId == QMetaType::Void) {
64 75 Py_INCREF(Py_None);
65 76 return Py_None;
@@ -175,6 +186,9 return Py_None;
175 186 void* ptr = NULL;
176 187 if (info.isPointer) {
177 188 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
189 } else if (info.enumWrapper) {
190 // create enum return value
191 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
178 192 } else {
179 193 switch (info.typeId) {
180 194 case QMetaType::Char:
@@ -118,38 +118,29 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
118 118 }
119 119
120 120 if (ok) {
121 bool returnValueIsEnum = false;
122
123 121 // parameters are ok, now create the qt return value which is assigned to by metacall
124 122 if (returnValueParam.typeId != QMetaType::Void) {
125 // extra handling of enum return value
126 if (!returnValueParam.isPointer && returnValueParam.enumWrapper) {
127 // create enum return value
128 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, argList[0]);
129 returnValueIsEnum = true;
130 } else {
123 // create empty default value for the return value
124 if (!directReturnValuePointer) {
131 125 // create empty default value for the return value
132 if (!directReturnValuePointer) {
133 // create empty default value for the return value
134 argList[0] = PythonQtConv::CreateQtReturnValue(returnValueParam);
135 if (argList[0]==NULL) {
136 // return value could not be created, maybe we have a registered class with a default constructor, so that we can construct the pythonqt wrapper object and
137 // pass its internal pointer
138 PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(returnValueParam.name);
139 if (info && info->pythonQtClassWrapper()) {
140 PyObject* emptyTuple = PyTuple_New(0);
141 // 1) default construct an empty object as python object (owned by PythonQt), by calling the meta class with empty arguments
142 result = PyObject_Call((PyObject*)info->pythonQtClassWrapper(), emptyTuple, NULL);
143 if (result) {
144 argList[0] = ((PythonQtInstanceWrapper*)result)->_wrappedPtr;
145 }
146 Py_DECREF(emptyTuple);
147 }
148 }
149 } else {
150 // we can use our pointer directly!
151 argList[0] = directReturnValuePointer;
126 argList[0] = PythonQtConv::CreateQtReturnValue(returnValueParam);
127 if (argList[0]==NULL) {
128 // return value could not be created, maybe we have a registered class with a default constructor, so that we can construct the pythonqt wrapper object and
129 // pass its internal pointer
130 PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(returnValueParam.name);
131 if (info && info->pythonQtClassWrapper()) {
132 PyObject* emptyTuple = PyTuple_New(0);
133 // 1) default construct an empty object as python object (owned by PythonQt), by calling the meta class with empty arguments
134 result = PyObject_Call((PyObject*)info->pythonQtClassWrapper(), emptyTuple, NULL);
135 if (result) {
136 argList[0] = ((PythonQtInstanceWrapper*)result)->_wrappedPtr;
137 }
138 Py_DECREF(emptyTuple);
139 }
152 140 }
141 } else {
142 // we can use our pointer directly!
143 argList[0] = directReturnValuePointer;
153 144 }
154 145 }
155 146
@@ -161,13 +152,9 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
161 152 if (directReturnValuePointer) {
162 153 result = NULL;
163 154 } else {
164 if (!returnValueIsEnum) {
165 // the resulting object maybe present already, because we created it above at 1)...
166 if (!result) {
167 result = PythonQtConv::ConvertQtValueToPython(returnValueParam, argList[0]);
168 }
169 } else {
170 result = PyInt_FromLong(*((unsigned int*)argList[0]));
155 // the resulting object maybe present already, because we created it above at 1)...
156 if (!result) {
157 result = PythonQtConv::ConvertQtValueToPython(returnValueParam, argList[0]);
171 158 }
172 159 }
173 160 } else {
General Comments 0
You need to be logged in to leave comments. Login now