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. Talking to Items inside a Component loaded with Loader / QtQuick 2.0
QtWS25 Last Chance

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

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 2 Posters 3.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.
  • M Offline
    M Offline
    matti-
    wrote on last edited by
    #1

    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
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      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
      0
      • M Offline
        M Offline
        matti-
        wrote on last edited by
        #3

        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
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          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
          0
          • M Offline
            M Offline
            matti-
            wrote on last edited by
            #5

            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
            0
            • sierdzioS Offline
              sierdzioS Offline
              sierdzio
              Moderators
              wrote on last edited by
              #6

              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
              0

              • Login

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