[Interest] QML Loader sourceComponent Dynamic selection

md at rpzdesign.com md at rpzdesign.com
Mon Nov 17 14:33:11 CET 2014


Nuno:

Thanks for this info.

I had not gotten a running example yet to determine performance,
but I figured if I could reduce that substantially if I embedded the
dynamic components inside the QML file that contained the Loader.

In your sample, you gave:
   component = Qt.createComponent("DeviceParameterButton.qml");

(In an offline email, maybe you could send along a sample of the
DeviceParameterButton.qml file)

I was looking to use Loader::sourceComponent : Loader { INLINE COMPONENTS }.

Not Loader::source : Loader { "QML FILE" }.

Anybody with ideas?

Cheers,

Marco

On 11/17/2014 4:32 AM, Nuno Santos wrote:
> 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
>> <mailto: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 <mailto:Interest at qt-project.org>
>> http://lists.qt-project.org/mailman/listinfo/interest
> 
> 
> 
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
> 



More information about the Interest mailing list