[Interest] Define map of static items in QML

Elvis Stansvik elvstone at gmail.com
Wed Mar 30 17:24:34 CEST 2016


2016-03-30 17:22 GMT+02:00 Elvis Stansvik <elvstone at gmail.com>:

> 2016-03-30 16:55 GMT+02:00 Jérôme Godbout <jerome at bodycad.com>:
>
>> You may want to have them declared as list of object with the key as a
>> property of each entry, and build the map based on the list content.
>>
>> ex:
>>
>> *// May have to change the list type here*
>> *property list<Screen> myScreens:*
>> *[*
>> *     WelcomeScreen { property string keyName: 'welcome' }*
>> *   , OtherScreen { property string keyName: 'other' }*
>> *]*
>>
>> *property var myScreenMap: listToMapByProperty(myScreens, 'keyName')*
>>
>> *// This can be put into pargma library .js*
>> *function listToMapByProperty(list, mapKey)*
>> *{*
>> *   var rv = {};*
>> *   for(var i = 0; i < list.length; ++i)*
>> *   {*
>> *      rv[list[i][mapKey]] = list[i];*
>> *   }*
>> *   return rv;*
>> *}*
>>
>> This should be reusable and allow for easy declaration of Items/Objects.
>> Just need the same property to be declared inside each one. You can also
>> iterate on the list.
>>
>> Here's the result of this code with QtObject, but the idea is the same:
>> *Item*
>> *{*
>> * property list<QtObject> myScreens:*
>> * [*
>> * QtObject { property string keyName: 'welcome' }*
>> *   , QtObject { property string keyName: 'other' }*
>> * ]*
>>
>> * property var myScreenMap: listToMapByProperty(myScreens, 'keyName')*
>>
>> * // This can be put into pargma library .js*
>> * function listToMapByProperty(list, mapKey)*
>> * {*
>> *   var rv = {};*
>> *   for(var i = 0; i < list.length; ++i)*
>> *   {*
>> *  rv[list[i][mapKey]] = list[i];*
>> *   }*
>> *   return rv;*
>> * }*
>> *}*
>> resulting into those properties into the item:
>> [image: Inline image 1]
>>
>>
> Thanks a lot, I like this approach very much!
>

Btw, do you think it's a bad idea to use the objectName property for this
purpose, instead of a custom keyName property like you did?

Elvis


