Jason R. Mick
Jason R. Mick

Reputation: 5297

How to Bind a Readonly var to the Data Of a ListModel in QML?

Brief

Is it possible to create a readonly property var bound to the data inside the ListElement values of a ListModel?

(Or is there some equivalent route to get a structured readonly object containing this data without the write exposure of a readonly property ListModel's get(...) function?)


Background / Full-Version

I'm working with a data model code in qml. This installed project makes heavy use of a pragma Singleton front-end / QtObject back-end pattern, in which the data in the front-end is readonly, the backend is conditionally loaded via a Loader w/ source assigned via a switch conditional, and where partner runtime projects instead use function calls to order the backend to change data (when necessary). This is done to assist in obfuscating whether the backend is real data read in from hardware, or mocked up data set by the partner project with the runtime code. Another upside is the ability to dynamically switch from hardware inputs to software mockups at runtime.

The basic pattern is:

SomeFeatureFrontEnd.qml

pragma Singleton
import QtQuick 2.0

QtObject {
   id: someFeatureFrontEnd

   readonly property string _backend: "fake"
   readonly property double fraction: _backend.item.fraction
   readonly property int counter: _backend.item.counter

   //... etc ...

   function setFraction(value) { _backend.item.setFraction(value) }

   function incrementCounter() { _backend.item.incrementCounter() }

   function decrementCounter() { _backend.item.decrementCounter() }

   //... etc ...

    _backend: Loader {
        id: _backend
        source: {
            switch(backend) {
                case "fake":
                default:
                   return "backends/SomeFeatureBackendFake.qml"
            }
        }
    }  
}

backends/SomeFeatureBackendApi.qml

import QtQuick 2.0

//This is just an interface for the derived backend children 
//  not actually instantiation.
QtObject {
   property double fraction
   property int counter

   //... etc ...

   function setFraction(value) { }

   function incrementCounter() { }

   function decrementCounter() { }

   //... etc ...
}

backends/SomeFeatureBackendFake.qml

import QtQuick 2.0

SomeFeatureBackendApi {
   fraction: 1.0
   counter: 0

   //... etc ...

   function setFraction(value) { fraction = value }

   function incrementCounter() { counter++ }

   function decrementCounter() { counter-- }

   //... etc ...
}

Now within that general strategy I've encountered a sort of dilemma in that I would like to add some dynamically allocated structured data in the same manner as counter and fraction above. A seemingly intuitive fit for this is seemingly ListModel as it supports structured, modifiable data.

A few details about the ListModel:

Or if it's more convenient here's an example:

ThingList.qml

import QtQuick 2.0

ListModel {
   //Initializer code to dynamically initialize w/ an
   //arbitrary number of ThingEntry instances...
}

ThingEntry.qml

import QtQuick 2.0

ListElement {
   property double profileValue
   property int profileScore
}

Let me know if you have any questions on the obfuscated code snippets above.

Now recapping the question / dilemma per the brief, regarding the use of this ListModel with my backend/frontend pattern:

Per my understanding readonly property ListModel structuredStuff is still modifiable via structuredStuff.get() calls, right? I don't want that... I want whatever is on the frontend to be readonly for the reasons discussed above.

How do I conveniently and efficiently get a readonly representation that's var-like in the front-end, based upon the non-readonly property ListModel in the backend?

Upvotes: 0

Views: 976

Answers (1)

Yi Qingliang
Yi Qingliang

Reputation: 23

I have developed a framework for this problem based on qml. the basic problem is the listmodel must contain direct data, but not object, in my framework, the listmodel can contain any qt object, which is support data binding, i.e. the listmodel data can binding to other qt data/var.

Upvotes: 0

Related Questions