// The type init slot. static int pyqtWrapperType_init(pyqtWrapperType *self, PyObject *args, PyObject *kwds) { // Let the super-type complete the basic initialisation. if (sipWrapperType_Type->tp_init((PyObject *)self, args, kwds) < 0) return -1; const pyqt4ClassPluginDef *pyqt_td = reinterpret_cast<const pyqt4ClassPluginDef *>(sipTypePluginData(((sipWrapperType *)self)->wt_td)); if (pyqt_td && !sipIsExactWrappedType((sipWrapperType *)self)) { // Create a dynamic meta-object as its base wrapped type has a static // Qt meta-object. if (pyqt_td->static_metaobject && create_dynamic_metaobject(self) < 0) return -1; } return 0; }
// The type init slot. static int pyqtWrapperType_init(pyqtWrapperType *self, PyObject *args, PyObject *kwds) { // Let the super-type complete the basic initialisation. if (sipWrapperType_Type->tp_init((PyObject *)self, args, kwds) < 0) return -1; pyqt4ClassTypeDef *pyqt_td = (pyqt4ClassTypeDef *)((sipWrapperType *)self)->type; if (pyqt_td && !sipIsExactWrappedType((sipWrapperType *)self)) { // Create a dynamic meta-object as its base wrapped type has a static // Qt meta-object. if (pyqt_td->qt4_static_metaobject && create_dynamic_metaobject(self) < 0) return -1; } return 0; }
// Parse the given Python type object. bool Chimera::parse_py_type(PyTypeObject *type_obj) { const sipTypeDef *td = sipTypeFromPyTypeObject(type_obj); if (td) { if (sipTypeIsNamespace(td)) return false; _type = td; _name = sipTypeName(td); if (sipTypeIsClass(td)) set_flag(); if (sipTypeIsEnum(td) || isFlag()) { _metatype = QMetaType::Int; } else { bool is_a_QObject = PyType_IsSubtype(type_obj, sipTypeAsPyTypeObject(sipType_QObject)); // If there is no assignment helper then assume it is a // pointer-type. if (!get_assign_helper()) _name.append('*'); _metatype = QMetaType::type(_name.constData()); // This will deal with cases where the registered type is a // super-class and specifically allows for multiple inheritance. // The problem we are solving is that we want a QGraphicsWidget to // be handled as a QGraphicsItem (which Qt registers) rather than a // QObject, specifically in the value passed as a QVariant to // QGraphicsItem::itemChange(). This solution means that it will // always be passed as a QGraphicsItem, even if there are // circumstances where it should be passed as a QObject. If we // come across such a circumstance then we may need to remove this // and implement a more specific solution in %MethodCode for the // various itemChange() implementations. if (_metatype == 0 && is_a_QObject) { PyObject *mro = type_obj->tp_mro; Q_ASSERT(PyTuple_Check(mro)); Q_ASSERT(PyTuple_GET_SIZE(mro) >= 3); for (SIP_SSIZE_T i = 1; i < PyTuple_GET_SIZE(mro) - 1; ++i) { PyTypeObject *sc = (PyTypeObject *)PyTuple_GET_ITEM(mro, i); if (sc == sipSimpleWrapper_Type || sc == sipWrapper_Type) continue; QByteArray sc_name(sc->tp_name); // QObjects are always pointers. sc_name.append('*'); _metatype = QMetaType::type(sc_name.constData()); if (_metatype >= QMetaType::User) { _type = sipTypeFromPyTypeObject(sc); _name = sc_name; _py_type = (PyObject *)sc; Py_INCREF(_py_type); return true; } } } // If it is a user type then it must be a type that SIP knows // about but was registered by Qt. if (_metatype < QMetaType::User) { if (sipType_QWidget && PyType_IsSubtype(type_obj, sipTypeAsPyTypeObject(sipType_QWidget))) { _metatype = QMetaType::QWidgetStar; } else if (is_a_QObject) { _metatype = QMetaType::QObjectStar; } else if (!sipIsExactWrappedType((sipWrapperType *)type_obj)) { // It must be a (non-QObject, non-QWidget) Python // sub-class so make sure it gets wrapped in a // PyQt_PyObject. _type = 0; _metatype = PyQt_PyObject::metatype; _name.clear(); } } } } #if PY_MAJOR_VERSION >= 3 else if (type_obj == &PyUnicode_Type) { _type = sipType_QString; _metatype = QMetaType::QString; } #else else if (type_obj == &PyString_Type || type_obj == &PyUnicode_Type) { // In this case we accept that the reverse conversion will result in an // object of a different type (i.e. a QString rather than a Python // string). _type = sipType_QString; _metatype = QMetaType::QString; } #endif else if (type_obj == &PyBool_Type) { _metatype = QMetaType::Bool; } #if PY_MAJOR_VERSION < 3 else if (type_obj == &PyInt_Type) { // We choose to map to a C++ int, even though a Python int is // potentially much larger, as it represents the most common usage in // Qt. However we will allow a larger type to be used if the context // is right. _metatype = QMetaType::Int; _inexact = true; } #endif else if (type_obj == &PyLong_Type) { // We choose to map to a C++ int for the same reasons as above and to // be consistent with Python3 where everything is a long object. If // this isn't appropriate the user can always use a string to specify // the exact C++ type they want. _metatype = QMetaType::Int; _inexact = true; } else if (type_obj == &PyFloat_Type) { _metatype = QMetaType::Double; } // Fallback to using a PyQt_PyObject. if (_metatype == QMetaType::Void) _metatype = PyQt_PyObject::metatype; // If there is no name so far then use the meta-type name. if (_name.isEmpty()) _name = QMetaType::typeName(_metatype); _py_type = (PyObject *)type_obj; Py_INCREF(_py_type); return true; }