[Interest] Define map of static items in QML

Jérôme Godbout jerome at bodycad.com
Wed Mar 30 16:55:32 CEST 2016


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]

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/903ebd68/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/903ebd68/attachment.png>


More information about the Interest mailing list