diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp index 00526dd5bf1..604b4a19c69 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.cpp +++ b/src/corelib/itemmodels/qabstractitemmodel.cpp @@ -2660,6 +2660,7 @@ QHash QAbstractItemModel::roleNames() const { // if the return value ever becomes dependent on *this, also change the following overrides: // - QFileSystemModel + // - QConcatenateTablesProxyModel return QAbstractItemModelPrivate::defaultRoleNames(); } diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp index db1e041137f..a328a229f96 100644 --- a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp +++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp @@ -61,6 +61,7 @@ public: ConnArray connections; }; QList m_models; + mutable QHash m_roleNames; QList::const_iterator findSourceModel(const QAbstractItemModel *m) const { @@ -77,6 +78,9 @@ public: // for columns{AboutToBe,}{Inserted,Removed} int m_newColumnCount; + mutable uint m_roleNamesDirty : 1; + uint m_reserved : 31; + // for layoutAboutToBeChanged/layoutChanged QList layoutChangePersistentIndexes; QList layoutChangeProxyIndexes; @@ -85,7 +89,9 @@ public: QConcatenateTablesProxyModelPrivate::QConcatenateTablesProxyModelPrivate() : m_rowCount(0), m_columnCount(0), - m_newColumnCount(0) + m_newColumnCount(0), + m_roleNamesDirty(true), + m_reserved(0) { } @@ -507,6 +513,12 @@ void QConcatenateTablesProxyModel::addSourceModel(QAbstractItemModel *sourceMode QObjectPrivate::connect(sourceModel, &QAbstractItemModel::modelReset, d, &QConcatenateTablesProxyModelPrivate::slotModelReset), }); + if (!d->m_roleNamesDirty) { + // do update immediately, since append() is a simple update: + const auto newRoleNames = sourceModel->roleNames(); + for (const auto &[k, v] : newRoleNames.asKeyValueRange()) + d->m_roleNames.insert_or_assign(k, v); + } if (newRows > 0) endInsertRows(); @@ -533,6 +545,7 @@ void QConcatenateTablesProxyModel::removeSourceModel(QAbstractItemModel *sourceM if (rowsRemoved > 0) beginRemoveRows(QModelIndex(), rowsPrior, rowsPrior + rowsRemoved - 1); d->m_models.erase(it); + d->m_roleNamesDirty = true; d->m_rowCount -= rowsRemoved; if (rowsRemoved > 0) endRemoveRows(); @@ -551,10 +564,13 @@ void QConcatenateTablesProxyModel::removeSourceModel(QAbstractItemModel *sourceM QHash QConcatenateTablesProxyModel::roleNames() const { Q_D(const QConcatenateTablesProxyModel); - QHash ret = QAbstractItemModel::roleNames(); - for (const auto &[model, _] : d->m_models) - ret.insert(model->roleNames()); - return ret; + if (d->m_roleNamesDirty) { + d->m_roleNames = QAbstractItemModelPrivate::defaultRoleNames(); + for (const auto &[model, _] : d->m_models) + d->m_roleNames.insert(model->roleNames()); + d->m_roleNamesDirty = false; + } + return d->m_roleNames; } void QConcatenateTablesProxyModelPrivate::slotRowsAboutToBeInserted(const QModelIndex &parent,