コード例 #1
0
ファイル: qpython.cpp プロジェクト: M4rtinK/pyotherside
QVariant
QPython::getattr(QVariant obj, QString attr) {
    if (!SINCE_API_VERSION(1, 4)) {
        emitError(QString("Import PyOtherSide 1.4 or newer to use getattr()"));
        return QVariant();
    }

    ENSURE_GIL_STATE;

    PyObjectRef pyobj(convertQVariantToPyObject(obj), true);

    if (!pyobj) {
        emitError(QString("Failed to convert %1 to python object: '%1' (%2)").arg(obj.toString()).arg(priv->formatExc()));
        return QVariant();
    }

    QByteArray byteArray = attr.toUtf8();
    const char *attrStr = byteArray.data();

    PyObjectRef o(PyObject_GetAttrString(pyobj.borrow(), attrStr), true);

    if (!o) {
        emitError(QString("Attribute not found: '%1' (%2)").arg(attr).arg(priv->formatExc()));
        return QVariant();
    }

    return convertPyObjectToQVariant(o.borrow());
}
コード例 #2
0
ファイル: tests.cpp プロジェクト: fkrull/pyotherside
void
TestPyOtherSide::testConvertToPythonAndBack()
{
    QVariantList l;
    l << "Hello" << 123 << 45.667 << true;
    QVariantList l2;
    l2 << "A" << QVariant() << "B" << 4711;
    l << QVariant(l2);
    QVariant v(l);

    PyObject *o = convertQVariantToPyObject(v);
    QVariant v2 = convertPyObjectToQVariant(o);
    QVERIFY(v == v2);
}
コード例 #3
0
ファイル: qpython_priv.cpp プロジェクト: fkrull/pyotherside
PyObject *
pyotherside_qrc_list_dir(PyObject *self, PyObject *dirname)
{
    QString qdirname = qstring_from_pyobject_arg(dirname);

    if (qdirname.isNull()) {
        return NULL;
    }

    QDir dir(":" + qdirname);
    if (!dir.exists()) {
        PyErr_SetString(PyExc_ValueError, "Directory not found");
        return NULL;
    }

    return convertQVariantToPyObject(dir.entryList());
}
コード例 #4
0
ファイル: tests.cpp プロジェクト: thp/pyotherside
void
TestPyOtherSide::testPyObjectRefRoundTrip()
{
    // Simulate a complete round-trip of a PyObject reference, from PyOtherSide
    // to QML and back.

    // Create a Python object, i.e. in a Python function.
    bool destructor_called = false;
    PyObject *o = PyCapsule_New(&destructor_called, "test", destruct);
    QVERIFY(o->ob_refcnt == 1);

    // Convert the object to a QVariant and increment its refcount.
    QVariant v = convertPyObjectToQVariant(o);

    // Decrement refcount and pass QVariant to QML.
    QVERIFY(o->ob_refcnt == 2);
    Py_DECREF(o);
    QVERIFY(o->ob_refcnt == 1);

    // Pass QVariant back to PyOtherSide, which converts it to a PyObject,
    // incrementing its refcount.
    PyObject *o2 = convertQVariantToPyObject(v);
    QVERIFY(o->ob_refcnt == 2);

    // The QVariant is deleted, i.e. by a JS variable falling out of scope.
    // This deletes the PyObjectRef and thus decrements the object's refcount.
    v = QVariant();

    // At this point, we only have one reference (the one from o2)
    QVERIFY(o->ob_refcnt == 1);

    // There's still a reference, so the destructor must not have been called
    QVERIFY(!destructor_called);

    // Now, at this point, the last remaining reference is removed, which
    // will cause the destructor to be called
    Py_DECREF(o2);

    // There are no references left, so the capsule's destructor is called.
    QVERIFY(destructor_called);
}
コード例 #5
0
ファイル: qpython.cpp プロジェクト: M4rtinK/pyotherside
QVariant
QPython::call_sync(QVariant func, QVariant args)
{
    ENSURE_GIL_STATE;

    PyObjectRef callable;
    QString name;

    if (SINCE_API_VERSION(1, 4)) {
        if (static_cast<QMetaType::Type>(func.type()) == QMetaType::QString) {
            // Using version >= 1.4, but func is a string
            callable = PyObjectRef(priv->eval(func.toString()), true);
            name = func.toString();
        } else {
            // Try to interpret "func" as a Python object
            callable = PyObjectRef(convertQVariantToPyObject(func), true);
            PyObjectRef repr = PyObjectRef(PyObject_Repr(callable.borrow()), true);
            name = convertPyObjectToQVariant(repr.borrow()).toString();
        }
    } else {
        // Versions before 1.4 only support func as a string
        callable = PyObjectRef(priv->eval(func.toString()), true);
        name = func.toString();
    }

    if (!callable) {
        emitError(QString("Function not found: '%1' (%2)").arg(name).arg(priv->formatExc()));
        return QVariant();
    }

    QVariant v;
    QString errorMessage = priv->call(callable.borrow(), name, args, &v);
    if (!errorMessage.isNull()) {
        emitError(errorMessage);
    }
    return v;
}