diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2018-08-01 22:53:17 +0200 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2018-08-02 15:53:58 +0000 |
commit | fe1a259be66835bc937890f3ed62bb2e8496d0f1 (patch) | |
tree | 12453b09306764e679cb45af9de417c38101f572 /src/qml/types | |
parent | e997cd013a665505bd2d33a3e4b76e27752bcb39 (diff) |
QQmlTableInstanceModel: handle model data changes more gracefully
Equal to QQmlDelegateModel, we need to listen for changes done to
existing model items, and notify existing delegate items about it.
Otherwise, they will not stay in sync with the model.
By accident, this sort of worked in QQuickTableView already, since
it would rebuild the whole table for every model update. This
is really slow, and completely unnecessary.
Change-Id: I10750ff387f8b455d0f27c50a17926d9beb6dd03
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/qml/types')
-rw-r--r-- | src/qml/types/qqmltableinstancemodel.cpp | 19 | ||||
-rw-r--r-- | src/qml/types/qqmltableinstancemodel_p.h | 2 |
2 files changed, 21 insertions, 0 deletions
diff --git a/src/qml/types/qqmltableinstancemodel.cpp b/src/qml/types/qqmltableinstancemodel.cpp index 6604e009c1..536dd46182 100644 --- a/src/qml/types/qqmltableinstancemodel.cpp +++ b/src/qml/types/qqmltableinstancemodel.cpp @@ -437,7 +437,26 @@ void QQmlTableInstanceModel::setModel(const QVariant &model) // needs to stay in sync with the model. So we need to drain the pool // completely when the model changes. drainReusableItemsPool(0); + if (auto const aim = abstractItemModel()) + disconnect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback); m_adaptorModel.setModel(model, this, m_qmlContext->engine()); + if (auto const aim = abstractItemModel()) + connect(aim, &QAbstractItemModel::dataChanged, this, &QQmlTableInstanceModel::dataChangedCallback); +} + +void QQmlTableInstanceModel::dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles) +{ + // This function is called when model data has changed. In that case, we tell the adaptor model + // to go through all the items we have created, find the ones that are affected, and notify that + // their model data has changed. This will in turn update QML bindings inside the delegate items. + int numberOfRowsChanged = end.row() - begin.row() + 1; + int numberOfColumnsChanged = end.column() - begin.column() + 1; + + for (int column = 0; column < numberOfColumnsChanged; ++column) { + const int columnIndex = begin.column() + column; + const int rowIndex = begin.row() + (columnIndex * rows()); + m_adaptorModel.notify(m_modelItems.values(), rowIndex, numberOfRowsChanged, roles); + } } QQmlComponent *QQmlTableInstanceModel::delegate() const diff --git a/src/qml/types/qqmltableinstancemodel_p.h b/src/qml/types/qqmltableinstancemodel_p.h index 23243e7f0e..71689ce6da 100644 --- a/src/qml/types/qqmltableinstancemodel_p.h +++ b/src/qml/types/qqmltableinstancemodel_p.h @@ -142,6 +142,8 @@ private: void deleteAllFinishedIncubationTasks(); QQmlDelegateModelItem *resolveModelItem(int index); + void dataChangedCallback(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles); + static bool isDoneIncubating(QQmlDelegateModelItem *modelItem); static void deleteModelItemLater(QQmlDelegateModelItem *modelItem); |