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. Update List Model created via QVariant::fromValue(QList<QObject*>))
Forum Updated to NodeBB v4.3 + New Features

Update List Model created via QVariant::fromValue(QList<QObject*>))

Scheduled Pinned Locked Moved Solved QML and Qt Quick
6 Posts 4 Posters 1.1k 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.
  • M Offline
    M Offline
    maxwell31
    wrote on last edited by maxwell31
    #1

    Hi,

    I have a

    QList<QObject*> _mylist;
    

    which I display in a TableView. To get the model for the TableView I did

    _engine->rootContext()->setContextProperty("myList", QVariant::fromValue(_myList));
    

    This is working fine, in principle. However, when I add new elements via

    _myList.push_back(new MyItem(...));
    

    I need to update the model. How is this done correctly? Right now I simply called

    _engine->rootContext()->setContextProperty("myList", QVariant::fromValue(_myList));
    

    again. However, with this approach, I also get error messages of this type:

    qrc:/Screen.qml:158: TypeError: Cannot read property 'firstProperty' of null
    

    Still, the new content gets displayed.
    Thanks for your help!

    DiracsbracketD 1 Reply Last reply
    0
    • M maxwell31

      Hi,

      I have a

      QList<QObject*> _mylist;
      

      which I display in a TableView. To get the model for the TableView I did

      _engine->rootContext()->setContextProperty("myList", QVariant::fromValue(_myList));
      

      This is working fine, in principle. However, when I add new elements via

      _myList.push_back(new MyItem(...));
      

      I need to update the model. How is this done correctly? Right now I simply called

      _engine->rootContext()->setContextProperty("myList", QVariant::fromValue(_myList));
      

      again. However, with this approach, I also get error messages of this type:

      qrc:/Screen.qml:158: TypeError: Cannot read property 'firstProperty' of null
      

      Still, the new content gets displayed.
      Thanks for your help!

      DiracsbracketD Offline
      DiracsbracketD Offline
      Diracsbracket
      wrote on last edited by Diracsbracket
      #2

      @maxwell31
      According to the Qt doc:
      http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html
      your approach of re-using setContextProperty() to update the view is correct:

      Note: There is no way for the view to know that the contents of a QList has changed. 
      If the QList changes, it is necessary to reset the model by calling
      QQmlContext::setContextProperty() again.
      

      To avoid the typeError warning you can check whetherobject is null before you try to use its firstProperty property, e.g.:

         someBinding: object ? object.firstProperty : someDefaultValue
      

      Or you should defer using the object until you are sure the object has been created, e.g. using Component.onCompleted etc...

      To be honest, I also still struggle with QML's object creation order issues like this, especially when the layout has multiple model-based views which depend on each other.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        maxwell31
        wrote on last edited by
        #3

        Thanks for your post. The errors come from the TableViewColumns. If I modify them according to your suggestion

          TableViewColumn {
            width: 80
            title: "property"
            delegate: Text{
              text: model ? model.firstProperty.toFixed(2):""
            }
          }
        

        The errors disappear. I guess using onComponentCompleted is not possible here, as the model already was present before calling setContextProperty again? So there is no other solution for this than checking for null?

        J.HilkJ 1 Reply Last reply
        0
        • M maxwell31

          Thanks for your post. The errors come from the TableViewColumns. If I modify them according to your suggestion

            TableViewColumn {
              width: 80
              title: "property"
              delegate: Text{
                text: model ? model.firstProperty.toFixed(2):""
              }
            }
          

          The errors disappear. I guess using onComponentCompleted is not possible here, as the model already was present before calling setContextProperty again? So there is no other solution for this than checking for null?

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @maxwell31
          well, instead of setting the List directly as a context property, you could wrap it in a Qobject based class and make the List available via Q_Property macro

          Q_PROPERTY(QVariant myModel READ myModel NOTIFY myModelChanged)
          

          Now, when you emit myModelChanged(), the QML part will update itself


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          A 1 Reply Last reply
          5
          • M Offline
            M Offline
            maxwell31
            wrote on last edited by
            #5

            Good idea

            1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @maxwell31
              well, instead of setting the List directly as a context property, you could wrap it in a Qobject based class and make the List available via Q_Property macro

              Q_PROPERTY(QVariant myModel READ myModel NOTIFY myModelChanged)
              

              Now, when you emit myModelChanged(), the QML part will update itself

              A Offline
              A Offline
              AlfreddGco
              wrote on last edited by
              #6

              @J-Hilk I think this would represent a problem anyways, because if you use the list in a repeater, QML is still not able to know when it changes so the first approach would need to be implemented again. Even if I call "emit myModelChanged", it doesn't work. It seems that the dataModel only updates with the emit when the size changes... so I remove the last element, emit de change, add it back, and emit again.

              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