1
votes

I have a Q_PROPERTY of type QList<QString> in a c++ class that is not being shown in QML. The class looks like this:

class FooView : public QQuickItem
{
    Q_OBJECT;
    Q_PROPERTY(QList<QString> myStrings READ myStrings NOTIFY myStringsChanged);

private:
    QList<QString> m_strings;

public:
    FooView(QQuickItem * parent) : QQuickItem(parent), m_strings() {
        m_strings << "String one" << "String two";
    }

    QList<QString> myStrings() const {
        return m_strings;
    }

signals:
    void myStringsChanged();
};

The above class is registered as a QML type using qmlRegisterType. I try to use the property as a model to a ListView like so:

FooView {
    id: 'foo'
    ListView {
        anchors.fill: parent
        model: foo.myStrings
        delegate: Text {
            text: "Hi" // to be replaced with foo.myStrings[index]
        }
    }
}

Can you not use QList<QString>'s as models? I thought you could since it was listed as a simple list type.

1
m_strings()? in the constructor.Phiber
m_string() override your m_strings << "String one" << "String two"; so your are using empty listPhiber
@Phiber m_strings << "String one" << "String two"; it runs after m_string(), although m_string() is unnecessary because a list is empty by defaulteyllanesc

1 Answers

2
votes

First use QStringList instead of QList<QString>:

class FooView : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QStringList myStrings READ myStrings NOTIFY myStringsChanged)
    QStringList m_strings;
public:
    FooView(QQuickItem * parent=nullptr) :
        QQuickItem(parent)
    {
        m_strings << "String one" << "String two";
    }
    QStringList myStrings() const {
        return m_strings;
    }
signals:
    void myStringsChanged();
};

And going to the problem, you must use modelData when the model is a list as indicated by the docs:

Models that do not have named roles (such as the ListModel shown below) will have the data provided via the modelData role. The modelData role is also provided for models that have only one role. In this case the modelData role contains the same data as the named role.


FooView {
    id: foo
    anchors.fill: parent
    ListView {
        anchors.fill: parent
        model: foo.myStrings
        delegate: Text {
            text: modelData
        }
    }
}