Solved Newb: How to access C++ QAbstractListModel from child Qml item
-
Starting from Qt example "AbstractItemModel", then wrapping the root Qml ListView in an Item, ListView can no longer access the model, and I cannot figure out how to do it. I want to use models outside of the root Item.
Error is:
qrc:view.qml:55:1: Required property model was not initialized ListView { ^ qrc:view.qml: 55
Original QML:
ListView { width: 200; height: 250 required model delegate: Text { required property string type required property string size text: "Animal: " + type + ", " + size } }
New QML:
Item { ListView { width: 200; height: 250 required model ... } }
main() is:
QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView); view.setInitialProperties({{"model", QVariant::fromValue(&model)}}); view.setSource(QUrl("qrc:view.qml"));
-
Three changes helped in this case:
- Use setContextProperty() instead of setInitialProperties()
- Assign ListView model
- Don't use "model" for model name.
//view.setInitialProperties({{"model1", QVariant::fromValue(&model)}}); view.rootContext()->setContextProperty("model1", &model);
ListView { ... //required model model: model1 ... }
-
@Gordon-Smith said in Newb: How to access C++ QAbstractListModel from child Qml item:
Use setContextProperty() instead of setInitialProperties()
Don't use setContextProperty for new code
useqmlRegisterSingletonInstance
insteadYour problem was that you set the model property of the Item, not the child ListView.
You could have added an alias in Item :
property alias model: idOfTheListView.model
Or a property in Item and reference it in the ListView:model: idOfTheItem.model
-
@GrecKo Thank you for your response. I found your post about qmlregistersingletoninstance.
You are right to comment, my problem is not solved. I cannot use models in my larger app.
I understand what you are saying about properties, but I am unable to get it to work.
I'm also unable to compile a Singleton at the moment, so I stay with setContextProperty() for this post.
view.rootContext()->setContextProperty(QStringLiteral("animalModel"), &model);
I try the following (A):
Item { id: root property alias animalModel: listView.model ListView { id: listView delegate: Text { text: "Animal: " + type + ", " + size } } }
Probably backwards-thinking on my part. There is no QML error, and the ListView is empty.
Same result with (B):
Item { id: root ListView { model: root.animalModel delegate: Text { text: "Animal: " + type + ", " + size } } }
And (C):
Item { id: root property alias animalModel2: animalModel ListView { id: listView model: root.animalModel2 delegate: Text { text: "Animal: " + type + ", " + size } } }
Error is: Invalid alias reference. Unable to find id "animalModel"
I'm quite lost, obviously.
-
Setting the context property will make "animalModel" implicitly available in QML. In (A), your alias root.animalModel is shadowing your context property, which is why it doesn't work. Try this:
Item { id: root ListView { id: listView model: animalModel delegate: Text { text: "Animal: " + type + ", " + size } } }
Incidentally, I'm a huge fan of setContextProperty, as it behaves the same as the "dummydata" folder when using qmlscene.
-
@dgallagher219 Turns out, your suggestion still works! It's easy to get off track. Thanks.