>
> Elvis
>
>
>> On Wed, Mar 30, 2016 at 5:19 AM, Elvis Stansvik <elvstone at gmail.com>
>> wrote:
>>
>>> 2016-03-30 11:08 GMT+02:00 Gianluca <gmaxera at gmail.com>:
>>> >
>>> > Il giorno 30/mar/2016, alle ore 09:46, Elvis Stansvik <
>>> elvstone at gmail.com> ha scritto:
>>> >
>>> >> Hi Gianluca,
>>> >>
>>> >> 2016-03-30 10:16 GMT+02:00 Gianluca <gmaxera at gmail.com>:
>>> >>>
>>> >>> Il giorno 30/mar/2016, alle ore 07:43, Elvis Stansvik <
>>> elvstone at gmail.com>
>>> >>> ha scritto:
>>> >>>
>>> >>> Den 30 mar 2016 8:36 fm skrev "Elvis Stansvik" <elvstone at gmail.com>:
>>> >>>>
>>> >>>> Hi all,
>>> >>>>
>>> >>>> I can understand why I can do
>>> >>>>
>>> >>>> property Item foo: Foo {}
>>> >>>> property Item bar: Bar {}
>>> >>>> property variant items: {
>>> >>>>    "foo": foo,
>>> >>>>    "bar": bar
>>> >>>> }
>>> >>>>
>>> >>>> but not
>>> >>>>
>>> >>>> property variant items: {
>>> >>>>    "foo": Foo{},
>>> >>>>    "bar": Bar{}
>>> >>>> }
>>> >>>>
>>> >>>> The first opening { in the second example probably puts me in JS
>>> >>>> territory, where the Item {} syntax is not understood as a static
>>> definition
>>> >>>> of an item.
>>> >>>>
>>> >>>> However, is there some way of defining a map of static items like
>>> this,
>>> >>>> without having to bind the item instances to properties first? Such
>>> that I
>>> >>>> can later do e.g. items["foo"] to access an item?
>>> >>>
>>> >>> I should state my use case as well: I'm doing a small page based
>>> embedded
>>> >>> app (less than 20 pages), based on a StackView, where I'm thankfully
>>> not
>>> >>> hardware constrained (it's a fast PC). So I have no reason to use
>>> Loader to
>>> >>> load pages dynamically but was thinking of keeping them all
>>> statically in a
>>> >>> map, so that I can switch page based on the name of the page (e.g
>>> >>> "WelcomeScreen") by calling some function or perhaps emitting a
>>> signal with
>>> >>> the name as argument.
>>> >>>
>>> >>> For this use cases (and others), I usually use one of the
>>> ObjectModel,
>>> >>> DelegateModel or Package (or the older VisualDataModel). They are
>>> wonderful
>>> >>> for creating models containing QML object and they can created as
>>> you want.
>>> >>> Also DelegateModel can contains groups so you can filter them, and
>>> Package
>>> >>> let you to name the items so you can access using dot syntax:
>>> views.foo,
>>> >>> views.bar
>>> >>> In your case, I will use DelegateModel and access using numeric
>>> index, but
>>> >>> you can also explore Package and use the attached propertied
>>> Package.name to
>>> >>> give a name to all the views.
>>> >>
>>> >> Thanks a lot for the suggestions.
>>> >>
>>> >> I must ask though. Why would you use a DelegateModel in my case? Would
>>> >> you manage the name -> index mapping separately then? (to avoid
>>> >> hardcoded indices throughout the code).
>>> >>
>>> >> I think I will go the Package route, the dot syntax seems like a nice
>>> >> thing I can use.
>>> >>
>>> >> Elvis
>>> >
>>> > I think that the Package may be the best route for you, but I suppose
>>> it can be used only with a DelegateModel and not alone. And of course, I
>>> suggest you to give a try.
>>>
>>> Alright. Althought I came to think of something: Will not Package
>>> require me to define the items fully inside the Package? E.g. I would
>>> have to have my screens all defined in the same file, like:
>>>
>>> Package {
>>>     WelcomeScreen {
>>>         id: welcomeScreen
>>>         Package.name: "welcomeScreen"
>>>         ...
>>>     }
>>>     OtherScreen {
>>>         id: otherScreen
>>>         Package.name: "otherScreen"
>>>         ...
>>>     }
>>>     ....
>>> }
>>>
>>> My screens will be quite complex, and I would want to keep them in
>>> separate QML files :/ So if using Package requires me to have them all
>>> inline like this, I'll have to find some other solution.
>>>
>>> One idea I had was to abandon the idea with identifying screens by
>>> their name as a string, and instead use a singleton (e.g. Screens.qml)
>>> where I keep all the screens as properties, so I could do e.g.
>>> Screens.welcomeScreen to refer to them. But I hit some trouble with
>>> using multiple singletons (see my other most recent post to the list).
>>>
>>> > The Package has been added recently, before the introducing of Package
>>> I used to use the Component.onCompleted to construct the name -> index
>>> mapping. In this way, it’s less hardcoded and inside the definition of the
>>> Items. So, if you move an item or you insert a new one in the middle, the
>>> name -> index mapping is automatically updated without need to touch
>>> anything.
>>>
>>> Alright, maybe Package is not for me though, considering the above,
>>> and that you mention it needs a DelegateModel, which I don't think I
>>> have any use for (the app is using a StackView as the central
>>> navigation).
>>>
>>> Elvis
>>>
>>> >
>>> > Ciao,
>>> > Gianluca.
>>> >
>>> _______________________________________________
>>> 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/20160330/da5428ab/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 12665 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20160330/da5428ab/attachment.png>


More information about the Interest mailing list