Почему QAbstractTableModel и QTableView потребляют много оперативной памяти?

Рейтинг: -1Ответов: 2Опубликовано: 03.07.2023

необходимо отобразить в окне большое кол-во строк(от 1000 до 1М+). Для этого переопределяю QTableView и QAbstractTableModel, который заполняется данными из другого потока через сигнал-слоты (Qt::QueuedConection). Слот добавления строк выглядит следующим образом:

    void MaTableModel::insertRow_slot(QVector<QVector <QString>> &text)
    {
      beginResetModel();
      tableData.append(text);
      endResetModel();
    }

Реализация остальных необходимых функций тривиальна.

Всё вроде работает нормально(за исключением того что при использовании begin и endInsertRows() таблица отображает пустые строки), но приложение начинает потреблять большое кол-во оперативной памяти. К примеру если выполнить загрузку нескольких файлов суммарный объём занимаемой памяти которых равен 40МБ (220т строк), то потребляемая оперативная память программы увеличивается с 30Мб в стартовом состоянии, до 400мб. А если подгрузить ещё больше файлов то вообще падает с bad::alloc.

Вопрос в том нормально ли что так сильно увеличивается потребление памяти при использовании этих классов? Или я что то не так делаю?

Ответы

▲ 0

В комментарии уже не лезет, поэтому сюда...

Будем считать что упоминание про beginInsertRows/endInsertRows у вас приведено "просто так", и при работе с моделью не используются (по крайней мере код вы привели только слота добавления). История с ними несколько другая, но что касается вашего куска кода...

Для beginResetModel английским по белому написано - When a model is reset it means that any previous data reported from the model is now invalid and has to be queried for again. Т.е. QTableView оповещается что модель изменена и надо все пересчитывать заново.

Более правильным при обновлении является такое:

setUpdatesEnabled(false);
// крутим-вертим, добавляем-удаляем элементы модели
setUpdatesEnabled(true);

Когда setUpdatesEnabled установлен в false, события paint() и update() игнорируются, т.е. gui не приходится пересчитывать-перерисовывать изменения между снятием-установкой setUpdatesEnabled.

С полной уверенностью сказать не могу, но наиболее вероятно что beginResetModel/endResetModel приводит примерно к тому же эффекту, но после endResetModel приходится полностью пересчитывать-перерисовывать все с нуля

▲ 0

необходимо отобразить в окне большое кол-во строк(от 1000 до 1М+)

Мне кажется, что по любому такое количество не поместится во вьюпорте QTableView. Это я к тому, что отрисовывается только видимая часть строк.

По мере прокрутки (скроллинг) дозагружаются из модели данных следующие строки (fetchMore что-то типа того).

А какая у вас модель данных QStandardItemModel или QSqlTableModel?