// Convert a QVariant to a Python object based on the type of the object. PyObject *Chimera::toAnyPyObject(const QVariant &var) { if (!var.isValid()) { Py_INCREF(Py_None); return Py_None; } // Handle null variants for the v2 API. if (var.isNull() && sipIsAPIEnabled("QVariant", 2, 0)) return qpycore_qpynullvariant_FromQVariant(var); const char *type_name = var.typeName(); const sipTypeDef *td = sipFindType(type_name); Chimera *ct = new Chimera; ct->_type = td; ct->_name = type_name; ct->_metatype = var.userType(); if (td && sipTypeIsClass(td)) ct->set_flag(); PyObject *py = ct->toPyObject(var); delete ct; return py; }
// Parse a meta-property as a type. const Chimera *Chimera::parse(const QMetaProperty &mprop) { Chimera *ct = new Chimera; const char *type_name = mprop.typeName(); ct->_type = sipFindType(type_name); ct->_metatype = mprop.userType(); ct->_inexact = true; ct->_is_flag = mprop.isFlagType(); ct->_name = type_name; return ct; }
// This is a factory for the wrapped QDeclarativeListProperty<PyDelegate>. static PyObject *QPyDeclarativeListProperty_call(PyObject *, PyObject *args, PyObject *) { PyTypeObject *qobject_type = sipTypeAsPyTypeObject(sipType_QObject); PyObject *qobj_obj, *list_obj; if (!PyArg_ParseTuple(args, #if PY_VERSION_HEX >= 0x02050000 "O!O!:QPyDeclarativeListProperty", #else const_cast<char *>("O!O!:QPyDeclarativeListProperty"), #endif qobject_type, &qobj_obj, &PyList_Type, &list_obj, &PyType_Type)) return 0; // Get the C++ QObject. int iserr = 0; QObject *qobj = reinterpret_cast<QObject *>(sipConvertToType(qobj_obj, sipType_QObject, 0, SIP_NOT_NONE|SIP_NO_CONVERTORS, 0, &iserr)); if (iserr) return 0; // Get a list wrapper with the C++ QObject as its parent. ListWrapper *list_wrapper = ListWrapper::wrapper(list_obj, qobj); if (!list_wrapper) return 0; // Create the C++ QDeclarativeListProperty<QObject> with the list as the // data. QDeclarativeListProperty<QObject> *prop = new QDeclarativeListProperty<QObject>(qobj, &list_wrapper->qobject_list, list_append, list_count, list_at, list_clear); // Convert it to a Python object. static const sipTypeDef *mapped_type = 0; if (!mapped_type) mapped_type = sipFindType("QDeclarativeListProperty<QObject>"); Q_ASSERT(mapped_type); // Make sure ownership is with Python. PyObject *prop_obj = sipConvertFromNewType(prop, mapped_type, qobj_obj); if (!prop_obj) { delete prop; return 0; } return prop_obj; }
/** * Creates a PyObject that wraps the calling C++ instance. * Ownership is transferred to the caller, i.e. the caller * is responsible for calling Py_DECREF * @return A PyObject wrapping this instance */ PyObject *PythonScript::createSipInstanceFromMe() { const sipTypeDef *sipClass = sipFindType("PythonScript"); PyObject *sipWrapper = sipConvertFromType(this, sipClass, nullptr); assert(sipWrapper); return sipWrapper; }
// Parse the given C++ type name. bool Chimera::parse_cpp_type(const QByteArray &type) { _name = type; // Resolve any types. QByteArray resolved = resolve_types(type); if (resolved.isEmpty()) return false; // See if the type is known to Qt. _metatype = QMetaType::type(resolved.constData()); // If not then use the PyQt_PyObject wrapper. if (_metatype == QMetaType::Void) _metatype = PyQt_PyObject::metatype; // See if the type (without a pointer) is known to SIP. bool is_ptr = resolved.endsWith('*'); if (is_ptr) { resolved.chop(1); if (resolved.endsWith('*')) return false; } _type = sipFindType(resolved.constData()); if (!_type) { // This is the only fundamental pointer type recognised by Qt. if (_metatype == QMetaType::VoidStar) return true; // This is 'int', 'bool', etc. if (_metatype != PyQt_PyObject::metatype && !is_ptr) return true; if ((resolved == "char" || resolved == "const char") && is_ptr) { // This is a special value meaning a (hopefully) '\0' terminated // string. _metatype = -1; return true; } // This is an explicit 'PyQt_PyObject'. if (resolved == "PyQt_PyObject" && !is_ptr) return true; return false; } if (sipTypeIsNamespace(_type)) return false; if (sipTypeIsClass(_type)) { set_flag(); if (is_ptr) { PyTypeObject *type_obj = sipTypeAsPyTypeObject(_type); if (sipType_QWidget && PyType_IsSubtype(type_obj, sipTypeAsPyTypeObject(sipType_QWidget))) { _metatype = QMetaType::QWidgetStar; } else if (PyType_IsSubtype(type_obj, sipTypeAsPyTypeObject(sipType_QObject))) { _metatype = QMetaType::QObjectStar; } } } // We don't support pointers to enums. if (sipTypeIsEnum(_type) && is_ptr) _type = 0; if (sipTypeIsEnum(_type) || isFlag()) _metatype = QMetaType::Int; return true; }