javascript - 如何在 C++ 中获取 QML 方法的源代码?

标签 javascript c++ qt qml qt5

我正在将对象序列化写入 QML,并希望能够获取 QML 对象中定义的函数的源代码。假设我在 QML (test.qml) 中有以下示例:

import QtQml 2.2

QtObject {
    function foo() {
        return 42;
    }
}

我从中创建了一个QObject:obj

有没有办法(可能是 hacky)在​​不解析 QML 文件 obj< 的情况下获取 obj 方法 foo 的源代码 是从什么地方创建的?

可以使用 QQmlComponent obj was created from 或任何其他 Qt 类,只要我不必自己解析它即可。或者,如何在不编写自己的解析器的情况下从 test.qml 文件中获取函数的源代码?我不想假设 test.qml 有什么特别之处(例如,它可能与上面的不同,并且它不必简单到足以使用正则表达式或其他不成熟的QML 解析器)。

假设这像 JavaScript 一样工作,我尝试了类似的东西:

QQmlExpression expr(engine.rootContext(), obj, "foo.toString()");
QVariant sourceCode = expr.evaluate();

但是,它不起作用。

编辑:根据http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.2函数对象原型(prototype)的 toString 方法是实现定义的。如果是 QML,我会得到结果:

QVariant(QString, "function() { [code] }")

由于似乎没有办法通过 JS 或 C++ 获取代码,因此我不再局限于公共(public) Qt API。

最佳答案

我认为不可能从已经创建的 QML 对象中获取函数的源代码。它似乎没有任何 C++ 接口(interface),JavaScript 也不会使用 toSource 方法返回它。

但是,可以使用 QML 解析器检索它。坏消息是 QML 解析器是 Qt 私有(private) API 的一部分,因此在使用不同的 Qt 库构建时它可能无法工作。

使用Qt 5.3.0私有(private)API解析QML的代码大致是:

.pro 文件:

QT += qml qml-private

cpp 文件:

using namespace QQmlJS::AST;

class LVisitor: public QQmlJS::AST::Visitor {
public:
    LVisitor(QString code): _code(code) {}

    virtual bool visit(FunctionBody *fb) {
        qDebug() << "Visiting FunctionBody" <<
                    printable(fb->firstSourceLocation(), fb->lastSourceLocation());
        return true;
    }

private:
    QStringRef printable(const SourceLocation &start, const SourceLocation &end) {
        return QStringRef(&_code, start.offset, end.offset + end.length - start.offset);
    }

private:
    QString _code;
};

void testQmlParser() {
    QFile file(":/test.qml");
    file.open(QFile::ReadOnly);
    QString code = file.readAll();
    file.close();

    QQmlJS::Engine engine;
    QQmlJS::Lexer lexer(&engine);

    lexer.setCode(code, 1, true);

    QQmlJS::Parser parser(&engine);

    if (!parser.parse() || !parser.diagnosticMessages().isEmpty()) {
        foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
            qDebug() << "Parse" << (m.isWarning() ? "warning" : "error") << m.message;
        }
    }

    UiProgram *ast = parser.ast();

    LVisitor visitor(code);
    ast->accept(&visitor);
}

要获得有关定义函数的对象的更精确信息或仅从 AST 获得更多信息,请实现 QQmlJS::AST::Visitor 的更多方法。

关于javascript - 如何在 C++ 中获取 QML 方法的源代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26813391/

相关文章:

javascript推送返回数字而不是对象

c++ - C++ 编程中的 vector 类

c++ - QNetworkAccessManager 的自定义 QSslSocket

c++ - 如何从静态方法中获取类名?

javascript - 关于使这段 Javascript 代码更好的建议?

javascript - vuetify v-data-table 不显示嵌套对象数据

javascript - 为什么即使在alert()之前调用preventDefault(),alert()也会执行?

c++ - 遍历结构变量

c++ - boost::multi_array 调整大小异常?

c++ - 从 QAbstractListModel 中删除项目后 QML 崩溃