Qt World Summit: Register Today!

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

  • 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!

  • @maxwell31
    According to the Qt doc:
    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.

  • 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?

  • Moderators

    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

  • Good idea

  • @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.

Log in to reply