Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Qt Academy Launch in California!

    Talking to Items inside a Component loaded with Loader / QtQuick 2.0

    QML and Qt Quick
    2
    6
    2761
    Loading More Posts
    • 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
      matti- last edited by

      Hi, I'm looking for a proper strategy for talking to (setting properties, calling methods, etc) Items inside a Component I'm loading dynamically. I have this setup that I've defined a Container(.qml) -- which essentially is a "dialog" -- type which does some magic like provides a BorderImage, a header, etc and uses a component id / Loader to load the "dialog" content dynamically so that the Container can be reused; the Container never really knows what its children are. The setup is something like this:

      Container.qml:
      @
      Item {
      id: root
      clip: true

      property alias contentComponent: contentLoader.sourceComponent
      property alias headerText: headerText.text
      
      // Frame / border image
      BorderImage {
          id: frameImage
          anchors.fill: parent
      
          border { left: 28; top: 28; right: 28; bottom: 28 }
          horizontalTileMode: BorderImage.Stretch
          verticalTileMode: BorderImage.Stretch
          source: "qrc:/images/container_background.png"
      }
      
      // Container area; adds automatic margins to fit things inside border
      Item {
          id: containerArea
          anchors.fill: parent
          anchors.margins: 11
      
          // Header rectangle
          Rectangle {
              id: header
                 // .. Omitted for clarity ..
      
              // Header text
              Text {
                 // .. Omitted for clarity ..
              }
          }
      
          // Container contents
          Item {
              anchors.top: header.bottom
              anchors.left: parent.left
              anchors.right: parent.right
              anchors.bottom: parent.bottom
              anchors.margins: 10 * xScale
              clip: true
      
              // Dynamically loaded content through Loader
              Loader {
                  id: contentLoader
                  anchors.fill: parent
              }
          }
      }
      

      }
      @

      main.qml:
      @
      // This is how I'm "instantiating" the "Container":
      Container {
      id: myContainer
      // .. Omitted for clarity ..

          // Here I define the header (string) and content (Component) for my Container
          headerText: "My header"
          contentComponent: myContent
      
          Component {
              id: myContent
              Item {
                  Text {
                      id: myText
                     // .. Omitted for clarity ..
                  }
             }
       }
      

      @

      Now, say something occurs and I would like to alter properties of the Text label "myText" which is inside the Component I'm using as the Container's content. I cannot access it normally (qrc:/main.qml:62: ReferenceError: myText is not defined) obviously since it's loaded by the Loader inside the separate Container.qml. So I am looking for a nice pattern for talking to the items inside a such Component. Or, should that be not feasible, another approach for defining such dynamic content for reusable Item components would be welcome too.

      It's QtQuick 2.0 I'm working with and I'm somewhat a beginner with it still.

      Cheers,

      • Matti

      EDIT: For now I'm going with the "default property alias children" -trick mentioned here: http://stackoverflow.com/questions/5021350/how-do-you-assign-a-qml-item-to-a-component-property-in-qml-and-then-use-that-ob but still interested about hearing how to deal with the Loader / Component combo.

      Author of <a href="http://mmark.777-team.org/">MMark13</a>

      1 Reply Last reply Reply Quote 0
      • sierdzio
        sierdzio Moderators last edited by

        Searching by objectName should work (from c++ and JS), just add:
        @
        id: myText
        objectName: "myText"
        @

        Not a perfect and clean solution, but that's the first idea that struck me.

        (Z(:^

        1 Reply Last reply Reply Quote 0
        • M
          matti- last edited by

          I see .. but how does that work when several Loaders load that Component that contains the myText item?

          Author of <a href="http://mmark.777-team.org/">MMark13</a>

          1 Reply Last reply Reply Quote 0
          • sierdzio
            sierdzio Moderators last edited by

            Ah there, you see, in that case it probably breaks ;)
            @
            Component {
            id: myContent
            Item {
            Text {
            @

            Why is this structure so deep? Wouldn't the sole Text element just work? Or an id chain like:
            @
            myContent.myItem.myText
            @

            I've used the component trick like this before, but in a different way (the container referenced items it does not have, which are added in the implementation), and it worked. No idea strikes me as to how exactly to solve your case here.

            (Z(:^

            1 Reply Last reply Reply Quote 0
            • M
              matti- last edited by

              Hm. I could have passed it just the Text thingys id but I assumed that Loader.sourceComponent had to be an id of an Component (and not one of an Item-descendant).

              Main problem here so far is that I dont probably understand the usage/usefulness of Loader correctly ;)

              -M

              Author of <a href="http://mmark.777-team.org/">MMark13</a>

              1 Reply Last reply Reply Quote 0
              • sierdzio
                sierdzio Moderators last edited by

                Ah wait, so this component is loaded into a Loader! That's probably an overkill (it would work without the loader just fine). In order to get to the belly of a Loader, you need to acces it through item property. Here's a snippet:
                @
                Loader {
                id: loader
                source: "whatever.qml"
                }

                // somewhere else in code (JS. C++ would work, too):
                loader.item.color = "#12ff87";
                @

                Hope I finally understand your code now :P

                (Z(:^

                1 Reply Last reply Reply Quote 0
                • First post
                  Last post