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. Referring to an item from a different file
Forum Updated to NodeBB v4.3 + New Features

Referring to an item from a different file

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 783 Views 2 Watching
  • 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.
  • M Offline
    M Offline
    mjakubowski
    wrote on last edited by
    #1

    I have a file main.qml like this:

    Window {
        visible: true
        width: 500; height: 500
    
        Rectangle {
            id: existingRect
            width: 50; height: 50
            color: "blue";
        }
    }
    

    It's loaded through QQmlApplicationEngine::load. Is there a way to load, at runtime, from C++, the following QML file called newrect.qml:

    Rectangle {
        id: newRect
        width: 10; height: 10
        color: "red";
        parent: existingRect
    }
    

    And have it correctly child to the existingRect defined in main.qml? If I just load it through QQmlApplicationEngine::load, I get a reference error: "existingRect is not defined". Same if I go with:

        QQmlComponent component(&engine);
        component.loadUrl(QUrl("qrc:/newrect.qml"));
        component.create(engine.rootContext());
    

    Any help would be appreciated.

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      Hi!

      Is there a way to load, at runtime, from C++

      Yes. It works like this:

      MyRect.qml

      import QtQuick 2.6
      
      Rectangle {
          width: 10; height: 10
          color: "red";
      }
      

      main.qml

      import QtQuick 2.6
      import QtQuick.Window 2.2
      
      Window {
          visible: true
          width: 600
          height: 400
      
          Rectangle {
              objectName: "existingRect" // sic!
              width: 50; height: 50
              color: "blue";
          }
      }
      

      main.cpp

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      #include <QtQml>
      #include <QQmlComponent>
      #include <QQuickItem>
      
      int main(int argc, char *argv[])
      {
          QGuiApplication app(argc, argv);
      
          QQmlApplicationEngine engine;
          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
          QQmlComponent component(&engine);
          component.loadUrl( QUrl("qrc:///MyRect.qml") );
      
          QQuickItem *newItem = qobject_cast<QQuickItem *>(component.create());
          QQuickItem *existingItem = engine.rootObjects().at(0)->findChild<QQuickItem*>("existingRect");
          newItem->setParentItem(existingItem);
      
          return app.exec();
      }
      

      Cheers!

      1 Reply Last reply
      1
      • M Offline
        M Offline
        mjakubowski
        wrote on last edited by
        #3

        Hi,

        Thanks, perfect! Well, almost, because I'll have to set the objectName property on all the relevant items, but that's fine. I think.

        But this got me thinking - does it mean I won't be able to interact with the existing objects from the new one? Imagine MyRect has a MouseArea and I wanted to change the color of existingRect when MyRect is clicked.

        MyRect.qml

        import QtQuick 2.0
        
        Rectangle {
            id: newRect
            width: 10; height: 10
            color: "red";
        
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    // this will work
                    parent.parent.color = "#ff0"
        
                    // but this won't, even though existingRect is lazily evaluated
                    existingRect.color = "#ff0"
                }
            }
        }
        

        I can reference and thus modify a parent in a straight line, but not a sibling or an item in a completely different hierarchy branch. I guess I could expose a method to look for an item by objectName to the QML engine, or is there a better way?

        1 Reply Last reply
        0
        • ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          You are right, it's kind of a problem. I'd use something like this here:

          import QtQuick 2.6
          
          Rectangle {
              width: 50; height: 50
              color: "red";
          
              property var someRect: null
          
              MouseArea {
                  anchors.fill: parent
                  onClicked: someRect.color = "plum"
              }
          }
          
          
          import QtQuick 2.6
          import QtQuick.Window 2.2
          
          Window {
              visible: true
              width: 600
              height: 400
          
              Rectangle {
                  id: limeRect
                  x: 200
                  width: 200
                  height: 200
                  color: "lime"
              }
          
              Rectangle {
                  objectName: "existingRect" // sic!
                  id: existingRect
                  width: 200; height: 200
                  color: "blue";
          
                  onChildrenChanged: children[0].someRect = limeRect
              }
          }
          
          1 Reply Last reply
          0

          • Login

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