Название: ModelView большое количество данных Отправлено: demaker от Сентября 05, 2025, 11:57 Всем доброго времени суток!
Возникла проблема с отображением большого количества строк в QAbstractTableModel. Прорисовка графики начинает подвисать, когда количество строк в таблице в районе 1500. Данные берутся из std::unordered_map и затем заполняется std::vector<std::pair<KEY, TYPE>> v и закидывается в модель. В модели переопределил методы data, flags, rows, columns. Есть метод upDate(), так как когда вычитываем свежую порцию данных ,то хотим их обновить в модели(например по таймеру 500ms) Код
Хотелось бы узнать насколько корректны мои действия в плане обновления данных модели? Нужно ли именно все данные подгружать в модель? Хочется подгружать именно ту область данных, которая на данный момент отображается на view)) Может есть другие механизмы более правильные? Может мне стоит использовать canFetchMore, fetchMore? Не получится ли при этом что добавлю в модель все 1500 строк и опять также графика вновь будет подвисать? Спасибо! Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 05, 2025, 13:44 demaker
Попробуй использовать QTreeView он чуть проще (не позволяет ресайзить вертикальные хедеры + есть опция uniformRowHeight которая делает отрисовку за O(N) вместо O(N*N)) 1500 это не очень большое количество, стандартные вьюги должны тянуть такое если поиграться с опциями. Если я правильно помню, они сносно тянут до 20к строк. Если надо прямо много (больше 100к, максимально я рисовал 3 миллиона строк), то надо писать свою вьюху - внутри QTableView/QTreeView есть стейт рядов (вектор) который хранит высоту ряда и синхронизируется с моделью. Так как это вектор то его ресайзы занимают значительно время на вставке в середину. Соответственно в модели вместо вектора надо пользовать std::deque. Но опять же это применимо когда рядов хотя бы полмиллиона. Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 05, 2025, 13:45 А, ну и вместо reset советую insert/remove rows
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 05, 2025, 15:35 Авварон
Такой вопрос) Можно ли допустим взять ту же вьюху(QTableView) и выводить в ней столько записей сколько помещается на отображение при этом использовать свой вертикальный скролл бар Код
Делаем нужную выборку из вектора Код
Код
Или кривовато??? У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы если уже такие данные есть до мы просто их обновляем. Поэтому при формирование вектора могут добавиться как в середину так и в начало и как использовать insert в таком случае я не понимаю? Нужно как-то предварительно рассчитывать куда insert делать. Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 05, 2025, 16:41 Цитировать Или кривовато??? я бы ожидал багов да=)весь смысл QTableView в вертикальном хедере который позволяет менять высоту строк (а как следствие высоту всей вью и макс значение скроллбара) Используй QTreeView с uniformRowHeights=true https://doc.qt.io/qt-6/qtreeview.html#uniformRowHeights-prop - так оно будет вычислять скроллбар как firstRowHeight*rowCount() а не суммировать в цикле. Скорее всего тормоза у тебя не уйдут так потому что все равно чтобы посчитать высоту Цитировать У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы не вижу особо проблем - в модели у тебя все равно будет вектор/дек так как ты в какой-то момент захочешь сортировку по колонкам делать и менять содержимое элементовесли уже такие данные есть до мы просто их обновляем. надо только аккуратно держать в синке вектор с мапой в целом можно избежать вставки в середину лайфхаком - всегда добавлять новое в конец (beginInsertRows) а потом пересортировывать (вызывая в просессе layoutAboutToBeChanged/layoutChanged) Делать фулл reset не очень удобно на практике так как полностью перерисоывает вьюпорт, сбрасывает селекшн. Вьюша же рисует только то что попадает во вьпорт и если ряды добавляются вне его то никаких перерисовок не будет Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 09, 2025, 22:24 Цитировать Или кривовато??? я бы ожидал багов да=)весь смысл QTableView в вертикальном хедере который позволяет менять высоту строк (а как следствие высоту всей вью и макс значение скроллбара) Используй QTreeView с uniformRowHeights=true https://doc.qt.io/qt-6/qtreeview.html#uniformRowHeights-prop - так оно будет вычислять скроллбар как firstRowHeight*rowCount() а не суммировать в цикле. Скорее всего тормоза у тебя не уйдут так потому что все равно чтобы посчитать высоту Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 09, 2025, 22:26 Цитировать У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы не вижу особо проблем - в модели у тебя все равно будет вектор/дек так как ты в какой-то момент захочешь сортировку по колонкам делать и менять содержимое элементовесли уже такие данные есть до мы просто их обновляем. надо только аккуратно держать в синке вектор с мапой в целом можно избежать вставки в середину лайфхаком - всегда добавлять новое в конец (beginInsertRows) а потом пересортировывать (вызывая в просессе layoutAboutToBeChanged/layoutChanged) Делать фулл reset не очень удобно на практике так как полностью перерисоывает вьюпорт, сбрасывает селекшн. Вьюша же рисует только то что попадает во вьпорт и если ряды добавляются вне его то никаких перерисовок не будет Хотелось немного по этой части уточнить) Правильно ли я понял принцип добавления\обновления элементов в моедль Код
Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 10, 2025, 00:42 beginInsertRows должен предшествовать изменению данных, endInsertRows должен быть после
иначе может разъехаться стейт для некоторых вьюх это может работать (если колбек на beginInsertRows пустой) для некоторых нет тут только смотреть конкретную реализацию (и я конечно из головы уже не помню че там 14 лет назад было дело) Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 10, 2025, 01:11 Собственно сама модель подписана на beginInsertRows и вызывает rowCount (https://codebrowser.dev/qt5/qtbase/src/corelib/itemmodels/qabstractitemmodel.cpp.html#667) который тут ожидается старый
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 10, 2025, 09:58 beginInsertRows должен предшествовать изменению данных, endInsertRows должен быть после иначе может разъехаться стейт для некоторых вьюх это может работать (если колбек на beginInsertRows пустой) для некоторых нет тут только смотреть конкретную реализацию (и я конечно из головы уже не помню че там 14 лет назад было дело) Ага понял Код
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 10, 2025, 10:00 Цитировать У меня используется мьюченный std::unordered_map ну чтобы threadsafe был и данные добавляются при этом формируется ключ, чтобы не вижу особо проблем - в модели у тебя все равно будет вектор/дек так как ты в какой-то момент захочешь сортировку по колонкам делать и менять содержимое элементовесли уже такие данные есть до мы просто их обновляем. надо только аккуратно держать в синке вектор с мапой в целом можно избежать вставки в середину лайфхаком - всегда добавлять новое в конец (beginInsertRows) а потом пересортировывать (вызывая в просессе layoutAboutToBeChanged/layoutChanged) Делать фулл reset не очень удобно на практике так как полностью перерисоывает вьюпорт, сбрасывает селекшн. Вьюша же рисует только то что попадает во вьпорт и если ряды добавляются вне его то никаких перерисовок не будет Здесь как ты советуешь планирую сделать что-то типа Код
И получается если размер deque изменился то соответственно мы делаем beginInsertRows - endInsertRows а если нет обновляем данные. Т.е ниже у меня был vector, теперь будет deque Надеюсь правилно тебя понял) Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 10, 2025, 14:14 похоже на правду, да
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 10, 2025, 16:28 Блин после того как сделал почему-то фильтрация отвалилась
Код
Код
Код
Пробовал делать Код: sort->dataChanged(...) Но увы не помогает(( Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 11, 2025, 02:11 Код: void Model::update(std::vector<Type> &fresh) это кстати будет работать только если в новом векторе рядов больше чем в старом Название: Re: ModelView большое количество данных Отправлено: Авварон от Сентября 11, 2025, 02:13 Вообще SortFilterProxyModel может быть источником тормозов в том числе
Она хорошая для простых кейзов, для сложных лучше писать сортировку руками Почему может не работать - хз надо читать код а мне лень может где-то контракт модели нарушен но в приведенном коде вроде всё ок Название: Re: ModelView большое количество данных Отправлено: kambala от Сентября 11, 2025, 12:09 еще можно свою модель погонять через QAbstractItemModelTester https://wiki.qt.io/Model_Test
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 12, 2025, 13:20 Код: void Model::update(std::vector<Type> &fresh) это кстати будет работать только если в новом векторе рядов больше чем в старом Да, согласен) Сделал вот так Код
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 12, 2025, 13:25 Вообще SortFilterProxyModel может быть источником тормозов в том числе Она хорошая для простых кейзов, для сложных лучше писать сортировку руками Почему может не работать - хз надо читать код а мне лень может где-то контракт модели нарушен но в приведенном коде вроде всё ок Сортировка работает, но фильтрация увы ((... Сделаю фильтрацию во время формирования вектора данных модели) Ну при этом у меня потеряется селектор блин, т.к индексы эементов будут другие И как тогда?.. Название: Re: ModelView большое количество данных Отправлено: __Heaven__ от Сентября 12, 2025, 14:12 Кажется, что в модельке не стоит обращаться ко view
Если правильно понял, ты тут обновляешь больше ячеек чем сообщаешь через dataChanged. Оно может быть критичным для моделей сортировки и фильтрации Название: Re: ModelView большое количество данных Отправлено: __Heaven__ от Сентября 12, 2025, 14:19 Ты ещё пишешь про unordered_map->vector. Если там простой std::copy, то полагаю, что строки в векторе могут перетасовываться = достаточно сложно вычислить какие индексы в модели обновились
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 13, 2025, 00:52 Ты ещё пишешь про unordered_map->vector. Если там простой std::copy, то полагаю, что строки в векторе могут перетасовываться = достаточно сложно вычислить какие индексы в модели обновились Делаю вот так Код
Название: Re: ModelView большое количество данных Отправлено: demaker от Сентября 13, 2025, 00:58 Используй QTreeView с uniformRowHeights=true https://doc.qt.io/qt-6/qtreeview.html#uniformRowHeights-prop - так оно будет вычислять скроллбар как firstRowHeight*rowCount() а не суммировать в цикле. Не получается выделить несколько строк. Делаю так: Код
Это связано с тем что tablemodel привязана к treview? Или в коде проблема? |