2014-11-08 58 views
0

我正在写一个对象到QML的序列化,并希望能够获得在QML对象中定义的函数的源代码。假设我有在QML(test.qml)下面的例子:如何在C++中获取QML方法的源代码?

​​

我创建一个QObject:从obj

有什么办法(可哈克),以获得obj的方法foo的源代码,而无需解析QML文件obj从被创造?

可以使用QQmlComponentobj是从任何其他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函数对象原型的toString方法是实现定义的。在QML的情况下,我得到的结果:

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

因为似乎没有成为一个方式来获得由JS或C++代码,我不会限制自己对公共的Qt API了。

+0

你想要一个源代码?或者只是想运行功能? – nitish005 2014-11-08 05:12:45

+0

我需要的源代码,而不是运行该功能。 – Xilexio 2014-11-08 15:44:27

回答

1

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

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

使用Qt 5.3解析QML的代码。0私人API或多或少:

.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

0

我也没有找到任何方式来这样做。但我找到了解决办法。

reffer this firts

现在,正如你knwo我们可以在C访问QML对象++。将会执行以下操作来在QML中运行该函数。

Item { 
    width: 100; height: 100 

    Rectangle { 
     property bool call:true 

     objectName: "rect" 
     onCallChanged() 
     { 
      myFunction(); 
     } 
     function myFunction() 
     { 
      //your code 
     } 
    } 
} 

,并在C++中,你必须做以下几点:

QObject *rect = object->findChild<QObject*>("rect"); 
if (rect) 
    rect->setProperty("call", !(rect->property("call").toBool())); 

这里我们使用的属性更改事件“称之为”调用myFunction的()

+0

我需要源代码,而不是运行该功能的方法。另外,为了运行这个函数,我提供的代码片段也可以正常工作:'''''QQmlExpression expr(engine.rootContext(),obj,“foo()”);'。 – Xilexio 2014-11-08 15:47:33