How to populate my ListView from a slot?



  • Hello,
    I'm not sure it's the right approach as I'm new in Qt and I couldn't find a similar example but I tried to do a bit like 'abstractitemmodel' example.

    The difference is that I don't access the ui from main but from a slot and so, I don't understand how to get my ListView

    I have the following QML file:

    Item {
        id: programsScreen
        ...
        ScrollView {
            id: avalaiblePrograms
            ...
            ListView {
                id: avalaibleProgramsList
                anchors.fill: parent
    
                Component.onCompleted: {
                    qmlApi.availableProgramsReadySlot(avalaibleProgramsList)
                }
    
                model: programsModel
                delegate: Text {
                    text: "name " + name + "image released " + imageReleased + "image pressed " + image_pressed
                }
            }
        }
    }
    

    And my slot code is:

    void QML_API::availableProgramsReadySlot(const QVariant &v) {
    
        qDebug() << "Called the availableProgramsReadySlot with value:" << v;
    
        ProgramsModel programs;
        programs.addProgram(Program("Female"));
        programs.addProgram(Program("Male"));
    
        QQuickView *view = qobject_cast<QQuickView*>(v.value<QObject*>());;
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        QQmlContext *ctxt = view->rootContext();
        ctxt->setContextProperty("programsModel", &programs);
    }
    

    As soon as availableProgramsReadySlot() is called, I get a wonderfull crash!

    How to correctly get my ListView?

    Al



  • The "model:" has to be persistent. Create it somewhere before you load that qml file and make sure it is available for the life of the qml instance. Many qml apps create any context variables before running any qml that depends upon it.

    In your example you are not just not providing a persistent "programsModel" you are creating one on the stack in a function. Once that function exits the object is destroyed and if the qml found the object then it is accessing bad memory.

    I would create the ProgramsModel programs; somewhere in main or a function called in main. Do NOT create this on the stack inside a function. Use new to create it and reference that object somewhere if created in a function. Then reference that object in calls to add/remove/etc the data in the model. You can even create calls on the object itself that would allow you to maintain items in the list via qml functions if desired.



  • @fcarney
    Yes, you are right, I didn't really take care about this mistake….

    Anyway I still get crashed, maybe by Something different now but I'm not really sure as I didn't really investigate about where it came from before.

    Now I now it more precisely:

    My QML is:

        …
    
        ScrollView {
            id: availablePrograms
            y: 504
            height: 168
            anchors.right: parent.right
            anchors.left: parent.left
    
            ListView {
                id: availableProgramsList
                anchors.fill: parent
    
                Component.onCompleted: {
                    qmlApi.availableProgramsReadySlot(availableProgramsList)
                }
    
                model: programsModel
                delegate: Text {
                    text: "name " + name + "image released " + imageReleased + "image pressed " + image_pressed
                }
            }
        }
    
    

    So when qmlApi.availableProgramsReadySlot() gets called, I execute the following code:

    void QML_API::availableProgramsReadySlot(const QVariant &v) {
    
        qDebug() << "Called the availableProgramsReadySlot with value:" << v;
    
        …
        QQuickView *view = qobject_cast<QQuickView*>(v.value<QObject*>());;
        
        qDebug() << "get ctx " << view;
        // which displays  "get ctx  QQuickWindow(0)"
    
        QQmlContext *ctxt = view->rootContext();
        qDebug() << "setContextProperty";
        ctxt->setContextProperty("programsModel", &programs);
    
    }
    

    Which means that I cannot get a QQuickView from the availableProgramsList id I pass as parameter from QML.
    This is what I didn't understand in QML/C++ binding.
    In fact I tried to do what is explaiend here https://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#connecting-to-qml-signals

    Alain


Log in to reply