Russian Qt Forum

Qt => Model-View (MV) => Тема начата: Akon от Декабрь 31, 2012, 08:29



Название: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Akon от Декабрь 31, 2012, 08:29
Цитировать
Property Documentation

dynamicSortFilter : bool
This property holds whether the proxy model is dynamically sorted and filtered whenever the contents of the source model change.

Note that you should not update the source model through the proxy model when dynamicSortFilter is true. For instance, if you set the proxy model on a QComboBox, then using functions that update the model, e.g., addItem(), will not work as expected. An alternative is to set dynamicSortFilter to false and call sort() after adding items to the QComboBox.

The default value is false.

This property was introduced in Qt 4.2.

Проще говоря, когда данные меняются (добавляются или редактируются через прокси-модель), то при установленном dynamicSortFilter обновления прокси-модели не происходит.

Я имею ТрееВью с прокси-моделью. Сортировка пользователю через ТрееВью не доступна (QTreeView::setSortingEnabled(false)), вместо этого порядок сортировки задан в коде через QSortFilterProxyModel::sort(). Пользователь изменяет данные через ТрееВью, сортировка не работает (как и описано в справке). Я должен отлавливать сигналы изменения исходной модели (dataChanged, rowInserted и т.п.) и делать QSortFilterProxyModel::sort()? Как вы решали эту задачу? Почему проблема не снимается непосредственно в QSortFilterProxyModel, dynamicSortFilter название то характерное?

Всех с Наступающим!


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Bepec от Декабрь 31, 2012, 10:48
С новым.

Когда я пробовал, никак. Пытался проводить динамическую сортировку. В результате пришёл к выводу, что время на сортировку большой модели убивает всю полезность.

PS в конце концов отказался от неё.


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Akon от Декабрь 31, 2012, 18:45
При сортировке по одной колонке, dynamicSortFilter() работает корректно. В моем случае я сортировал по нескольким столбцам с помощью lessThen(), при этом в прокси-модели у меня стояла первая колонка сортировки. Данные менялись в другой колонке, входящей в сортировку, и прокси-модель, отслеживая эти изменения, не обновляля свой марринг индексов (с точки зрения QSortFilterProxyModel колонка то сортировки другая, и изменение никак не может повлиять на сортировку). Мое решение навскидку: в наследнике QSortFilterProxyModel отслеживаются сигналы исходной модели и вызывается sort().

Вопрос Пантеру: в вашем решении по множественной сортировке как решается эта проблема.


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Igors от Декабрь 31, 2012, 18:58
Вопрос Партеру: в вашем решении по множественной сортировке как решается эта проблема.
Не знаю кто/что "Партер", но в любом случае "множественная сортировка" весьма мутный термин. Сортировка всегда "одномерна". Может быть задействовано любое число ключей, но в любом случае сначала вычисляется/сравнивается первый. Только если первые ключи равны - используется второй и.т.д. Конечно Вам это прекрасно известно - ну так формулируйте четче  :)



Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Akon от Январь 02, 2013, 09:25
Под множественной сортировкой я, конечно же, имел ввиду сортировку по урорядоченному множеству столбцов, т.е. по составному ключу. Прошу прощения за неоднозначную (или непонятную) формулировку.


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Igors от Январь 02, 2013, 11:25
Трудновато осмыслить как это должно быть для ТрееВью. Можно небольшой проект?


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: twp от Январь 03, 2013, 00:51
Да, как указал Верес, при больших объемах данных пересортировка модели при изменении/добавлении может привести к большим издержкам и самый оптимальный способ - это найти строку в прокси модели, куда должна переместиться существующая или вставиться новая строка. Поскольку данные в модели уже отсортированы, то это можно довольно быстро сделать бинарным поиском.


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Akon от Январь 03, 2013, 08:04
Цитировать
Трудновато осмыслить как это должно быть для ТрееВью. Можно небольшой проект?
Basic Sort/Filter Model Example.
Например, есть две колонки, сортируем по ключу: колонка #0, колонка #1. Кьютовые модели позволяют сортировку только по одной колонке, например, если отсортируем по колонке #0, то в случае равенства значений порядок записей не определяется значениями колонки #1.

Цитировать
Да, как указал Верес, при больших объемах данных пересортировка модели при изменении/добавлении может привести к большим издержкам и самый оптимальный способ - это найти строку в прокси модели, куда должна переместиться существующая или вставиться новая строка. Поскольку данные в модели уже отсортированы, то это можно довольно быстро сделать бинарным поиском.
А реально из-за чего тормоз знаете?


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Bepec от Январь 03, 2013, 09:41
Из-за пересортировки.

Как я подозреваю, при добавлении каждой записи производится сравнение всех строк и соответственно сортировка. При объёме в миллион добавление одной строки тормозит где то на секунды 4-6. Давно уже было, точную цифру назвать сложно.
Но при добавлении группы записей и сортировки раз в 25 м/с модель тормозит всю программу и не оживает.


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: Igors от Январь 04, 2013, 09:23
Basic Sort/Filter Model Example.
Например, есть две колонки, сортируем по ключу: колонка #0, колонка #1. Кьютовые модели позволяют сортировку только по одной колонке, например, если отсортируем по колонке #0, то в случае равенства значений порядок записей не определяется значениями колонки #1.
Перекрываем lessThan, подаваемые в него QModelIndex содержат номера оригинальных строк. По модели извлекаем данные для доп столбцов и используем


Название: Re: QSortFilterProxyModel::dynamicSortFilter
Отправлено: GreatSnake от Январь 04, 2013, 13:19
Для всех вью использующих QStandardItemModel можно через
Код
C++ (Qt)
void QStandardItemModel::setItemPrototype ( const QStandardItem * item )
установить прототип с перегруженным operator<.
Имхо, всё будет проще и даже быстрее, чем возня с прокси.