Newby questions about QML models

Tomaz Canabrava tcanabrava at kde.org
Mon Feb 1 10:46:10 PST 2016


On Mon, Feb 1, 2016 at 12:49 PM, Willem Ferguson <
willemferguson at zoology.up.ac.za> wrote:

> May I ask a few questions about implementing QML models in C++? Apologies
> if I sound uninformed.
>
> 1) When a model is specified on the QML side, e.g. in
>
>     ComboBox {
>     model xxxxx;
>
>     and that model is supplied by the C++ code, does the object returned
> by C++ have to a model object,
>     e.g. a QStringListModel or a QAbstractListModel? Or could it be a
> simple QStringList in the case of a simple ListView or ComboBox?
>     I suspect the former applies.
>

They can be either a QStringList or a QAbstractModel - they cannot be Tree
Models currently (QML has some tree model code already but it's a bit
cumberstome to use)


>
> 2) When the model is returned from C++ to QML, must this be performed by a
> C++ object that inherits from such a model class (e.g. QAbstractListModel)
> or could it be any class (i.e. inheriting from an arbitrary base class)
> that has an extractor method returning an appropriate model?
>

both:
I can have a class DiveComputers that is a model based on
QAbstractListModel, since any dive can have zero or more dive computers, I
can have the method DiveComputers *diveComputers() on the class Dive as a
Q_PROPERTY, and I can access it in QML via:

ListView {
    id: diveList
    model : diveListModel
    delegate {
        ListView {
            id: diveComputerList
            model: dive.diveComputers
        }
    }
}



> 3) Related to the above, within the Download-from-dc context, is the model
> used by the QML is dependent on the specific standard built-in
>    methods provided by one of the standard model classes (let's say
> QAbstractListModel) or can one implement an arbitrary extractor method that
> returns a model (e.g a QStringListModel). To me it looks like the latter is
> the case because QAbstracListModel does not have a standard built-in method
> that returns the complete list.
>

models shouldn't return the complete list - they have the data() method and
the rowCount() method, this way the view can request the specific indexes
to show without loading everything in memory.


>
> 4) Within the existing main.qml, selecting "Show GPS fixes" activates the
> C++ qmlManager.populateGpsData() method that, in turn, activates
> GpsListModel::instance()->update.  The appropriate (now updated) model is
> m_instance, returned by GpsListModel::instance().
> [So syntactically  the :: operator has priority over the -> operator,
> because instance()->update() does not make sense.]
> Is my understanding correct here?
>

the :: operator is the Scope operator, in c++. GpsListModel::instance()
means "Run the static method instance() that belongs to GpsListModel",
static methods are class methods that dont need to have an object.
if you look at the implementation of instance, it will be something like
this:

GpsListModel *GpsListModel::instance() {
      static    GpsListModel *self = new GpsListModel();
      return self;
}

this way we create only *one* object of type GpsListModel and use it when
we want (this is a safe way to create a global variable in C++ for complex
types )



> Now, the actual display of GPS data is done in  gpsList.qml, using
> gpsModel as a model and formatted by gpsDelegate. But I cannot link
> gpsModel back to main.qml, QMLManager or to GpsListModel. Where is the link
> made between gpsModel in gpsList.qml and the underlying C++ code?
> As discussed before I would have used ctxt->setContextProperty("gpsModel",
> QVariant::fromValue(gpsQStringList)) but this is clearly not the case here.
>

I don't really know.
the GPS data is global (shared via all other dives) or from a single dive?
if it's from a single dive, I think the approach to have a method inside
the DiveObjectWrapper that returns he gpsData for it is the place to go
if it's not from a single dive, I think
ctxt->setContextProperty("gpsModel", QVariant::fromValue(gpsQStringList))
is a good way to start.


> 5) If I understand it correctly, one can let DownloadManager inherit from
> QAbstractListModel, then let DownloadManager have two extractor methods,
> getVendorModel() and getProductModel() that each return an appropriate and
> populated model, callable from QML. Does this make sense at all?
>

AHH, it makes.
and my answers above answers it. just change from DiveObjectWrapper to
DownloadManager, and make a Q_PROPERTY for the vendorModel and productModel.


>
> I hope my questions are clear, and thank you so much for your time in
> answering.
> Kind regards,
> willem
>
>
>
>
>
>
>
> _______________________________________________
> subsurface mailing list
> subsurface at subsurface-divelog.org
> http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.subsurface-divelog.org/pipermail/subsurface/attachments/20160201/8fd21c67/attachment.html>


More information about the subsurface mailing list