I'm trying to set the model
property of a QML GridView
from C++ by calling
QQmlProperty::write(gridview, "model", QVariant::fromValue(objlist));
.
gridview
is set correctly, I can modify the property from C++, when I set it to a QList with 6 entries and print them from QML I get
qml: model = item(0x30617b50), Item(0x30617b90), Item(0x30617bd0), Item(0x30617c10), Item(0x30617c50), Item(0x30617cd0)
, though the model is not being displayed.
The Qt documentation suggest calling
QQmlContext *ctxt = view->rootContext();
ctxt->setContextProperty("gridModel", QVariant::fromValue(objlist));
And then setting the property from QML with model: gridModel
but that does not really suit my needs. It works fine though, as soon as the property is set the correct data is being displayed. When I print the variable from QML the output is
qml: model = [object Object]
so there is definitely a difference between setting the context property and setting the object property, but I don't know how to fix this.
If you say
QQmlProperty::write
correctly sets the model so what is your question? Anyway I suggest one more solution:Let's say you have
GridView
like below:objectName
is mandatory.So accessing from C++ could be:
The solution I came up with is slightly different from the answers posted, so I figured writing a clear answer would be best.
The key was to subclass
QAbstractItemModel
(or more precisely..ListModel
so you don't have to deal with rows/columns in C++ and QML).When doing it this way, not only can you simply set the model as a property with
It also notifys QML whenever a change is made to the model, e.g. an Item deleted. (You'll have to handle the changes properly though, see
removeRows()
in the example)Here is my ItemModel:
Sources:
data()
slightly altered) implementation of QAbstractItemModel from which I took the rolenames functionsInstead of attempting to access QML objects or properties from C++ I would suggest to using bindings on the QML side and provide the property values from C++.
If exposing the model instance via setContextProperty doesn't quite fit your needs, e.g. if the model is instantiated after QML loading time, then I would suggest the following approach:
The interface class would look somewhat like this
Of course instead of the setter the change of m_model could be internal to MyInterface, etc. That gives you full control on the C++ side on when to create a model instance, when to change it, when to delete it. If you change the type to QAbstractItemModel*, or some common model base class of yours, you could even change the type of model during runtime as you see fit