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. Using C++ Models with Qt Quick Views example
Forum Updated to NodeBB v4.3 + New Features

Using C++ Models with Qt Quick Views example

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
6 Posts 3 Posters 1.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.
  • M Offline
    M Offline
    Mark81
    wrote on 2 Nov 2021, 11:15 last edited by
    #1

    I'm trying to adapt this example to my needs. Here my code:

    modelcontent.h

    #ifndef MODELCONTENT_H
    #define MODELCONTENT_H
    
    #include <QObject>
    #include <QAbstractListModel>
    
    class Content
    {
    public:
        Content(const QString &label) : _label(label)
        {
        }
    
        QString label() const { return  _label; }
    
    private:
        QString _label;
    };
    
    class ModelContent : public QAbstractListModel
    {
        Q_OBJECT
    
    public:
        enum ContentRoles
        {
            LabelRole = Qt::UserRole + 1,
        };
    
        explicit ModelContent(QObject *parent = nullptr) : QAbstractListModel(parent)
        {
        }
    
        void addContent(const Content &content)
        {
            beginInsertRows(QModelIndex(), rowCount(), rowCount());
            _content << content;
            endInsertRows();
        }
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const
        {
            Q_UNUSED(parent);
            return _content.size();
        }
    
        QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
        {
            if (index.row() < 0 || index.row() >= _content.size()) return QVariant();
    
            const Content &content = _content[index.row()];
            switch (role)
            {
            case LabelRole: return content.label();
            default: return QVariant();
            }
        }
    
    private:
        QList<Content> _content;
    
    protected:
        QHash<int, QByteArray> roleNames() const
        {
            QHash<int, QByteArray> roles;
            roles[LabelRole] = "label";
            return roles;
        }
    };
    
    #endif // MODELCONTENT_H
    

    flow.h

    #ifndef FLOW_H
    #define FLOW_H
    
    #include <QObject>
    #include "modelcontent.h"
    
    class Flow : public QObject
    {
        Q_OBJECT
    
    public:
        explicit Flow(QObject *parent = nullptr);
        ModelContent modelContent;
    };
    
    #endif // FLOW_H
    

    flow.cpp*

    #include "flow.h"
    
    Flow::Flow(QObject *parent) : QObject(parent)
    {
        modelContent.addContent(Content("abc"));
        modelContent.addContent(Content("def"));
    }
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    #include "flow.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        Flow flow;
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl)
        {
            if (!obj && url == objUrl) QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.setInitialProperties({{"model", QVariant::fromValue(&flow.modelContent)}});
        engine.load(url);
    
        return app.exec();
    }
    

    main.qml

    import QtQuick
    import QtQuick.Controls
    
    ApplicationWindow {
        id: window
        width: 1920
        height: 1080
        visible: true
        visibility: "FullScreen"
        color: "black"
    
        Component {
            id: delegate
    
            Item {
                id: item
                width: 864*0.7; height: 1536*0.7
    
                Text {
                    required property string label
                    anchors.centerIn: parent
                    text: label
                }
            }
        }
    
        PathView {
            id: view
            anchors.fill: parent
            anchors.bottomMargin: 150
            anchors.topMargin: 50
            pathItemCount: 3
            preferredHighlightBegin: 0.5
            preferredHighlightEnd: 0.5
            highlightRangeMode: PathView.StrictlyEnforceRange
            highlightMoveDuration: 1000
            snapMode: PathView.SnapToItem
            rotation: -90
    
            required model
    
            delegate: delegate
            path: Path {
                startX: 0; startY: view.height / 2
                PathLine {x: view.width/2; y: view.height / 2; }
                PathLine {x: view.width; y: view.height / 2; }
            }
        }
    }
    

    No errors during building, but at run-time I get:

    QML debugging is enabled. Only use this in a safe environment.
    QQmlApplicationEngine failed to create component
    qrc:/main.qml: Setting initial properties failed: ApplicationWindow does not have a property called model
    qrc:/main.qml:117:5: Required property model was not initialized
    12:06:36: Remote process crashed.

    Line 117 is:

    PathView {
    

    I double checked the example and I didn't find anything I missed.
    I just changed the setInitialProperties call from QQuickView to QQmlApplicationEngine.

    Any idea?

    KroMignonK 1 Reply Last reply 2 Nov 2021, 11:36
    0
    • M Mark81
      2 Nov 2021, 11:15

      I'm trying to adapt this example to my needs. Here my code:

      modelcontent.h

      #ifndef MODELCONTENT_H
      #define MODELCONTENT_H
      
      #include <QObject>
      #include <QAbstractListModel>
      
      class Content
      {
      public:
          Content(const QString &label) : _label(label)
          {
          }
      
          QString label() const { return  _label; }
      
      private:
          QString _label;
      };
      
      class ModelContent : public QAbstractListModel
      {
          Q_OBJECT
      
      public:
          enum ContentRoles
          {
              LabelRole = Qt::UserRole + 1,
          };
      
          explicit ModelContent(QObject *parent = nullptr) : QAbstractListModel(parent)
          {
          }
      
          void addContent(const Content &content)
          {
              beginInsertRows(QModelIndex(), rowCount(), rowCount());
              _content << content;
              endInsertRows();
          }
      
          int rowCount(const QModelIndex &parent = QModelIndex()) const
          {
              Q_UNUSED(parent);
              return _content.size();
          }
      
          QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
          {
              if (index.row() < 0 || index.row() >= _content.size()) return QVariant();
      
              const Content &content = _content[index.row()];
              switch (role)
              {
              case LabelRole: return content.label();
              default: return QVariant();
              }
          }
      
      private:
          QList<Content> _content;
      
      protected:
          QHash<int, QByteArray> roleNames() const
          {
              QHash<int, QByteArray> roles;
              roles[LabelRole] = "label";
              return roles;
          }
      };
      
      #endif // MODELCONTENT_H
      

      flow.h

      #ifndef FLOW_H
      #define FLOW_H
      
      #include <QObject>
      #include "modelcontent.h"
      
      class Flow : public QObject
      {
          Q_OBJECT
      
      public:
          explicit Flow(QObject *parent = nullptr);
          ModelContent modelContent;
      };
      
      #endif // FLOW_H
      

      flow.cpp*

      #include "flow.h"
      
      Flow::Flow(QObject *parent) : QObject(parent)
      {
          modelContent.addContent(Content("abc"));
          modelContent.addContent(Content("def"));
      }
      

      main.cpp

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      #include <QQmlContext>
      #include "flow.h"
      
      int main(int argc, char *argv[])
      {
          QGuiApplication app(argc, argv);
      
          Flow flow;
      
          QQmlApplicationEngine engine;
          const QUrl url(QStringLiteral("qrc:/main.qml"));
          QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl)
          {
              if (!obj && url == objUrl) QCoreApplication::exit(-1);
          }, Qt::QueuedConnection);
          engine.setInitialProperties({{"model", QVariant::fromValue(&flow.modelContent)}});
          engine.load(url);
      
          return app.exec();
      }
      

      main.qml

      import QtQuick
      import QtQuick.Controls
      
      ApplicationWindow {
          id: window
          width: 1920
          height: 1080
          visible: true
          visibility: "FullScreen"
          color: "black"
      
          Component {
              id: delegate
      
              Item {
                  id: item
                  width: 864*0.7; height: 1536*0.7
      
                  Text {
                      required property string label
                      anchors.centerIn: parent
                      text: label
                  }
              }
          }
      
          PathView {
              id: view
              anchors.fill: parent
              anchors.bottomMargin: 150
              anchors.topMargin: 50
              pathItemCount: 3
              preferredHighlightBegin: 0.5
              preferredHighlightEnd: 0.5
              highlightRangeMode: PathView.StrictlyEnforceRange
              highlightMoveDuration: 1000
              snapMode: PathView.SnapToItem
              rotation: -90
      
              required model
      
              delegate: delegate
              path: Path {
                  startX: 0; startY: view.height / 2
                  PathLine {x: view.width/2; y: view.height / 2; }
                  PathLine {x: view.width; y: view.height / 2; }
              }
          }
      }
      

      No errors during building, but at run-time I get:

      QML debugging is enabled. Only use this in a safe environment.
      QQmlApplicationEngine failed to create component
      qrc:/main.qml: Setting initial properties failed: ApplicationWindow does not have a property called model
      qrc:/main.qml:117:5: Required property model was not initialized
      12:06:36: Remote process crashed.

      Line 117 is:

      PathView {
      

      I double checked the example and I didn't find anything I missed.
      I just changed the setInitialProperties call from QQuickView to QQmlApplicationEngine.

      Any idea?

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on 2 Nov 2021, 11:36 last edited by
      #2

      @Mark81 said in Using C++ Models with Qt Quick Views example:

      I think you will have many name clashes:

      • engine.setInitialProperties({{"model", QVariant::fromValue(&flow.modelContent)}}); ==> model is a common property name for many classes, to avoid to use it a global property name!
      • same with component called delegate, this is a very bad idea ==> delegate: delegate will connect delegate to itself!

      first cleanup you class/component/variable naming to avoid those clashes.

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      1 Reply Last reply
      0
      • M Offline
        M Offline
        Mark81
        wrote on 2 Nov 2021, 11:43 last edited by Mark81 11 Feb 2021, 11:43
        #3

        You should tell this to the Qt developers :-) I found this name in the linked example.
        Anyway, I changed:

        engine.setInitialProperties({{"modelContent", QVariant::fromValue(&flow.modelContent)}});
        ...
        required modelContent
        delegate: delegateContent
        

        Now the errors are these:

        QQmlApplicationEngine failed to create component
        qrc:/main.qml: Property modelContent was marked as required but does not exist
        QQmlComponent: Component destroyed while completion pending
        This may have been caused by one of the following errors:
        qrc:/main.qml: Property modelContent was marked as required but does not exist

        1 Reply Last reply
        0
        • GrecKoG Offline
          GrecKoG Offline
          GrecKo
          Qt Champions 2018
          wrote on 2 Nov 2021, 13:52 last edited by GrecKo 11 Feb 2021, 13:54
          #4

          The example you linked work because it was assigning to the existing model property or the ListView.

          Here you would need to define a property to hold your model in the root object of your QML, the ApplicationWindow in your case:

          ApplicationWindow {
               id: window
               required property QtObject model
              // ...
              PathView {
                  model: window.model
                  // ...
              }
          }
          

          or :

          ApplicationWindow {
              property alias model: view.model
              // ...
              PathView {
                  id: view
                  // ...
              }
          }
          
          M 1 Reply Last reply 2 Nov 2021, 19:46
          0
          • GrecKoG GrecKo
            2 Nov 2021, 13:52

            The example you linked work because it was assigning to the existing model property or the ListView.

            Here you would need to define a property to hold your model in the root object of your QML, the ApplicationWindow in your case:

            ApplicationWindow {
                 id: window
                 required property QtObject model
                // ...
                PathView {
                    model: window.model
                    // ...
                }
            }
            

            or :

            ApplicationWindow {
                property alias model: view.model
                // ...
                PathView {
                    id: view
                    // ...
                }
            }
            
            M Offline
            M Offline
            Mark81
            wrote on 2 Nov 2021, 19:46 last edited by Mark81 11 Feb 2021, 19:47
            #5

            @GrecKo Thanks, I understood ListView, GridView, PathView and so on differ for how they show the items only.
            The first syntax worked, at least a bit more.

            Now I have to understand how to declare the required property label.
            The example used this syntax:

            delegate: Text {
                required property string type
                required property string size
            
                text: "Animal: " + type + ", " + size
            }
            

            but it doesn't work for me:

            Required property label was not initialized

            I'm very sorry but I don't understand this syntax yet. I'll be very glad if you can help me to make this to work but also if there is a page in the docs that explain how to achieve this simple task.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              Mark81
              wrote on 3 Nov 2021, 04:04 last edited by
              #6

              I'm not sure if this solution is ok, because is quite different from the example but at least it works:

              main.cpp

              engine.rootContext()->setContextProperty("modelContent", &flow.modelContent);
              

              main.qml

              PathView {
                  id: view
                  ...
                  model: modelContent
              
              1 Reply Last reply
              0

              1/6

              2 Nov 2021, 11:15

              • Login

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