[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.1

    VisualItemModel {
    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.1

    Rectangle {
    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.1

    Rectangle {
    id: pageControl
    height: 300
    width: 300

    ListView {
           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: view

    delegate: Rectangle {
    id: myDelegate
    width: view.ListView.width; height: 200

    Loader {
      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!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.