Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Newb: How to access C++ QAbstractListModel from child Qml item



  • Starting from Qt example "AbstractItemModel", then wrapping the root Qml ListView in an Item, ListView can no longer access the model, and I cannot figure out how to do it. I want to use models outside of the root Item.

    Error is:

    qrc:view.qml:55:1: Required property model was not initialized 
         ListView {
     
         ^ qrc:view.qml: 55
    

    Original QML:

    ListView {
        width: 200; height: 250
    
        required model
    
        delegate: Text {
            required property string type
            required property string size
    
            text: "Animal: " + type + ", " + size
        }
    }
    

    New QML:

    Item {
        ListView {
            width: 200; height: 250
        
            required model
            ...
        }
    }
    

    main() is:

        QQuickView view;
        view.setResizeMode(QQuickView::SizeRootObjectToView);
        view.setInitialProperties({{"model", QVariant::fromValue(&model)}});
        view.setSource(QUrl("qrc:view.qml"));
    


  • @Gordon-Smith

    Three changes helped in this case:

    • Use setContextProperty() instead of setInitialProperties()
    • Assign ListView model
    • Don't use "model" for model name.
        //view.setInitialProperties({{"model1", QVariant::fromValue(&model)}});
        view.rootContext()->setContextProperty("model1", &model);
    
        ListView {
        ...
            //required model
            model: model1
        ...
        }
    

  • Qt Champions 2018

    @Gordon-Smith said in Newb: How to access C++ QAbstractListModel from child Qml item:

    Use setContextProperty() instead of setInitialProperties()

    Don't use setContextProperty for new code
    use qmlRegisterSingletonInstance instead

    Your problem was that you set the model property of the Item, not the child ListView.

    You could have added an alias in Item : property alias model: idOfTheListView.model
    Or a property in Item and reference it in the ListView: model: idOfTheItem.model



  • @GrecKo Thank you for your response. I found your post about qmlregistersingletoninstance.

    You are right to comment, my problem is not solved. I cannot use models in my larger app.

    I understand what you are saying about properties, but I am unable to get it to work.

    I'm also unable to compile a Singleton at the moment, so I stay with setContextProperty() for this post.

        view.rootContext()->setContextProperty(QStringLiteral("animalModel"), &model);
    

    I try the following (A):

    Item {
        id: root
        property alias animalModel: listView.model
    
        ListView {
            id: listView
            delegate: Text { text: "Animal: " + type + ", " + size }
        }
    }
    

    Probably backwards-thinking on my part. There is no QML error, and the ListView is empty.

    Same result with (B):

    Item {
        id: root
    
        ListView {
            model: root.animalModel
            delegate: Text { text: "Animal: " + type + ", " + size }
        }
    }
    

    And (C):

    Item {
        id: root
        property alias animalModel2: animalModel
    
        ListView {
            id: listView
            model: root.animalModel2
            delegate: Text { text: "Animal: " + type + ", " + size }
        }
    }
    

    Error is: Invalid alias reference.​ Unable to find id "​animalModel"​

    I'm quite lost, obviously.



  • Setting the context property will make "animalModel" implicitly available in QML. In (A), your alias root.animalModel is shadowing your context property, which is why it doesn't work. Try this:

    Item {
        id: root
    
        ListView {
          id: listView
          model: animalModel
          delegate: Text { text: "Animal: " + type + ", " + size }
        }
    }
    

    Incidentally, I'm a huge fan of setContextProperty, as it behaves the same as the "dummydata" folder when using qmlscene.



  • @dgallagher219 Turns out, your suggestion still works! It's easy to get off track. Thanks.


Log in to reply