Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] C++ equivalent of VisualItemModel
Forum Updated to NodeBB v4.3 + New Features

[Solved] C++ equivalent of VisualItemModel

Scheduled Pinned Locked Moved QML and Qt Quick
4 Posts 2 Posters 3.1k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • E Offline
    E Offline
    ephe
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • E Offline
      E Offline
      ephe
      wrote on last edited by
      #2

      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!

      1 Reply Last reply
      0
      • N Offline
        N Offline
        njeisecke
        wrote on last edited by
        #3

        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;
        }
        /
        ... */
        }
        @

        1 Reply Last reply
        0
        • E Offline
          E Offline
          ephe
          wrote on last edited by
          #4

          Thank you, that was a good idea!

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved