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

        For Gerrit Dashboard: QTBUG-48175
        # Subject Branch Project Status CR V

        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