[Solved] C++ equivalent of VisualItemModel
-
Is it somehow possible to create a VisualItemModel in C++?
Or is it possible to fill a QML VisualItemModel from C++ code?I would like to create QML items dynamically in C++ code and then add them to a ListView.
-
I have tried another approach now, but it still does not work.
I created a VisualItemModel in QML:
MyModel.qml
@
import QtQuick 1.1VisualItemModel {
onCountChanged:
{
console.log("count changed")
}
Component.onCompleted: console.log("model created");
}
@And I've created a BlueRect component (just a blue rectangle)
BlueRect.qml
@
import QtQuick 1.1Rectangle {
width: 100
height: 62
color: "blue"
Component.onCompleted: console.log("rectangle created");
}
@This is what my main function in C++ looks like:
@int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDeclarativeEngine engine;QDeclarativeComponent compModel(&engine, QUrl("qml/Test/MyModel.qml"));
QDeclarativeItem* itemModel = qobject_cast<QDeclarativeItem*>(compModel.create());QDeclarativeComponent compRect(&engine, QUrl("qml/Test/BlueRect.qml"));
QDeclarativeItem* itemRect = qobject_cast<QDeclarativeItem*>(compRect.create());itemRect->setParentItem(itemModel);
QDeclarativeView view;
view.rootContext()->setContextProperty("itemModel", itemModel);
view.setSource(QUrl::fromLocalFile("qml/Test/main.qml"));
view.show();return app.exec();
}
@And here is my main.qml:
@
import QtQuick 1.1Rectangle {
id: pageControl
height: 300
width: 300ListView { id: view anchors { fill: parent; bottomMargin: 30 } model: itemModel preferredHighlightBegin: 0; preferredHighlightEnd: 0 highlightRangeMode: ListView.StrictlyEnforceRange orientation: ListView.Horizontal snapMode: ListView.SnapOneItem; flickDeceleration: 2000 }
}
@So basically I'm trying to add BlueRect components in C++ to my model. Then I'm trying to use that model in the ListView in QML.
The output says:
model created
rectangle created
so somehow it seems to be working. But sadly, I cannot see anything. When I'm filling the model directly with blue rectangles and use MyModel in the ListView directly, it is working.Can somebody help me? Or isn't it possible to fill a VisualItemModel in C++?
Thank you!
-
You could use a role in your model to return the Qml Component URL as a string and then use a Loader inside your delegate to create an instance of that component on demand:
@
ListView {
id: viewdelegate: Rectangle {
id: myDelegate
width: view.ListView.width; height: 200Loader { id: content anchors.fill: parent source: model.componentPath // ask the model for the component URL onLoaded: { /* Give the item access to the model data. */ /* The loaded component should provide a modelData variant property */ item.modelData = model } }
}
}
@In your model:
@
QVariant MyModel::data(const QModelIndex &index, int role) const
{
MyItem myItem = d->items.at(index.row()); // access your model data
/ ... /
switch (role) {
/ ... /
case ComponentPathRole:
return qmlBasePath + "/" + myItem->componentUrl;
}
/ ... */
}
@ -
Thank you, that was a good idea!