@@ -46,6 +46,7 | |||||
46 | #include "PythonQtSlot.h" |
|
46 | #include "PythonQtSlot.h" | |
47 | #include "PythonQtClassInfo.h" |
|
47 | #include "PythonQtClassInfo.h" | |
48 | #include "PythonQtConversion.h" |
|
48 | #include "PythonQtConversion.h" | |
|
49 | #include "PythonQtInstanceWrapper.h" | |||
49 |
|
50 | |||
50 | static PyObject* PythonQtClassWrapper_alloc(PyTypeObject *self, Py_ssize_t nitems) |
|
51 | static PyObject* PythonQtClassWrapper_alloc(PyTypeObject *self, Py_ssize_t nitems) | |
51 | { |
|
52 | { | |
@@ -93,8 +94,39 static PyObject *PythonQtClassWrapper_help(PythonQtClassWrapper* type) | |||||
93 | return PythonQt::self()->helpCalled(type->classInfo()); |
|
94 | return PythonQt::self()->helpCalled(type->classInfo()); | |
94 | } |
|
95 | } | |
95 |
|
96 | |||
|
97 | PyObject *PythonQtClassWrapper__init__(PythonQtClassWrapper *type, PyObject *args) | |||
|
98 | { | |||
|
99 | Py_ssize_t argc = PyTuple_Size(args); | |||
|
100 | if (argc>0) { | |||
|
101 | // we need to call __init__ of the instance | |||
|
102 | PyObject* self = PyTuple_GET_ITEM(args, 0); | |||
|
103 | if (PyObject_TypeCheck(self, (PyTypeObject*)type->classInfo()->pythonQtClassWrapper())) { | |||
|
104 | PyObject* newargs = PyTuple_New(argc-1); | |||
|
105 | for (int i = 0;i<argc-1; i++) { | |||
|
106 | PyTuple_SET_ITEM(newargs, i,PyTuple_GET_ITEM(args, i+1)); | |||
|
107 | } | |||
|
108 | PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)self; | |||
|
109 | int result = PythonQtInstanceWrapper_init(wrapper, newargs, NULL); | |||
|
110 | Py_DECREF(newargs); | |||
|
111 | if (result==0) { | |||
|
112 | Py_INCREF(Py_None); | |||
|
113 | return Py_None; | |||
|
114 | } else { | |||
|
115 | // init failed! | |||
|
116 | } | |||
|
117 | } else { | |||
|
118 | // self not of correct type! | |||
|
119 | } | |||
|
120 | } else { | |||
|
121 | // wrong number of args | |||
|
122 | } | |||
|
123 | return NULL; | |||
|
124 | } | |||
96 |
|
125 | |||
97 | static PyMethodDef PythonQtClassWrapper_methods[] = { |
|
126 | static PyMethodDef PythonQtClassWrapper_methods[] = { | |
|
127 | {"__init__", (PyCFunction)PythonQtClassWrapper__init__, METH_VARARGS, | |||
|
128 | "Return the classname of the object" | |||
|
129 | }, | |||
98 | {"className", (PyCFunction)PythonQtClassWrapper_classname, METH_NOARGS, |
|
130 | {"className", (PyCFunction)PythonQtClassWrapper_classname, METH_NOARGS, | |
99 | "Return the classname of the object" |
|
131 | "Return the classname of the object" | |
100 | }, |
|
132 | }, | |
@@ -109,17 +141,44 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) | |||||
109 | { |
|
141 | { | |
110 | const char *attributeName; |
|
142 | const char *attributeName; | |
111 | PythonQtClassWrapper *wrapper = (PythonQtClassWrapper *)obj; |
|
143 | PythonQtClassWrapper *wrapper = (PythonQtClassWrapper *)obj; | |
112 |
|
144 | |||
113 |
|
|
145 | if ((attributeName = PyString_AsString(name)) == NULL) { | |
114 | return NULL; |
|
146 | return NULL; | |
115 | } |
|
147 | } | |
|
148 | if (obj == (PyObject*)&PythonQtInstanceWrapper_Type) { | |||
|
149 | return NULL; | |||
|
150 | } | |||
116 |
|
151 | |||
117 | PythonQtMemberInfo member = wrapper->classInfo()->member(attributeName); |
|
152 | if (qstrcmp(attributeName, "__dict__")==0) { | |
118 | if (member._type == PythonQtMemberInfo::EnumValue) { |
|
153 | PyObject* dict = ((PyTypeObject *)wrapper)->tp_dict; | |
119 | return PyInt_FromLong(member._enumValue); |
|
154 | if (!wrapper->classInfo()) { | |
|
155 | Py_INCREF(dict); | |||
|
156 | return dict; | |||
|
157 | } | |||
|
158 | dict = PyDict_Copy(dict); | |||
|
159 | ||||
|
160 | QStringList l = wrapper->classInfo()->memberList(true); | |||
|
161 | foreach (QString name, l) { | |||
|
162 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); | |||
|
163 | PyDict_SetItemString(dict, name.toLatin1().data(), o); | |||
|
164 | Py_DECREF(o); | |||
|
165 | } | |||
|
166 | if (wrapper->classInfo()->constructors()) { | |||
|
167 | PyDict_SetItemString(dict, "__init__", PyCFunction_New(&PythonQtClassWrapper_methods[0], obj)); | |||
|
168 | } | |||
|
169 | PyDict_SetItemString(dict, PythonQtClassWrapper_methods[1].ml_name, PyCFunction_New(&PythonQtClassWrapper_methods[1], obj)); | |||
|
170 | PyDict_SetItemString(dict, PythonQtClassWrapper_methods[2].ml_name, PyCFunction_New(&PythonQtClassWrapper_methods[2], obj)); | |||
|
171 | return dict; | |||
120 | } |
|
172 | } | |
121 | if (member._type == PythonQtMemberInfo::Slot && member._slot->isClassDecorator()) { |
|
173 | ||
122 | return PythonQtSlotFunction_New(member._slot, obj, NULL); |
|
174 | if (wrapper->classInfo()) { | |
|
175 | PythonQtMemberInfo member = wrapper->classInfo()->member(attributeName); | |||
|
176 | if (member._type == PythonQtMemberInfo::EnumValue) { | |||
|
177 | return PyInt_FromLong(member._enumValue); | |||
|
178 | } else | |||
|
179 | if (member._type == PythonQtMemberInfo::Slot && member._slot->isClassDecorator()) { | |||
|
180 | return PythonQtSlotFunction_New(member._slot, obj, NULL); | |||
|
181 | } | |||
123 | } |
|
182 | } | |
124 |
|
183 | |||
125 | // look for the interal methods (className(), help()) |
|
184 | // look for the interal methods (className(), help()) | |
@@ -129,15 +188,10 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) | |||||
129 | } |
|
188 | } | |
130 | PyErr_Clear(); |
|
189 | PyErr_Clear(); | |
131 |
|
190 | |||
132 | if (qstrcmp(attributeName, "__dict__")==0) { |
|
191 | // look in super | |
133 | QStringList l = wrapper->classInfo()->memberList(true); |
|
192 | PyObject* superAttr = PyType_Type.tp_getattro(obj, name); | |
134 | PyObject* dict = PyDict_New(); |
|
193 | if (superAttr) { | |
135 | foreach (QString name, l) { |
|
194 | return superAttr; | |
136 | //PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); |
|
|||
137 | PyDict_SetItemString(dict, name.toLatin1().data(), Py_None); |
|
|||
138 | //Py_DECREF(o); |
|
|||
139 | } |
|
|||
140 | return dict; |
|
|||
141 | } |
|
195 | } | |
142 |
|
196 | |||
143 | QString error = QString(wrapper->classInfo()->className()) + " has no attribute named '" + QString(attributeName) + "'"; |
|
197 | QString error = QString(wrapper->classInfo()->className()) + " has no attribute named '" + QString(attributeName) + "'"; | |
@@ -211,8 +265,8 PyTypeObject PythonQtClassWrapper_Type = { | |||||
211 | 0, /* tp_weaklistoffset */ |
|
265 | 0, /* tp_weaklistoffset */ | |
212 | 0, /* tp_iter */ |
|
266 | 0, /* tp_iter */ | |
213 | 0, /* tp_iternext */ |
|
267 | 0, /* tp_iternext */ | |
214 | 0, /* tp_methods */ |
|
268 | 0, /* tp_methods */ | |
215 | 0, /* tp_members */ |
|
269 | 0, /* tp_members */ | |
216 | 0, /* tp_getset */ |
|
270 | 0, /* tp_getset */ | |
217 | 0, /* tp_base */ |
|
271 | 0, /* tp_base */ | |
218 | 0, /* tp_dict */ |
|
272 | 0, /* tp_dict */ |
@@ -134,7 +134,7 static PyObject* PythonQtInstanceWrapper_new(PyTypeObject *type, PyObject * args | |||||
134 | return (PyObject *)self; |
|
134 | return (PyObject *)self; | |
135 | } |
|
135 | } | |
136 |
|
136 | |||
137 |
|
|
137 | int PythonQtInstanceWrapper_init(PythonQtInstanceWrapper * self, PyObject * args, PyObject * kwds) | |
138 | { |
|
138 | { | |
139 | PyObject* result = NULL; |
|
139 | PyObject* result = NULL; | |
140 |
|
140 | |||
@@ -247,29 +247,34 static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) | |||||
247 | } |
|
247 | } | |
248 | PyErr_Clear(); |
|
248 | PyErr_Clear(); | |
249 |
|
249 | |||
250 | if (wrapper->_obj) { |
|
|||
251 | // look for a child |
|
|||
252 | QObjectList children = wrapper->_obj->children(); |
|
|||
253 | for (int i = 0; i < children.count(); i++) { |
|
|||
254 | QObject *child = children.at(i); |
|
|||
255 | if (child->objectName() == attributeName) { |
|
|||
256 | return PythonQt::self()->priv()->wrapQObject(child); |
|
|||
257 | } |
|
|||
258 | } |
|
|||
259 | } |
|
|||
260 |
|
||||
261 | if (qstrcmp(attributeName, "__dict__")==0) { |
|
250 | if (qstrcmp(attributeName, "__dict__")==0) { | |
262 | QStringList l = wrapper->classInfo()->memberList(false); |
|
251 | QStringList l = wrapper->classInfo()->memberList(false); | |
263 | PyObject* dict = PyDict_New(); |
|
252 | PyObject* dict = PyDict_New(); | |
264 | foreach (QString name, l) { |
|
253 | foreach (QString name, l) { | |
265 |
|
|
254 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); | |
266 | PyDict_SetItemString(dict, name.toLatin1().data(), Py_None); |
|
255 | PyDict_SetItemString(dict, name.toLatin1().data(), Py_None); | |
267 |
|
|
256 | Py_DECREF(o); | |
268 | } |
|
257 | } | |
269 | // Note: we do not put children into the dict, is would look confusing?! |
|
258 | // Note: we do not put children into the dict, is would look confusing?! | |
270 | return dict; |
|
259 | return dict; | |
271 | } |
|
260 | } | |
272 |
|
261 | |||
|
262 | // look in super | |||
|
263 | PyObject* superAttr = PyBaseObject_Type.tp_getattro(obj, name); | |||
|
264 | if (superAttr) { | |||
|
265 | return superAttr; | |||
|
266 | } | |||
|
267 | ||||
|
268 | if (wrapper->_obj) { | |||
|
269 | // look for a child | |||
|
270 | QObjectList children = wrapper->_obj->children(); | |||
|
271 | for (int i = 0; i < children.count(); i++) { | |||
|
272 | QObject *child = children.at(i); | |||
|
273 | if (child->objectName() == attributeName) { | |||
|
274 | return PythonQt::self()->priv()->wrapQObject(child); | |||
|
275 | } | |||
|
276 | } | |||
|
277 | } | |||
273 |
|
278 | |||
274 | QString error = QString(wrapper->classInfo()->className()) + " has no attribute named '" + QString(attributeName) + "'"; |
|
279 | QString error = QString(wrapper->classInfo()->className()) + " has no attribute named '" + QString(attributeName) + "'"; | |
275 | PyErr_SetString(PyExc_AttributeError, error.toLatin1().data()); |
|
280 | PyErr_SetString(PyExc_AttributeError, error.toLatin1().data()); | |
@@ -332,6 +337,7 static int PythonQtInstanceWrapper_setattro(PyObject *obj,PyObject *name,PyObjec | |||||
332 | static PyObject * PythonQtInstanceWrapper_str(PyObject * obj) |
|
337 | static PyObject * PythonQtInstanceWrapper_str(PyObject * obj) | |
333 | { |
|
338 | { | |
334 | PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; |
|
339 | PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; | |
|
340 | const char* typeName = obj->ob_type->tp_name; | |||
335 | QObject *qobj = wrapper->_obj; |
|
341 | QObject *qobj = wrapper->_obj; | |
336 | if (wrapper->_wrappedPtr) { |
|
342 | if (wrapper->_wrappedPtr) { | |
337 | QString str = PythonQtConv::CPPObjectToString(wrapper->classInfo()->metaTypeId(), wrapper->_wrappedPtr); |
|
343 | QString str = PythonQtConv::CPPObjectToString(wrapper->classInfo()->metaTypeId(), wrapper->_wrappedPtr); | |
@@ -339,28 +345,30 static PyObject * PythonQtInstanceWrapper_str(PyObject * obj) | |||||
339 | return PyString_FromFormat("%s", str.toLatin1().constData()); |
|
345 | return PyString_FromFormat("%s", str.toLatin1().constData()); | |
340 | } else |
|
346 | } else | |
341 | if (wrapper->_obj) { |
|
347 | if (wrapper->_obj) { | |
342 |
return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", |
|
348 | return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj); | |
343 | } else { |
|
349 | } else { | |
344 |
return PyString_FromFormat("%s (C++ Object %p)", |
|
350 | return PyString_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr); | |
345 | } |
|
351 | } | |
346 | } else { |
|
352 | } else { | |
347 |
return PyString_FromFormat("%s (QObject %p)", |
|
353 | return PyString_FromFormat("%s (QObject %p)", typeName, qobj); | |
348 | } |
|
354 | } | |
349 | } |
|
355 | } | |
350 |
|
356 | |||
351 | static PyObject * PythonQtInstanceWrapper_repr(PyObject * obj) |
|
357 | static PyObject * PythonQtInstanceWrapper_repr(PyObject * obj) | |
352 | { |
|
358 | { | |
353 | PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; |
|
359 | PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)obj; | |
|
360 | const char* typeName = obj->ob_type->tp_name; | |||
|
361 | ||||
354 |
|
|
362 | QObject *qobj = wrapper->_obj; | |
355 | if (wrapper->_wrappedPtr) { |
|
363 | if (wrapper->_wrappedPtr) { | |
356 | QString str = PythonQtConv::CPPObjectToString(wrapper->classInfo()->metaTypeId(), wrapper->_wrappedPtr); |
|
364 | QString str = PythonQtConv::CPPObjectToString(wrapper->classInfo()->metaTypeId(), wrapper->_wrappedPtr); | |
357 | if (!str.isEmpty()) { |
|
365 | if (!str.isEmpty()) { | |
358 |
return PyString_FromFormat("%s(%s, %p)", |
|
366 | return PyString_FromFormat("%s(%s, %p)", typeName, str.toLatin1().constData(), wrapper->_wrappedPtr); | |
359 | } else |
|
367 | } else | |
360 | if (wrapper->_obj) { |
|
368 | if (wrapper->_obj) { | |
361 |
return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", |
|
369 | return PyString_FromFormat("%s (C++ Object %p wrapped by %s %p))", typeName, wrapper->_wrappedPtr, wrapper->_obj->metaObject()->className(), qobj); | |
362 | } else { |
|
370 | } else { | |
363 |
return PyString_FromFormat("%s (C++ Object %p)", |
|
371 | return PyString_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr); | |
364 | } |
|
372 | } | |
365 | } else { |
|
373 | } else { | |
366 | return PyString_FromFormat("%s (QObject %p)", wrapper->classInfo()->className(), qobj); |
|
374 | return PyString_FromFormat("%s (QObject %p)", wrapper->classInfo()->className(), qobj); |
General Comments 0
You need to be logged in to leave comments.
Login now