0
votes

I am trying to populate a QML ListView using a class that inherits QAbstractListModel. So far, I managed to create this using the QT Documentation here, under the "QAbstractItemModel subclass" section:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include <QQmlContext>
#include "gamemodel.h"  

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    GameModel model;    //A class similar to AnimalModel in Qt Documentation.
                        //It contains a QList of Objects, each having 2 QString
                        //members (title and genre).

    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    model.readFile("c:/somePath/XML_G.xml"); //Initializing GameModel QList member 
                                             //using an XML file

    QQmlContext *ctxt = engine.rootContext();
    ctxt->setContextProperty("myModel", &model);

    return app.exec();
}

main.qml

import QtQuick 2.5
import QtQuick.Window 2.2

Window
{
    id: win
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")


    ListView
    {
        id: myList
        width: parent.width
        height: 50

        clip: true
        spacing: 5
        orientation: ListView.Horizontal
        model: myModel
        delegate:
        Rectangle
        {
            width: 150
            height: 20
            color: "#2255ff"

            Text
            {
                text: gameTitle + " " + genre
            }

        }
    }

} 

Up to this point, my code works. However, if I try to change my main.qml file like this:

import QtQuick 2.5
import QtQuick.Window 2.2

Window
{
    id: win
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Item    //ListView is now nested in this Item
    {

        ListView
        {
            id: myList
            width: parent.width
            height: 50

            clip: true
            spacing: 5
            orientation: ListView.Horizontal
            model: myModel
            delegate:
            Rectangle
            {
                width: 150
                height: 20
                color: "#2255ff"

                Text
                {
                    text: gameTitle + " " + genre
                }

            }
        }
    }

} 

I end up being unable to set my model using ctxt->setContextProperty("myModel", &model);. From what little I can gather from the Qt Documentation (although I am most likely wrong), QQmlContext acts like a scope for the QML file. Thinking that, I tried changing this:

QQmlContext *ctxt = engine.rootContext();

to this:

QQmlContext *ctxt = engine.rootContext()->findChild<QQmlContext*>("list");

As well as setting my Item's objectName property to "list". Obviously, that failed, and it also caused a crash. Since my experience with QML is limited to the Qt Docs, I have been unsuccessful at finding a workaround. Is a solution using QQmlContext possible, or do I have to use QObject? If so, what would the QObject equivalent of ctxt->setContextProperty("myModel", &model) be?

2
Try doing QQmlContext *ctxt = engine.rootContext(); ctxt->setContextProperty("myModel", &model); before engine.load(). Eg right after you define your model before you load the view.arynaq
My code above works normally. What I want to do is access a ListView nested in another Item, which is where I am currently stuck.SASUPERNOVA

2 Answers

0
votes

The first argument of the setContextProperty() call is basically the "identifier" of the object, like the id property on the QML side.

You need to set that before accessing it in QML, otherwise it is unknown at the time of usage.

So you don't need any other call, but you need to do it before you load QML that needs it.

Just move it before the engine.load(...) line in your main.cpp

0
votes

OK, apparently my problem was in my QML file. In my code, I setup my ListView like this:

width: parent.width

However, when I added an Item as the parent of my ListView, I forgot to set an initial width for my Item, thus turning ListView's width to 0. After I set an initial width for my Item, everything works as expected again.