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. Access model owned by class in QML
Forum Updated to NodeBB v4.3 + New Features

Access model owned by class in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 2 Posters 2.2k Views
  • 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.
  • O Offline
    O Offline
    Obi-Wan
    wrote on last edited by Obi-Wan
    #1

    Hi!

    I've seen several topics on similar problems, but I still haven't been able to solve it, so I'm making a new thread.

    I have a class, ModelManager, that owns an instance of MyListModel, inheriting from QAbstractListModel. The ModelManager is the .cpp backend that is exposed to QML through a call to setContextProperty in main.cpp.

    I would like to access myListModel in QML and use it as a model for a Repeater.

    My idea was to have the ModelManager own an instance of myListModel and have a Q_INVOKABLE getter in ModelManager.

    In ModelManager I have:

    class ModelManager : QObject
    {
    Q_OBJECT
    public:
    ModelManager(QObject* parent = 0);
    Q_INVOKABLE MyListModel* myListModel() {return &myListModel_;}
    private:
    MyListModel myListModel_;
    }
    

    And in the Repeater I want to write:

    Repeater
    {
    model: manager.myListModel()
    ...
    }
    

    I can't get it working however. I've read several posts about out it here on the forum. Some mention qmlRegisterType, which I've tried calling in my main.cpp with no luck.

    qmlRegisterType<MyListModel>("ListModel",1,0, "listModel");
    

    and then importing it with:

    import ListModel 1.0
    

    But no matter what I try, I always get the error:

    Unkown return type: MyListModel*
    

    I've also tried returing QObject* in myListModel(). This runs, but I get a very nasty error and crash, I'm assuming when the Repeater actually tries to access the model.

    Any ideas about what I'm getting wrong?

    1 Reply Last reply
    1
    • L Offline
      L Offline
      literA2
      wrote on last edited by literA2
      #2

      @Obi-Wan you don't need to have a Q_INVOKABLE getter to expose your MyListModel into QML components instead use QQmlContext class, try it this way:

      //main.cpp
      QQmlContext *context = new QQmlContext(engine.rootContext());
      context->setContextProperty("myListModel", &myListModel);
      
      //qml file
      Repeater
      {
         model: myListModel
         ...
      }
      
      O 1 Reply Last reply
      2
      • L literA2

        @Obi-Wan you don't need to have a Q_INVOKABLE getter to expose your MyListModel into QML components instead use QQmlContext class, try it this way:

        //main.cpp
        QQmlContext *context = new QQmlContext(engine.rootContext());
        context->setContextProperty("myListModel", &myListModel);
        
        //qml file
        Repeater
        {
           model: myListModel
           ...
        }
        
        O Offline
        O Offline
        Obi-Wan
        wrote on last edited by
        #3

        @literA2 Thanks!

        This seems to work, as in the text turns blue if I write myListModel in QML, but I'm having a hard time confirming if it does!

        myListModel currently is a list of doubles, I tought I could should these in a QML window by writing:

        ListView
        {
        id: testView
        width: 200
        height: 200
        x: 50
        y: 50
        model: myListModel
        
        delegate: Text {
        text: display // As this is the default role
        }
        

        Shouldn't this work?

        L 1 Reply Last reply
        0
        • O Obi-Wan

          @literA2 Thanks!

          This seems to work, as in the text turns blue if I write myListModel in QML, but I'm having a hard time confirming if it does!

          myListModel currently is a list of doubles, I tought I could should these in a QML window by writing:

          ListView
          {
          id: testView
          width: 200
          height: 200
          x: 50
          y: 50
          model: myListModel
          
          delegate: Text {
          text: display // As this is the default role
          }
          

          Shouldn't this work?

          L Offline
          L Offline
          literA2
          wrote on last edited by
          #4

          @Obi-Wan in order to use the model properties in delegate, this is the syntax:

          model.<propertyName>

          O 1 Reply Last reply
          1
          • L literA2

            @Obi-Wan in order to use the model properties in delegate, this is the syntax:

            model.<propertyName>

            O Offline
            O Offline
            Obi-Wan
            wrote on last edited by Obi-Wan
            #5

            @literA2 Thanks again, that does indeed work!

            I'm not sure what I'm doing wrong, but I often have trouble figuring out these smaller details. I keep looking in the documentation, but I guess I keep looking in the wrong place.

            In any case, my complete solution to the original problem is, as per @literA2's suggestion, to use setContextProperty in main.cpp. The model is still owned by the modelManager in my case, but I expose the model to QML in main.cpp by calling a getter.

            main.cpp

            ModelManager modelManager;
            
            QQmlApplicationEngine engine;
            engine.rootContext()->setContextProperty("myListModel", modelManager.myListModel());
            
            ...
            

            myListModel() returns a pointer to the MyListModel of the ModelManager.

            In my case, I can test that this works by having a ListView that displays the contents of the model like this. I'm using the default display role currently.

            ListView
            {
            id: testView
            width: 200
            height: 200
            x: 50
            y: 50
            model: myListModel
            
            delegate: Text {
            text: model.display
            }
            
            L 1 Reply Last reply
            0
            • O Obi-Wan

              @literA2 Thanks again, that does indeed work!

              I'm not sure what I'm doing wrong, but I often have trouble figuring out these smaller details. I keep looking in the documentation, but I guess I keep looking in the wrong place.

              In any case, my complete solution to the original problem is, as per @literA2's suggestion, to use setContextProperty in main.cpp. The model is still owned by the modelManager in my case, but I expose the model to QML in main.cpp by calling a getter.

              main.cpp

              ModelManager modelManager;
              
              QQmlApplicationEngine engine;
              engine.rootContext()->setContextProperty("myListModel", modelManager.myListModel());
              
              ...
              

              myListModel() returns a pointer to the MyListModel of the ModelManager.

              In my case, I can test that this works by having a ListView that displays the contents of the model like this. I'm using the default display role currently.

              ListView
              {
              id: testView
              width: 200
              height: 200
              x: 50
              y: 50
              model: myListModel
              
              delegate: Text {
              text: model.display
              }
              
              L Offline
              L Offline
              literA2
              wrote on last edited by
              #6

              @Obi-Wan i think you don't need to exposed your modelManager, you can omit that line.

              O 1 Reply Last reply
              0
              • L literA2

                @Obi-Wan i think you don't need to exposed your modelManager, you can omit that line.

                O Offline
                O Offline
                Obi-Wan
                wrote on last edited by
                #7

                @literA2 said in Access model owned by class in QML:

                @Obi-Wan i think you don't need to exposed your modelManager, you can omit that line.

                You are absolutely right I think, it is only there because I'm using for something else. I'll remove it here for clarity.

                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