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

QmlListProperty access in javascript



  • Hi,
    I have a C++ class which contains a list of objects. I want this list to be accessible in my QML interface, so a defined a property of type QQmlListProperty. When using this property as the model of a listview, everythin works fine. However, if I try to use this list in a javascript function, I can't do anything - a basic call to count() returns 'undefined'.

    The following example may clarify why I'm trying to do :
    Here's my Bar class - a simple object with a single property returning a string :

    @class Bar : public QObject
    {
    Q_OBJECT
    public:
    explicit Bar(const QString& name, QObject *parent = 0) : QObject(parent), _name(name) {}
    explicit Bar(QObject *parent = 0) : QObject(parent), _name("") {}

    Q_PROPERTY(QString name READ name NOTIFY nameChanged)
    
    QString name() const {return _name;}
    

    signals:
    void nameChanged();
    private:
    QString _name;

    };@

    Here's my Foo class, which contains a list of Bars :
    @class Foo : public QObject
    {
    Q_OBJECT
    public:
    explicit Foo(QObject *parent = 0) : QObject(parent) {}

    void initBars()
    

    {
    _bars.append(new Bar("Banana"));
    _bars.append(new Bar("Apple"));
    _bars.append(new Bar("Raspberry"));
    Q_EMIT barsChanged();
    }

    Q_PROPERTY(QQmlListProperty<Bar> bars READ bars NOTIFY barsChanged)
    
    QQmlListProperty<Bar> bars() { return QQmlListProperty<Bar>(this, _bars);}
    

    signals:
    void barsChanged();
    public slots:

    private:
    QList<Bar*> _bars;
    };@

    Here my QML file - foo is a context property set in my main.cpp :
    @import QtQuick 2.2
    import QtQuick.Controls 1.1
    import test.Bar 1.0
    import test.Foo 1.0

    ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Foobar")

    ListView {
        model: foo.bars
        id: listView
        anchors.centerIn: parent
        anchors.fill: parent
    
        delegate: Row {
            id: row
            Text {
                text: name
            }
        }
    
    }
    
    Component.onCompleted: {
        console.log(foo.bars.count);
        for(var i = 0; i < foo.bars.count; i++)
            console.log(foo.bars.get(i).name)
    }
    

    }@

    And finally, here's my main :
    @int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    qmlRegisterType<Foo>("test.Foo", 1, 0, "Foo");
    qmlRegisterType<Bar>("test.Bar", 1, 0, "Bar");
    QQmlApplicationEngine engine;
    Foo myFoo;
    myFoo.initBars();
    engine.rootContext()->setContextProperty("foo", &myFoo);
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    return app.exec();
    

    }
    @

    When I launch this example, the listview is correctly filled with 3 items - Banana, Apple, Raspberry.
    However, the javascript function called on Component.onCompleted only displays "qml: undefined" in the console.
    What am I doing wrong ? how can I use my list in javascript ?

    Thank you for your answers.



  • Hi,

    The qmllistproperties work slightly in a different way than regular. You need to implement a number of static functions to get everything working. Check the documentation, it has examples to get you started!


Log in to reply