0
votes

I have Foo class which is derived from QAbstractListModel. And Bar class which I register and create in qml. Bar class holds Foo object exposed as property.

class Foo : public QAbstractListModel
{
    Q_OBJECT
public:
    explicit Foo(QObject *parent = nullptr) : QAbstractListModel(parent) {
        mList.append("test1");
        mList.append("test2");
        mList.append("test3");
    }

    virtual int rowCount(const QModelIndex &parent) const Q_DECL_OVERRIDE {
        return mList.count();
    }
    virtual QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE {
        return mList.at(index.row());
    }
private:
    QStringList mList;
};

class Bar : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(Foo* foo READ foo NOTIFY fooChanged)

public:
    explicit Bar(QQuickItem *parent = nullptr)
        : QQuickItem(parent) {
        mFoo = new Foo(this);
    }

    Foo *foo() const { return mFoo; }

signals:
    void fooChanged(Foo *foo);

private:
    Foo *mFoo;
};

Register Bar type:

qmlRegisterType<Bar>("Custom", 1, 0, "Bar");

qml:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import Custom 1.0

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

    ListView {
        id: someList
        model: bar.foo
        delegate: Text {
            text: modelData
        }
    }

    Bar {
        id: bar
    }
}

I create ListView and assign model Foo. Expected result is to see delegate text filled with "test1", "test2", "test3" but I get this:

ReferenceError: modelData is not defined
ReferenceError: modelData is not defined
ReferenceError: modelData is not defined
1

1 Answers

3
votes

QML engine is right, modelData is not defined. Within a delegate, model is defined not modelData.

Also since in your QAbstractListModel you've not defined your own roles, you can use default roles. display is a default role you can use it. So, your ListView should look like this:

ListView {
    id: someList
    model: bar.foo
    delegate: Text {
        text: model.display
    }
}