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

Access model owned by class in QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
7 Posts 2 Posters 2.0k 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 18 Sept 2017, 14:04 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 18 Sept 2017, 17:06 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 19 Sept 2017, 10:01
      2
      • L literA2
        18 Sept 2017, 17:06

        @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 19 Sept 2017, 10:01 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 19 Sept 2017, 10:05
        0
        • O Obi-Wan
          19 Sept 2017, 10:01

          @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 19 Sept 2017, 10:05 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 19 Sept 2017, 10:52
          1
          • L literA2
            19 Sept 2017, 10:05

            @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 19 Sept 2017, 10:52 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 19 Sept 2017, 11:58
            0
            • O Obi-Wan
              19 Sept 2017, 10:52

              @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 19 Sept 2017, 11:58 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 19 Sept 2017, 13:47
              0
              • L literA2
                19 Sept 2017, 11:58

                @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 19 Sept 2017, 13:47 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

                4/7

                19 Sept 2017, 10:05

                • Login

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