[Interest] QML Loader sourceComponent Dynamic selection (not source property)

Nuno Santos nunosantos at imaginando.pt
Mon Nov 17 10:32:27 CET 2014


Hi,

Not sure if this is what you want but recently I have implemented a dynamic delegate usage by using the Component class.

DeviceParameterView had three types: button, option, slider. I want to render a different delegate depending on the type of the parameter model. This was the solution I have implemented since instantiating the three different delegates inside the delegate was killing list performance.

This approach will asynchronously load the specified component. 

import QtQuick 2.2

Item {
    id: root
    clip: true

    property var parameter
    property Component component

    property DeviceParameterButton button
    property DeviceParameterOption option
    property DeviceParameterSlider slider

    Component.onDestruction: {
        if (button!=null)
            button.destroy()

        if (option!=null)
            option.destroy()

        if (slider!=null)
            slider.destroy()
    }

    onParameterChanged: {
        switch (parameter.type)
        {
            case 0:
                component = Qt.createComponent("DeviceParameterButton.qml");

                var incubator = component.incubateObject(root, {"height": 20, "parameter": parameter});

                if (incubator.status != Component.Ready)
                {
                    incubator.onStatusChanged = function(status)
                    {
                        if (status == Component.Ready)
                        {
                            button = incubator.object
                            root.width = button.width
                        }
                    }
                }
                break;

            ...
        }
    }
}

> On 17 Nov 2014, at 03:18, mark diener <rpzrpzrpz at gmail.com> wrote:
> 
> Even:
> 
> A couple months back you gave an intelligent answer from a interest list query about
> creating complex list views.
> 
> I was a little tied up with things and could not get around to actually create a working example of a complex list view.  Now is that time.
> 
> Maybe you could get me past some implementation uncertainties
> 
> Attached below is a copy of the original message.  
> 
> I am having trouble defining a loader that does not need a separate QML file for its definition, but a javascript function that is away of which row index of the model it is currently drawing and can pass that to a javacript function that will return a Component value directly instead of a reference to an QML file.
> 
> I have included a small snippet QML file below:
> 
> ListModel {
>  id: glistdata
>   {
>    type: 1
>    name : "Joe Perra"
>    cell: "555-1212"
>    eyes: "blue"
>    mood: "sad"
>     }
>   ListElement
>   {
>     type: 2
>     name : "Mary Tyler"
>     cell: "555-1213"
>     eyes: "brown"
>     mood: "happy"
>     }
>    ListElement
>    {
>     type: 3
>     name : "Peter Gabriel"
>     cell: "555-1214"
>     eyes: "blue"
>     mood: "bitter"
>    }
> } 
> 
> Component {
>   id: gflavorone
>   Item
>   {
>      Text
>      {
>         text: 'Name:' + name
>      }
>      Text
>      {
>         text: 'Mood:' + mood
>      }
>  }
> 
> Component {
>   id: gflavortwo
>   Item
>   {
>      Text
>      {
>         text: 'Name:' + name
>      }
>      Text
>      {
>         text: 'Eyes:' + eyes
>      }
>  }
> 
> Component {
>   id: gflavorthree
>   Item
>   {
>      Text
>      {
>         text: 'Name:' + name
>      }
>      Text
>      {
>         text: 'cell:' + cell
>      }
>  }
> 
> Loader {
>   id: gloader
>  
>   function getComp(gidx)
>   {
>     switch (gidx)
>     {
>      case 1: return gflavorone 
>      case 2: return gflavortwo 
>     }
>     //Default case
>     return gflavorthree 
>    }
>  }
>  sourceComponent: getComp(index)
> }
> 
> ListView {
>         id: glistview
>         anchors.margins: 0
>         anchors.fill: parent
>         delegate: gloader
>         model: glistdata
> 
> }
> 
> 
> Maybe you or anybody else has some ideas on how to specifically code the  Loader written to 
> a dynamic Component instead of referring to an external QML file to generate the Component value.
> 
> And on top of that, how does the loader getComp( ) function access the index of the row or maybe it must just only refer to the model fields
> 
> So yes, I would like the Loader to intelligently select the sourceComponent using a dynamic function attached to the loader.
> 
> This is an area that needs maybe a long experience QT veteran  to comment on this.
> 
> 
> Cheers,
> 
> md
> 
> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> > Subject: [Interest] Qt Quick 2.x Complex ListView
> >
> > Hello QTers:
> 
> > Does anybody have an idea on how to create each row of the listview with a delegate that allows for each row > to be rendered with separate logic instead of the standard delegate which renders each row with the same or > very similar logic.
> 
> > Any comments or tips would be useful and I am sure more people would like this option
> 
> Not sure if it covers what you need, but I believe the common way to
> solve this is through using a Loader element as the delegate and
> changing the source depending on your criteria for which row delegate to
> use on the fly.
> 
> ListView {
>         id: example
>         delegate: Loader {
>                 function getDelegate() { ... }
>                 source: getDelegate()
>         }
> }
> 
> Use the getDelegate() function to return the url for the delegate to use.
> 
> You can use a similar trick inside the delegate item itself instead (or
> in addition) if you create separate elements for the different type of
> columns that you need to render, then you can use a Row with Loaders for
> example.
> 
> 
> -Ev
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141117/8e87a2aa/attachment.html>


More information about the Interest mailing list