[Interest] Best model type for shared data between C++ and QML, as well as insertion and removal on both sides.

Ben Lau xbenlau at gmail.com
Thu Nov 20 18:22:10 CET 2014


I have tried QQmlListProperty , QObjectListModel (code from git) . Finally
, I found that implement a QAbstractListModel to store QList<QVariantMap>
is the most simple , flexible and reusable solution. You don't need to care
about QObject ownership and works just like a ListModel , except you can't
pass it to worker.  Addition cost in C++ , a converter from your data
structure to QVariantMap is needed.

A good example can be found in this repo:

qml-object-model
<https://qt.gitorious.org/qt-labs/qml-object-model/source/057666b294f8d0ac50fc97134a6591bd2f33b83c:>



On 20 November 2014 23:38, Nuno Santos <nunosantos at imaginando.pt> wrote:

> Jerome,
>
> Thanks for your feedback. In time between your reply I have achieved
> precisely what you have said in your reply.
>
> Which options would you consider for this problem?
>
> What about QVariantMap? Is it a model? Can’t find 5.3 documentation for it.
>
> Regards,
>
> Nuno
>
>
> On 20 Nov 2014, at 15:24, Jérôme Godbout <jerome at bodycad.com> wrote:
>
> Hi,
> My observation with the QQmlListProperty so far. You can assign to it but
> only with javascript array, list, etc. It does not allow diect array object
> instanciate. The following should work:
>
>
> *presets: [patchSet1]*
> *PatchSet *
> *{*
>
>
> *            id: patchSet1            name: "Preset 1"            patches:
> [patch1, patch2] *
>
> * }Patch { id: patch1; name: "Patch 1"}*
> *Patch { id: patch2; name: "Patch 2"}*
>
> You cannot assign one QQmlListProperty to another one
>
> *presets: myOtherQQmlListProperty   // Won't work*
>
> But you can make yourself a javascript function that take every element of
> a QQmlListProperty and put them into a JS Array and assign that array to
> the list
>
> *function convertQQmlListPropertyToJSArray(myQQmlList)*
> *{*
> *   var rv = [];*
> *for(var i = 0; i < myQQmlList.length; ++i)*
> *{*
> *  rv.push(myQQmlList[i];*
> *}*
> *return rv;*
> *}*
>
> *presets: convertQQmlListPropertyToJSArray(myOtherQQmlListProperty)  //
> will work*
>
> Another point, the QQmlListProperty will clear and append every element
> into it, it does not emitChanged when doing so, you have to create another
> signal.
> Personnaly, for those exchange, I prefer to go QVariantMap, you still have
> to emit the change and reassign the whole map every time, but it's easy to
> manipulate into Javascript. QQmlListProperty are only fun if populated
> from C++ and only read from Qml.
>
>
> On Thu, Nov 20, 2014 at 9:38 AM, Nuno Santos <nunosantos at imaginando.pt>
> wrote:
>
>> Hi,
>>
>> I need to implement a model class that allows me to have the data in C++
>> but exposed to QML.
>>
>> The data will need to be exposed to QML and it will be necessary to write
>> from QML to that model as well.
>>
>> The C++ side will be in charge of the data persistence.
>>
>> I started with QQmlListProperty and it works for having data exposed from
>> C++ to QML. The problem is that I also need to dynamically instantiate data
>> on the QML side and write to the list. That doesn’t seem to be possible,
>> or, if it is, I don’t know how to get there. So far I have only been able
>> to write to the list, writing the items on the property it self. See
>> example below.
>>
>> What I am trying to do with QQmlListProperty is possible or should I
>> adopt another model type such as QAbstractListModel?
>>
>> Thanks
>>
>> Nuno
>>
>> Example:
>>
>> // works
>> PatchSetManager {
>>     id: patchManager
>>
>>     presets: [
>>         PatchSet {
>>             name: "Preset 1"
>>             patches: [
>>                 Patch {
>>                     name: "Patch 1"
>>                 },
>>                 Patch {
>>                     name: "Patch 2"
>>                 }
>>             ]
>>         }
>>     ]
>> }
>>
>> // doesn’t work
>>
>> var patchSet = Qt.createQmlObject('import Imaginando 1.0; PatchSet {}',
>> patchManager);
>>
>> if (patchSet)
>> {
>>     console.log("object created successfully");
>> }
>>
>> patchSet.name = "test"
>>
>> var patch = Qt.createQmlObject('import Imaginando 1.0; Patch {}',
>> patchSet);
>>
>> if (patch)
>> {
>>     patchSet.patches.append(patch)
>>     console.log(patchSet.patches + " length: " + patchSet.patches.length)
>> }
>>
>>
>> _______________________________________________
>> Interest mailing list
>> 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141121/edc72a00/attachment.html>


More information about the Interest mailing list