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

Nuno Santos nunosantos at imaginando.pt
Thu Nov 20 23:40:09 CET 2014


I have subclassed QAbstractListModel and i’m already able to have the model listed in a list view. 

What I can’t find is how I programmatically add items to the model from the QML side and which methods I need to reimplement in my model class. 

The qml-object-model you have sent me is probably old because there aren’t the same methods on the documentation for Qt 5.3 

Suggestions?


> On 20 Nov 2014, at 17:22, Ben Lau <xbenlau at gmail.com> wrote:
> 
> 
> 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 <mailto: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 <mailto: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 <mailto: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 <mailto:Interest at qt-project.org>
>> http://lists.qt-project.org/mailman/listinfo/interest <http://lists.qt-project.org/mailman/listinfo/interest>
>> 
> 
> 
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org <mailto:Interest at qt-project.org>
> http://lists.qt-project.org/mailman/listinfo/interest <http://lists.qt-project.org/mailman/listinfo/interest>
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20141120/b53ff765/attachment.html>


More information about the Interest mailing list