예제 #1
0
// 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;
}
예제 #2
0
// 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;
}
예제 #3
0
// 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;
}
예제 #4
0
/**
 * 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;
}
예제 #5
0
// 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;
}