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



  • 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.


  • Moderators

    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.



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


  • Moderators

    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.



  • 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


  • Moderators

    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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.