QML view wont update when adding a new item to a QAbstractListModel based model

c++, qabstractitemmodel, qml, qt, qt-quick

Solution

you should call `beginInsertRows` and `endInsertRows` instead of emitting the signal

void SimpleListModel::addName(QString firstName, QString lastName)
{
    DataObject *dataObject = new DataObject(firstName, lastName);

    // tell QT what you will be doing
    beginInsertRows(ModelIndex(),m_items.size(),m_items.size());

    // do it
    m_items.append(dataObject);

    // tell QT you are done
    endInsertRows();

}

these 2 functions emit all needed signals

Problem

I've figured out how to bind a model derived from QAbstractListModel to a QML view. But the next thing I tired does not work. If a new Item is added to the model the QML view will not update. Why is that? DataObject.h ``` class DataObject { public: DataObject(const QString &firstName, const QString &lastName): first(firstName), last(lastName) {} QString first; QString last; }; ``` SimpleListModel.h ``` class SimpleListModel : public QAbstractListModel { Q_OBJECT enum /*class*/ Roles { FIRST_NAME = Qt::UserRole, LAST_NAME }; public: SimpleListModel(QObject *parent=0); QVariant data(const QModelIndex &index, int role) const; Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const; QHash<int, QByteArray> roleNames() const; void addName(QString firstName, QString lastName); private: Q_DISABLE_COPY(SimpleListModel); QList<DataObject*> m_items; }; ``` SimpleListModel.cpp ``` SimpleListModel::SimpleListModel(QObject *parent) : QAbstractListModel(parent) { DataObject *first = new DataObject(QString("Firstname01"), QString("Lastname01")); DataObject *second = new DataObject(QString("Firstname02"), QString("Lastname02")); DataObject *third = new DataObject(QString("Firstname03"), QString("Lastname03")); m_items.append(first); m_items.append(second); m_items.append(third); } QHash<int, QByteArray> SimpleListModel::roleNames() const { QHash<int, QByteArray> roles; roles[/*Roles::*/FIRST_NAME] = "firstName"; roles[/*Roles::*/LAST_NAME] = "lastName"; return roles; } void SimpleListModel::addName(QString firstName, QString lastName) { DataObject *dataObject = new DataObject(firstName, lastName); m_items.append(dataObject); emit dataChanged(this->index(m_items.size()), this->index(m_items.size())); } int SimpleListModel::rowCount(const QModelIndex &) const { return m_items.size(); } QVariant SimpleListModel::data(const QModelIndex &index, int role) const { //--- Return Null variant if index is invalid if(!index.isValid()) return QVariant(); //--- Check bounds if(index.row() > (m_items.size() - 1)) return QVariant(); DataObject *dobj = m_items.at(index.row()); switch (role) { case /*Roles::*/FIRST_NAME: return QVariant::fromValue(dobj->first); case /*Roles::*/LAST_NAME: return QVariant::fromValue(dobj->last); default: return QVariant(); } } ``` AppCore.h ``` class AppCore : public QObject { Q_OBJECT Q_PROPERTY(SimpleListModel *simpleListModel READ simpleListModel CONSTANT) public: explicit AppCore(QObject *parent = 0); SimpleListModel *simpleListModel() const; public slots: void addName(); private: SimpleListModel *m_SimpleListModel; }; ``` AppCore.cpp ``` AppCore::AppCore(QObject *parent) : QObject(parent) { m_SimpleListModel = new SimpleListModel(this); } SimpleListModel *AppCore::simpleListModel() const { return m_SimpleListModel; } void AppCore::addName() { m_SimpleListModel->addName("FirstnameNEW", "LastnameNEW"); } ``` main.cpp ``` int main(int argc, char *argv[]) { QGuiApplication a(argc, argv); QQuickView *view = new QQuickView(); AppCore *appCore = new AppCore(); qRegisterMetaType<SimpleListModel *>("SimpleListModel"); view->engine()->rootContext()->setContextProperty("appCore", appCore); view->setSource(QUrl::fromLocalFile("main.qml")); view->show(); return a.exec(); } ``` main.qml ``` // ... ListView { id: myListView anchors.fill: parent delegate: myDelegate model: appCore.simpleListModel } MouseArea { anchors.fill: parent onClicked: { appCore.addName() console.log('rowCount: ' + appCore.simpleListModel.rowCount()) } } //... ```

Original source