PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer) { int argc = args?PyTuple_Size(args):0; #ifdef PYTHONQT_DEBUG std::cout << "called " << info->metaMethod()->typeName() << " " << info->metaMethod()->signature() << std::endl; #endif PyObject* r = NULL; bool ok = false; if (directReturnValuePointer) { *directReturnValuePointer = NULL; } if (info->nextInfo()) { // overloaded slot call, try on all slots with strict conversion first bool strict = true; PythonQtSlotInfo* i = info; while (i) { bool skipFirst = i->isInstanceDecorator(); if (i->parameterCount()-1-(skipFirst?1:0) == argc) { PyErr_Clear(); ok = PythonQtCallSlot(classInfo, objectToCall, args, strict, i, firstArg, &r, directReturnValuePointer); if (PyErr_Occurred() || ok) break; } i = i->nextInfo(); if (!i) { if (strict) { // one more run without being strict strict = false; i = info; } } } if (!ok && !PyErr_Occurred()) { QString e = QString("Could not find matching overload for given arguments:\n" + PythonQtConv::PyObjGetString(args) + "\n The following slots are available:\n"); PythonQtSlotInfo* i = info; while (i) { e += QString(i->fullSignature()) + "\n"; i = i->nextInfo(); } PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); } } else { // simple (non-overloaded) slot call bool skipFirst = info->isInstanceDecorator(); if (info->parameterCount()-1-(skipFirst?1:0) == argc) { PyErr_Clear(); ok = PythonQtCallSlot(classInfo, objectToCall, args, false, info, firstArg, &r, directReturnValuePointer); if (!ok && !PyErr_Occurred()) { QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args); PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); } } else { QString e = QString("Called ") + info->fullSignature() + " with wrong number of arguments: " + PythonQtConv::PyObjGetString(args); PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); } } return r; }
static PyObject * meth_get__doc__(PythonQtSlotFunctionObject * m, void * /*closure*/) { QByteArray doc; PythonQtSlotInfo* info = m->m_ml; const QByteArray& returnType = info->parameters().at(0).name; int returnTypeId = info->parameters().at(0).typeId; PythonQtSlotInfo* longestInfo = info; PythonQtSlotInfo* infoSearch = info->nextInfo(); while (infoSearch) { if (longestInfo->parameterCount() < infoSearch->parameterCount()) { longestInfo = infoSearch; } infoSearch = infoSearch->nextInfo(); } doc = "X." + info->slotName(true) + "("; for (int i = 1;i<longestInfo->parameterCount(); i++) { if (i!=1) { doc += ", "; } doc += QString('a' + i-1); } doc += ")"; QByteArray pyReturnType; if (returnType == "QString" || returnType == "SbName" || returnType == "SbString") { pyReturnType = "str"; } else if (returnType.startsWith("QVector<") || returnType.startsWith("QList<") || returnType == "QStringList" || returnType == "QObjectList" || returnType == "QVariantList") { pyReturnType = "tuple"; } else if (returnType.startsWith("QHash<") || returnType.startsWith("QMap<") || returnType == "QVariantMap" || returnType == "QVariantHash") { pyReturnType = "dict"; } else if (returnTypeId == QVariant::Bool) { pyReturnType = "bool"; } else if (returnTypeId == PythonQtMethodInfo::Variant) { pyReturnType = "object"; } else if (returnTypeId == QMetaType::Char || returnTypeId == QMetaType::UChar || returnTypeId == QMetaType::Short || returnTypeId == QMetaType::UShort || returnTypeId == QMetaType::Int || returnTypeId == QMetaType::UInt || returnTypeId == QMetaType::Long || returnTypeId == QMetaType::ULong || returnTypeId == QMetaType::LongLong || returnTypeId == QMetaType::ULongLong) { pyReturnType = "int"; } else if (returnTypeId == QMetaType::Float || returnTypeId == QMetaType::Double) { pyReturnType = "float"; } else { PythonQtClassInfo* returnTypeClassInfo = PythonQt::priv()->getClassInfo(returnType); if (returnTypeClassInfo) { PyObject* s = PyObject_GetAttrString(returnTypeClassInfo->pythonQtClassWrapper(), "__module__"); if (s) { pyReturnType = QByteArray(PyString_AsString(s)) + "." + returnType; Py_DECREF(s); } } } if (!pyReturnType.isEmpty()) { doc += " -> " + pyReturnType; } return PyString_FromString(doc.constData()); }
PyObject *PythonQtMemberFunction_parameterNames(PythonQtSlotInfo* theInfo) { PythonQtSlotInfo* info = theInfo; int count = 0; while (info) { info = info->nextInfo(); count++; } info = theInfo; PyObject* result = PyTuple_New(count); for (int j = 0;j<count;j++) { QList<QByteArray> names = info->metaMethod()->parameterNames(); PyObject* tuple = PyTuple_New(names.count()); for (int i = 0; i<names.count();i++) { #ifdef PY3K PyTuple_SET_ITEM(tuple, i, PyUnicode_FromString(names.at(i).constData())); #else PyTuple_SET_ITEM(tuple, i, PyString_FromString(names.at(i).constData())); #endif } info = info->nextInfo(); PyTuple_SET_ITEM(result, j, tuple); } return result; }
PyObject *PythonQtMemberFunction_typeName(PythonQtSlotInfo* theInfo) { PythonQtSlotInfo* info = theInfo; int count = 0; while (info) { info = info->nextInfo(); count++; } info = theInfo; PyObject* result = PyTuple_New(count); for (int j = 0;j<count;j++) { QByteArray name = info->metaMethod()->typeName(); PyTuple_SET_ITEM(result, j, PyString_FromString(name.constData())); info = info->nextInfo(); } return result; }
void PythonQtClassInfo::clearCachedMembers() { QHashIterator<QByteArray, PythonQtMemberInfo> i(_cachedMembers); while (i.hasNext()) { PythonQtMemberInfo member = i.next().value(); if (member._type== PythonQtMemberInfo::Slot || member._type== PythonQtMemberInfo::Signal) { PythonQtSlotInfo* info = member._slot; while (info) { PythonQtSlotInfo* next = info->nextInfo(); delete info; info = next; } } } }