[Interest] Define map of static items in QML

Elvis Stansvik elvstone at gmail.com
Wed Mar 30 17:22:43 CEST 2016


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!

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/5f4d093f/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/5f4d093f/attachment.png>


More information about the Interest mailing list