Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-48175

Documentation should mention that setting properties on the globalObject of QQmlEngine is not supported

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • None
    • 5.5.0
    • Documentation
    • None
    • 81dad6eb2b58314c10af2ba40abceab974c7e80f

    Description

      The following code seems like it shouldn't produce a warning:

      #include <QApplication>
      #include <QQmlApplicationEngine>
      #include <QtQml>
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
          QQmlApplicationEngine engine;
          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
          QJSEngine *jsEngine = &engine;
      
          QObject *object = new QObject;
      
          QJSValue gameObject = jsEngine->newQObject(object);
          jsEngine->globalObject().setProperty("game", gameObject);
      
          QJSValue evaluationResult = jsEngine->evaluate("game");
          if (evaluationResult.isError()) {
              qWarning().nospace() << evaluationResult.property("message").toString() << ":\n"
                  << "    File name: " << evaluationResult.property("fileName").toString() << "\n"
                  << "    Line number: " << evaluationResult.property("lineNumber").toInt() << "\n"
                  << "    Stack: " << evaluationResult.property("stack").toString();
          }
      
          if (!jsEngine->globalObject().deleteProperty("game")) {
              return 1;
          }
      
          return 0;
      }
      

      The output is:

      "game is not defined":
          File name: ""
          Line number: 1
          Stack: "%entry@:1"
      

      The documentation for QJSEngine (since QQmlEngine is derived from it) gives the impression that this should be possible:

      Returns this engine's Global Object.

      By default, the Global Object contains the built-in objects that are part of ECMA-262, such as Math, Date and String. Additionally, you can set properties of the Global Object to make your own extensions available to all script code. Non-local variables in script code will be created as properties of the Global Object, as well as local variables in global code.

      The same code works with a plain old QJSEngine:

      #include <QApplication>
      #include <QQmlApplicationEngine>
      #include <QtQml>
      
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
      
          QJSEngine jsEngine;
      
          QObject *object = new QObject;
      
          QJSValue gameObject = jsEngine.newQObject(object);
          jsEngine.globalObject().setProperty("game", gameObject);
      
          QJSValue evaluationResult = jsEngine.evaluate("game");
          if (evaluationResult.isError()) {
              qWarning().nospace() << evaluationResult.property("message").toString() << ":\n"
                  << "    File name: " << evaluationResult.property("fileName").toString() << "\n"
                  << "    Line number: " << evaluationResult.property("lineNumber").toInt() << "\n"
                  << "    Stack: " << evaluationResult.property("stack").toString();
          }
      
          if (!jsEngine.globalObject().deleteProperty("game")) {
              return 1;
          }
      
          return 0;
      }
      

      If QQmlEngine can be used to evaluate JavaScript, this limitation (of not being able to write to the global object) should be documented.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            mitch_curtis Mitch Curtis
            mitch_curtis Mitch Curtis
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes