LINUX.ORG.RU

Не обновляется вид QTableView при изменении данных модели. Emit dataChanged() присутствует.

 , ,


0

1

По какой-то причине не могу увидеть строки в QTableView. Вид отображает модель, унаследованную от QAbstractTableModel.

В модели, в методе setData(), вызываю emit dataChanged():

bool AttachTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
  // Если индекс недопустимый
  if(!index.isValid() && role!=ATTACH_TABLE_DATA_ROLE)
    return false;

  // Если происходит установка ссылки на таблицу с данными
  if(role==ATTACH_TABLE_DATA_ROLE)
  {
    table=value.value<AttachTableDataPointer>();

    QModelIndex startIndex=createIndex(0, 0);
    QModelIndex stopIndex=createIndex(table->size(), ATTACH_COLUMNS-1 );

    qDebug() << "Set new data to AttachTableModel with rows: " << table->size();

    emit dataChanged(startIndex, stopIndex);

    return true;
  }
  ...

При отладке вижу, что данные в модели обновляются:
Set new data to AttachTableModel with rows: 2

Так же сделал специальную кнопочку чтобы проверять что там у модели установлено. Она тоже показывает при нажатии 2 строки:
void AttachTableController::onInfo(void)
{
  qDebug() << "Model row: " << model->rowCount();
}

В консоли вижу:
Model row: 2

Однако вид ничего не показывает. Не пойму почему.

Код проекта: https://github.com/xintrea/mytetra_dev/commit/e627a41b3e18f7472b4364eb443e8c3...

Как проверить:

1. Запустить;
2. Добавить пару записей (Кнопка «лист с плюсиком»);
3. Выяснить, где лежит файл mytetra.xml ( Инструменты-Настройки-Директория с данными-Кнопка [...] );
4. Выйти из mytetra;
5. В файле mytetra.xml преобразовать запись в одну строку:
<record url="" id="xo18t7c43" dir="rkpqeq2c4" author="" file="text.html" tags="" ctime="20150731162919" name="Запись обычная"/>

К такому виду:
<record url="" id="xo18t7c43" dir="rkpqeq2c4" author="" file="text.html" tags="" ctime="20150731162919" name="Запись с приаттаченными файлами">
 <files>
  <file id="abc12345" fileName="Архив.zip" type="file"/> 
  <file id="defg6789" fileName="Данные.zip" type="file"/> 
 </files>
</record>

Note: По стандарту XML при оформлении в виде одного тега, должна быть косая черта в конце тега: «/>». А при оформлении в виде открывающего и закрывающего тега, косой черты в открывающем теге быть не должно.

6. Снова запустить, кликнуть на измененную запись;
7. Кликнуть на кноку со скрепкой;
8. Наблюдать пустой список файлов;
9. Кликнуть на кнопку Attach Info;
10. Увидеть в консоли надпись:

Model row: 2


Да, после изменения xml файла, в самой программе ничего нелья добавлять/удалять/редактировать. Только смотреть. Так как xml-файл перезапишется, и в нем измененные строки исчезнут (функционал еще не доделан).

★★★★★

Это не ответ на твой вопрос, а скорее встречный вопрос: зачем ты уведомляешь вьюху об изменении целого списка индексов? В идеале, если у тебя меняется index, который передается аргументом в setData, то его ты и должен указывать как начальный/конечный.

m0rph ★★★★★ ()

dataChanged работает только для уже существующих индексов, если надо объявить про появление новых или удаление старых, то надо использовать beginInsertRows/endInsertRows и endRemoveRows/beginRemoveRows. Плюс по хорошему свою модель еще надо тестировать:

http://wiki.qt.io/Model_Test.

anonymous ()
Ответ на: комментарий от m0rph

зачем ты уведомляешь вьюху об изменении целого списка индексов?

Чтобы вьюха обновилась.

Xintrea ★★★★★ ()
Ответ на: комментарий от m0rph

В идеале, если у тебя меняется index, который передается аргументом в setData

Если ты заметил, у меня в setData() передается указатель на таблицу всех данных, которые должна передавать модель. Потому что по-другому через стандартный интерфейс модели заставить модель переключиться на другие данные невозможно.

Xintrea ★★★★★ ()
Последнее исправление: Xintrea (всего исправлений: 1)
Ответ на: комментарий от Xintrea

Чтобы вьюха обновилась.

setData() изменяет только один существующий индекс, а ты судя по всему пытаешься добавить еще несколько. Анонимус дело говорит.

m0rph ★★★★★ ()
Ответ на: комментарий от Xintrea

Потому что по-другому через стандартный интерфейс модели заставить модель переключиться на другие данные невозможно.

Так замени модель во вьюхе на другую, с новым данными. Если нужно чтобы во всех вьюхах с этой моделью одновременно изменились данные, можно ресетнуть модель (reset()) и загрузить туда новые данные.

m0rph ★★★★★ ()
Ответ на: комментарий от anonymous

Все оказалось проще. Коль у меня меняется вся модель, надо воспользоваться методами beginResetModel/endResetModel:

beginResetModel();

// Устанавливается данные переданной по указателю таблицы
table=value.value<AttachTableDataPointer>();
qDebug() << "Set new data to AttachTableModel with rows: " << table->size();

endResetModel();
Xintrea ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.