Прокси-модели используют индексы модели источника для получения своих индексов с помощью метода QAbstractProxyModel::mapToSource
. В итоге если в прокси-модели индексов больше чем в модели источнике, то индексы не присутствующие в модели-источнике будут вести себя некорректно.
Для корректной работы Вам нужно переопределить методы:
QModelIndex TableModel::mapToSource(const QModelIndex& proxyIndex) const
{
if (proxyIndex.row() >= sourceModel()->rowCount()) {
return createIndex(proxyIndex.row(), proxyIndex.column());
}
return QSortFilterProxyModel::mapToSource(proxyIndex);
}
QModelIndex TableModel::index(int row, int column, const QModelIndex& parent) const
{
if (row >= sourceModel()->rowCount()) {
return createIndex(row, column);
}
return QSortFilterProxyModel::index(row, column, parent);
}
Qt::ItemFlags TableModel::flags(const QModelIndex& index) const
{
if (index.row() >= sourceModel()->rowCount()) {
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren;
}
return QSortFilterProxyModel::flags(index);
}
Помимо этого нужно заметить, что помимо mapToSource
QSortFilterProxyModel
использует скрытую от пользователя функцию index_to_iterator
для ускорения многих операций. Она работает на основе internalPointer
-а индекса, который у нас для row >= sourceModel()->rowCount()
равен nullptr
. (Мы использовали QAbstractItemModel::createIndex
). По этой причине нам нужно переопределить методы, которые могут использовать данную функцию на наших добавочных индексах (Как правило в других прокси-моделях их тоже необходимо переопределять, но по другим причинам):
QModelIndex TableModel::parent(const QModelIndex& child) const
{
return QModelIndex(); //Мы знаем, что работаем с таблицей
}
QModelIndex TableModel::sibling(int row, int column, const QModelIndex& idx) const
{
if (row >= sourceModel()->rowCount()) {
return createIndex(row, column);
}
return QSortFilterProxyModel::sibling(row, column, idx);
}
Замечу, что помимо этих мест, index_to_iterator
неявно вызывается в приватном методе QSortFilterProxyModelPrivate::needsReorder
, на который мы повлиять не можем, а потому я не могу предсказать насколько корректно будет работать сортировка модели (это я не тестировал). Однако, я бы в любом случае порекомендовал вам использовать QSortFilterProxyModel
исключительно для вопросов фильтрации и сортировки, а дополнительные строки добавлять через ещё одну прокси-модель наследуемую от QIdentityProxyModel
.
Обратите внимание, что я предполагал использование таблиц. Для деревьев всё немного сложнее.