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

QQmlContext::nameForObject() with ApplicationWindow causes creation of many QQuickScreenInfo objects

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 6.3.1
    • None
    • macOS

    Description

      Using QQmlContext::nameForObject() with QML ApplicationWindow causes creation of many QQuickScreenInfo instances. Each call adds another instance, resulting in an exponential growth of the QML tree. Does not happen when using plain QML Window instead.

      Can test it with a C++ function like:

      class test: public QObject {
        Q_OBJECT
      
      public:
        Q_INVOKABLE void testIt(QObject *obj) {
          qDebug() << "test.testIt()" << obj;
      
          qDebug() << "Num children before:" << obj->children().size();
      
          for (auto current : obj->children()) {
      
            QQmlContext *objContext = qmlContext(current);
      
            if(!objContext && current && current->parent()) objContext = qmlContext(current->parent());
      
            if(objContext) {
              // causes a new QQuickScreenInfo instance to be added to the list of children
              auto id = objContext->nameForObject(current);
      
            //  qDebug() << "id for" << current << "=" << id;
            }
          }
          qDebug() << "Num children after:" << obj->children().size();
        }
      };
      
      #include "main.moc"
      
      int main(int argc, char *argv[])
      {
        QGuiApplication app(argc, argv);
      
        QQmlApplicationEngine engine;
        const QUrl url(u"qrc:/ScreenInfoBugTest/main.qml"_qs);
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
          if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
      
      
        test t;
        engine.rootContext()->setContextProperty("test", &t);
      
        engine.load(url);
      
        return app.exec();
      }
      

      QML:

      import QtQuick
      import QtQuick.Window
      import QtQuick.Controls
      
      ApplicationWindow {
        id: window
        width: 640
        height: 480
        visible: true
        title: qsTr("Hello World")
      
        MouseArea {
          anchors.fill: parent
          onClicked: test.testIt(window)
        }
      }
      

      Each time testIt() is called, it results in a new QQuickScreenInfo object in the list of children, for each time the nameForObject is called. The demo eventually crashes, due to too many objects, probably.

      Output like:

      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 2
      Num children after: 3
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 3
      Num children after: 5
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 5
      Num children after: 9
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 9
      Num children after: 17
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 17
      Num children after: 33
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 33
      Num children after: 65
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 65
      Num children after: 129
      test.testIt() ApplicationWindow_QMLTYPE_1(0x600001ce43c0)
      Num children before: 129
      Num children after: 257
      

      Attached is a full runnable demo CMake project.

      Tested with Qt 6.3.1 on MacOS and Windows MinGW.

      Attachments

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

        Activity

          People

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            Chrisu Christian Bartsch
            Votes:
            5 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:

              Gerrit Reviews

                There is 1 open Gerrit change