Страницы

Поиск по вопросам

суббота, 11 апреля 2020 г.

Как должны правильно взаимодействовать модель и QSortFilterProxyModel?

#cpp #qt #qt5 #qml

                    
Приветствую! 
Ситуация следующая:
Есть моделька, основанная на QAbstractItemModel, так как данных достаточно много,
получаю их с помощью предназначенного для этого canFetchMore и fetchMore
и когда просто модель отображается в ListView (qml), всё замечательно, данные подгружаются
по мере пролистывания.

Теперь на эту модельку сверху вешаю прокси, на основе QSortFilterProxyModel
в ней для теста отбираю строки (переопределив filterAcceptsRow) по какому нибудь
полю, не важно. 

Дальше начинаются проблемы. 
При установленной фильтрации во вьюшке выводятся не все возможные значения!
т.е. выводятся только загруженные в fetchMore в данный момент. 
Т.е. в fetchMore гружу по 100 записей, не выводятся ни одной, т.к. целевые значения
будут прогружены начиная с 500.
и прогрузки дальше не происходит т.к. логично, что вьюшка не считает необходимым
загружать ещё т.к. всё умещается и не надо пролистывать но и прокси моделька не считает
нужным прогрузить дальше, либо как-то сообщить основной модели - мне нужны записи с
вот такими значениями.

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

т.е. например я в fetchRow основной модели прогрузил записи от 0 до 100, в прокси
модели нужно выбирать, которые располагаются начиная с 500, ок, я говорю основной модели
- прогрузи ка записи с вот такими значенияи, если есть.
Ок, гружу. 

Но возникает следующая проблема - если запись например 555 добавлена в модель, то
при скролинге вьюшки, она попросит записи с 500 по 600 и я тогда снова добавлю запись
555. т.е. получается будет дублирование. 
Запоминать записи, которые грузил? что-то костылём попахивает. 
Может есть красивый выход из ситуации?

Спасибо, даже за подсказки, на что смотреть!
    


Ответы

Ответ 1



На мой взгляд, тут может быть только три варианта для решения проблемы. Первый - самый бестолковый, если данных очень много. Предполагает, что модель-источник должна загрузить сразу все данные и не использовать fetchMore в принципе. Второе решение может быть основано на переопределении метода fetchMore() у прокси с тем условием, что будет сразу же (рекурсивно) повторять запрос на чтение новых строк из исходной модели до тех пор, пока количество строк в прокси после filterAcceptsRow() не достигнет нужного числа, либо исходная модель не прочитает все данные. Фактически, это решение почти столь же бестолковое, что и первое, так как потребуется полное считывание всех данных исходной модели при определённых условиях фильтрации. Третье решение предполагает использование фильтрации данных непосредственно в модели-источнике. Обратите внимание, что все SQL-модели из состава Qt имеют возможность фильтровать данные самостоятельно и в общем случае не нуждаются в каких-либо прокси. Если модель-источник является таблицей в БД, то имеет смысл использовать классы, специально предназначенные для работы с подобными источниками, а не заниматься наследованием абстрактной модели. Если же модель-источник не является таблицей в БД, а, например, представляет из себя некий файл, то фильтрация данных должна быть добавлена в эту исходную модель и производиться непосредственно при вызове fetchMore() с тем, чтобы выдать минимальное количество данных, соответствующих условиям фильтрации.

Комментариев нет:

Отправить комментарий