QSortFilterProxyModel и свойство dynamicSortFilter - PullRequest
1 голос
/ 05 мая 2020

Я использую QSortFilterProxyModel, а свойство dynamicSortFilter не работает.

// main.cpp
QSortFilterProxyModel carsProxyModel;
carsProxyModel.setSourceModel(&carsModel);
carsProxyModel.setDynamicSortFilter(false); // whatever its true or false, it does not change the behavior

На стороне QML у меня есть 2 ListView, один для исходной модели и один для прокси, и они отображают список автомобилей таким же образом.

Когда исходная модель перевернута:

// carmodel.cpp
void CarModel::reverseModel()
{
    beginResetModel();
    std::reverse(m_carItems.begin(), m_carItems.end());
    endResetModel();
}

Оба представления показывают перевернутый список автомобилей, и это то, что я ожидаю, когда dynamicSortFilter истинно, но не тогда, когда его ложь (https://doc.qt.io/qt-5/qsortfilterproxymodel.html#dynamicSortFilter -prop ), на самом деле оба значения всегда приводят к изменению в представлении прокси.

Возможно, я не использую право собственности, но я пока не вижу ничего другого.

Когда исходная модель перевернута - я не хочу видеть изменения в представлении прокси, только в исходном представлении. Возможно ли это?

Надеюсь, этот вопрос ясен, я попытался извлечь наиболее важные части, потому что кодовая база слишком длинная, чтобы ее можно было здесь разместить.

Спасибо.

РЕДАКТИРОВАТЬ:

Небольшой пример:

если прокси-представление отсортировано по «марке автомобиля» (QString), то изменение исходной модели будет обратный порядок автомобилей той же марки, но сортировка или фильтрация обычно сохраняется (для автомобилей разных марок)

Ответы [ 2 ]

2 голосов
/ 05 мая 2020

Как упоминалось в @ypnos, сортировка Dynami c влияет только при вызове прокси sort. Если это true, он будет автоматически вызываться при изменении исходной модели. Это не влияет на сортировку объектов; это зависит от вашей реализации

Однако я прочитал в вашем вопросе, что у вас есть 2 представления в 1 списке, которые необходимо отсортировать по-разному. Я предлагаю вам использовать 2 различных QProxyFilterModels, по одному для каждого представления, и вообще не обрабатывать сортировку в базовой модели.

«Обратная» модель могла бы просто изменить порядок исходного списка путем сопоставления пункты в обратном порядке:

QModelIndex ReverseProxyModel::mapFromSource(const QModelIndex &sourceIndex) const {
    if (reversed) {
        return createIndex(sourceModel()->rowCount() - sourceIndex.row(), sourceIndex.column());
    } else {
        return createIndex(sourceModel()->rowCount(), sourceIndex.column());
    }
}

// Similar for mapToSource
2 голосов
/ 05 мая 2020

Итак, проблема здесь в том, что вы хотите контролировать общий порядок элементов, а не только то, как они упорядочены в соответствии с DisplayRole. Вам необходимо сделать так, чтобы прокси-модель знала ваш общий порядок, который включает несколько атрибутов элементов.

Как объясняется в документации :

Пользовательская сортировка поведение достигается путем создания подкласса QSortFilterProxyModel и повторной реализации lessThan (), который используется для сравнения элементов.

Свойство сортировки Dynami c не выполняет то, что вы думаете. На самом деле это триггер sort() на прокси-модели при изменении исходной модели. Но сортировщик по умолчанию для QStrings не изменит порядок элементов, которые для него выглядят одинаково (это так называемый стабильный сортировщик ). Даже если бы это был нестабильный сортировщик, вы бы получили в основном случайное перемешивание элементов в лучшем случае после каждого изменения исходной модели.

Обратите внимание, что вы не можете предотвратить распространение изменений в исходном порядке напрямую через прокси; вам нужно подавить их, предоставив сортировщик, который полностью контролирует порядок. Таким образом, lessThan() учитывает марку автомобиля, марку, цвет и т. Д. c. В качестве альтернативы вы можете сохранить начальный индекс каждого элемента и использовать его в качестве вторичного ключа при сортировке по бренду. Итак, в основном:

if (a.brand == b.brand)
    return a.index < b.index;
return a.brand < b.brand;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...