QQmlEngine and QJSEngine evaluate differently



  • Hello folks,

    I'm trying to evaluate some script code in a Qt GUI, where I can enter some code in a QTextEdit and then let it be evaluated by one of the plenty engines available in Qt.

    First I started with QScriptEngine, which worked fine, but I moved over to QJSEngine because the former is already deprecated. QJSEngine does evaluate scripts just as well.
    But it does lack many functionality, like loading plugins, etc.
    So I thought maybe just use QQmlEngine, it inherits from QJSEngine, and provides much more functionality, i.e. settings include paths, importing plugins, etc.
    So basically this is exactly what I need, BUT it cannot evaluate complex scripts.

    A simple example:

    oEngine->evaluate("var i = 0; i + 2;", "name");
    

    If oEngine is a QJSEngine the script will be evaluated, but a QQmlEngine throws following exception:

    Error in line 1: ReferenceError: i is not defined
    

    So my question is, is it possible to evaluate code with QQmlEngine just like with QJSEngine/QScriptEngine, because I would really like to add some plugins, or do I have to stick with QScriptEngine for now?

    Thanks


  • Moderators

    @phlipper I'm not sure how you are using it but following works for me:

    QQmlEngine engine;
    QJSValue result =  engine.evaluate("var i = 0; i + 2;", "name");
    qDebug() << result.toString(); //prints 2
    


  • First of all I am using Ubuntu 16.04 with Qt 5.5.1 and QtCreator 4.1.

    I isolated the code to a very simple example:

    #include <QCoreApplication>
    #include <QDebug>
    #include <QJSEngine>
    #include <QQmlEngine>
    
    int main(int argc, char *argv[])
    {
      QCoreApplication app(argc, argv);
    
      // switch between engines with comment
      QQmlEngine engine;
      //QJSEngine engine;
      QJSValue val = engine.evaluate("var i = 0; i + 2;", "name");
    
      if (val.isError())
      {
        qCritical() << "Error in line " << val.property("lineNumber").toString() << ": " << val.toString();
      }
      else
      {
        qInfo() << "Execution successful";
      }
    
      return 0;
    }
    

    If I use QQmlEngine the output is:

    QML debugging is enabled. Only use this in a safe environment.
    "QML Debugger: Invalid argument 'services:DebugMessages' detected. Ignoring the same."
    "QML Debugger: Invalid argument 'QmlDebugger' detected. Ignoring the same."
    "QML Debugger: Invalid argument 'V8Debugger' detected. Ignoring the same."
    "QML Debugger: Invalid argument 'QmlInspector' detected. Ignoring the same."
    QML Debugger: Waiting for connection on port 34039...
    Error in line "1" : "ReferenceError: i is not defined"
    Press <RETURN> to close this window...

    If I use QJSENgine the output is:

    QML debugging is enabled. Only use this in a safe environment.
    Execution successful
    Press <RETURN> to close this window...

    Do I need to use a newer Qt version to get the correct behaviour?

    Thank you.


  • Moderators

    @phlipper Your code works perfectly for me. The control goes into the else and prints 2 as expected.
    Apart from that you should use exec for the event loop to work properly.

    Do I need to use a newer Qt version to get the correct behaviour?

    Which version did you try ?



  • I am using Ubuntu 16.04 with Qt 5.5.1.


  • Moderators

    @phlipper Not sure if the version could be the problem but try with latest version. I tested using Qt 5.6



  • Downloaded latest Qt 5.7 and it now works.
    Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.