Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Reference item id in a dynamic loaded file
QtWS25 Last Chance

Reference item id in a dynamic loaded file

Scheduled Pinned Locked Moved QML and Qt Quick
qmlc++embeddedeglfsqml dynamic5.4
6 Posts 2 Posters 6.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    PhTe
    wrote on 26 May 2015, 14:04 last edited by PhTe
    #1

    I have a main window, which is defined in main.qml (Not my real code, just a simple example)

    ApplicationWindow {
        width: 800
        height: 480
        visible: true
        id: appWindow
    
        Item {
            clip: true
            id: appContainer
            width: 100
            height: 100
            anchors.centerIn: parent
        }
    }
    

    The item appContainer has a defined size and works as a container for another item which is loaded dynamically via C++

    ...
    QQmlComponent component(getEngine(), QUrl("mychild.qml", QQmlComponent::PreferSynchronous);
    if(component.isLoading() || component.isError()) {
        qDebug() << component.errorString();
        return false;
    }
    QObject *object = component.create(getEngine()->rootContext());
    this->view = qobject_cast<QQuickItem*>(object);
    this->view->setParent(this->parent);
    this->view->setParentItem(this->parent);
    ...
    

    from mychild.qml. The qml file contains a rectangle which should fill the entire Screen

    Rectangle {
        anchors.fill: appContainer
        color:"black"
    }
    

    But the rectangle cant reference to the root container and throws the error "ReferenceError: appContainer is not defined"
    How can i access item ids from other files if some of them are loaded dynamically?

    The reason i ask is because i need to create a message box which should be closed if the user click somewhere outside the box.

    Since i work with an embedded system with EGLFS (No window manager) i can not use the Window or Dialog items which would create a window for me. So i have to create something own with Rectangle and this basic stuff.
    My idea was to put a screen filling rectangle and mousearea under the message box to dark the items in the background for a better optic and to catch the mouseevents outside the box. But therefor i need to get the screen dimensions from the root item in my main.qml file.

    P 1 Reply Last reply 26 May 2015, 16:28
    0
    • P PhTe
      26 May 2015, 14:04

      I have a main window, which is defined in main.qml (Not my real code, just a simple example)

      ApplicationWindow {
          width: 800
          height: 480
          visible: true
          id: appWindow
      
          Item {
              clip: true
              id: appContainer
              width: 100
              height: 100
              anchors.centerIn: parent
          }
      }
      

      The item appContainer has a defined size and works as a container for another item which is loaded dynamically via C++

      ...
      QQmlComponent component(getEngine(), QUrl("mychild.qml", QQmlComponent::PreferSynchronous);
      if(component.isLoading() || component.isError()) {
          qDebug() << component.errorString();
          return false;
      }
      QObject *object = component.create(getEngine()->rootContext());
      this->view = qobject_cast<QQuickItem*>(object);
      this->view->setParent(this->parent);
      this->view->setParentItem(this->parent);
      ...
      

      from mychild.qml. The qml file contains a rectangle which should fill the entire Screen

      Rectangle {
          anchors.fill: appContainer
          color:"black"
      }
      

      But the rectangle cant reference to the root container and throws the error "ReferenceError: appContainer is not defined"
      How can i access item ids from other files if some of them are loaded dynamically?

      The reason i ask is because i need to create a message box which should be closed if the user click somewhere outside the box.

      Since i work with an embedded system with EGLFS (No window manager) i can not use the Window or Dialog items which would create a window for me. So i have to create something own with Rectangle and this basic stuff.
      My idea was to put a screen filling rectangle and mousearea under the message box to dark the items in the background for a better optic and to catch the mouseevents outside the box. But therefor i need to get the screen dimensions from the root item in my main.qml file.

      P Offline
      P Offline
      p3c0
      Moderators
      wrote on 26 May 2015, 16:28 last edited by
      #2

      Hi @PhTe,
      You will need to find that exact Item. It can be done using findChild. An example here. Then set this item as parent item using setParentItem for the newly created component.

      157

      1 Reply Last reply
      0
      • P Offline
        P Offline
        PhTe
        wrote on 27 May 2015, 06:04 last edited by
        #3

        Hi @p3c0,
        i have already done this. (Look at the last two lines in my C++ example above)
        The items from mychild.qml are shown correctly, as long as they dont refer to an item id from the main.qml.

        P 1 Reply Last reply 27 May 2015, 06:28
        0
        • P PhTe
          27 May 2015, 06:04

          Hi @p3c0,
          i have already done this. (Look at the last two lines in my C++ example above)
          The items from mychild.qml are shown correctly, as long as they dont refer to an item id from the main.qml.

          P Offline
          P Offline
          p3c0
          Moderators
          wrote on 27 May 2015, 06:28 last edited by
          #4

          @PhTe I think you are setting a wrong parent item. I would suggest you to set correct parent from C++ by finding it (i.e find appContainer) as said earlier. And then in mychild.qml anchors.fill: parent should work.

          157

          1 Reply Last reply
          0
          • P Offline
            P Offline
            PhTe
            wrote on 27 May 2015, 07:25 last edited by
            #5

            @p3c0 Oh, i just saw, i made a misstake in my example above, sorry.
            The rectangle in mychild.qml should fill the appWindow, not the appContainer item.

            Here is a complete, compilable example of what i mean:

            main.qml

            import QtQuick 2.4
            import QtQuick.Controls 1.3
            import QtQuick.Window 2.2
            import QtQuick.Dialogs 1.2
            
            ApplicationWindow {
                width: 800
                height: 480
                visible: true
                id: appWindow
            
                Item {
                    clip: true
                    id: appContainer
                    objectName: "appContainer"
                    width: 100
                    height: 100
                    anchors.centerIn: parent
                }
            }
            

            mychild.qml

            import QtQuick 2.0
            
            Item {
                anchors.fill: parent
            
                // Should fill the entire screen ( NOT WORKING - 'appWindow is not defined' )
                Rectangle {
                    anchors.fill: appWindow
                    color: "black"
                }
            
                // Should fill a 100 x 100 px area ( WORKING )
                Rectangle {
                    anchors.fill: parent
                    color: "red"
                }
            }
            

            main.cpp

            #include <QApplication>
            #include <QQmlApplicationEngine>
            #include <QQuickItem>
            #include <QQuickWindow>
            
            int main(int argc, char *argv[]) {
                QApplication app(argc, argv);
                QQmlApplicationEngine engine;
            
                // Load main.qml
                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
            
                // Get top level item
                QList<QObject*> temp = engine.rootObjects();
                QObject *topLevel = temp.value(0);
                QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
            
                // Find parent for dynamically loaded content
                QQuickItem *appContainer = window->findChild<QQuickItem*>("appContainer");
            
                // Load mychild.qml
                QQmlComponent component(&engine, QUrl("qrc:/mychild.qml"), QQmlComponent::PreferSynchronous);
                if(component.isLoading() || component.isError()) 
                    qDebug() << component.errorString();
                QObject *object = component.create(engine.rootContext());
                QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
                QQuickItem *view = qobject_cast<QQuickItem*>(object);
            
                // Set parent
                view->setParent(appContainer);
                view->setParentItem(appContainer);
                view->setVisible(true);
            
                window->show();
                return app.exec();
            }
            

            The red rectangle is drawn in the center of the screen but the black rectangle, which should fill the entire screen, is not drawn.

            I have tried to put the code from mychild.qml into main.qml, but then (with some changes) i get an error that an item
            "Cannot anchor to an item that isn't a parent or sibling."
            So i think its not possible in general, to create an item that anchors to some other item then its own parent if the parent isnt self anchored to something.

            P 1 Reply Last reply 27 May 2015, 07:53
            0
            • P PhTe
              27 May 2015, 07:25

              @p3c0 Oh, i just saw, i made a misstake in my example above, sorry.
              The rectangle in mychild.qml should fill the appWindow, not the appContainer item.

              Here is a complete, compilable example of what i mean:

              main.qml

              import QtQuick 2.4
              import QtQuick.Controls 1.3
              import QtQuick.Window 2.2
              import QtQuick.Dialogs 1.2
              
              ApplicationWindow {
                  width: 800
                  height: 480
                  visible: true
                  id: appWindow
              
                  Item {
                      clip: true
                      id: appContainer
                      objectName: "appContainer"
                      width: 100
                      height: 100
                      anchors.centerIn: parent
                  }
              }
              

              mychild.qml

              import QtQuick 2.0
              
              Item {
                  anchors.fill: parent
              
                  // Should fill the entire screen ( NOT WORKING - 'appWindow is not defined' )
                  Rectangle {
                      anchors.fill: appWindow
                      color: "black"
                  }
              
                  // Should fill a 100 x 100 px area ( WORKING )
                  Rectangle {
                      anchors.fill: parent
                      color: "red"
                  }
              }
              

              main.cpp

              #include <QApplication>
              #include <QQmlApplicationEngine>
              #include <QQuickItem>
              #include <QQuickWindow>
              
              int main(int argc, char *argv[]) {
                  QApplication app(argc, argv);
                  QQmlApplicationEngine engine;
              
                  // Load main.qml
                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
              
                  // Get top level item
                  QList<QObject*> temp = engine.rootObjects();
                  QObject *topLevel = temp.value(0);
                  QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
              
                  // Find parent for dynamically loaded content
                  QQuickItem *appContainer = window->findChild<QQuickItem*>("appContainer");
              
                  // Load mychild.qml
                  QQmlComponent component(&engine, QUrl("qrc:/mychild.qml"), QQmlComponent::PreferSynchronous);
                  if(component.isLoading() || component.isError()) 
                      qDebug() << component.errorString();
                  QObject *object = component.create(engine.rootContext());
                  QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
                  QQuickItem *view = qobject_cast<QQuickItem*>(object);
              
                  // Set parent
                  view->setParent(appContainer);
                  view->setParentItem(appContainer);
                  view->setVisible(true);
              
                  window->show();
                  return app.exec();
              }
              

              The red rectangle is drawn in the center of the screen but the black rectangle, which should fill the entire screen, is not drawn.

              I have tried to put the code from mychild.qml into main.qml, but then (with some changes) i get an error that an item
              "Cannot anchor to an item that isn't a parent or sibling."
              So i think its not possible in general, to create an item that anchors to some other item then its own parent if the parent isnt self anchored to something.

              P Offline
              P Offline
              p3c0
              Moderators
              wrote on 27 May 2015, 07:53 last edited by
              #6

              @PhTe Right it wont work. It cannot anchor to an item which is not its parent or sibling.

              157

              1 Reply Last reply
              0

              6/6

              27 May 2015, 07:53

              • Login

              • Login or register to search.
              6 out of 6
              • First post
                6/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved