LINUX.ORG.RU

Qt - модели


0

1

Не могу осилить концепцию моделей и индексов в моделях (несмотря на это пишу софт, использующий те и другие, хыхы).

Вот пример. Есть окно, в нем виджет QTableView выводящий содержимое какой-нить таблички базы данных (не принципиально).

Данные в базе могут менятся из других источников. Для слежения за этим у меня есть фоновый процесс, получающий команды от координатора или просто обновляющий данные по таймеру. Когда данные обновились, я их скармливаю в мою модель (потомок QAbstractTableModel).

В своей модели я реализовал методы headerData(), rowCount(), columnCount(), data().

В data() я выкодовываю из modelIndex его row и column, что бы знать, какое значение выводить в ячейке.

Пока данные не меняются - все работает отлично.

Дальше начинается интересное.

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

Тут начинаются глупые вопросы.

Кто ответственен за генерацию modelIndex'ов? Я или модель? Надо их генерить при каждом обновлении данных или как?

Из документации я понял, что modelIndex - это внутримодельное представление данных, т.е. каждой ячейке моей таблицы я должен сопоставить уникальный modelIndex. Как их генерировать и где? Тут начинается ступор.

P.S. Пишу на PyQt, так что приветствуются примеры на нём. P.P.S. Какой-то среднепоследний стейбл, 4.7 примерно.

★★★★★

> Кто ответственен за генерацию modelIndex'ов?

И ты и модель. Ты должен реализовать ...Model::index() , в который тебе с помощью ...Model::createIndex() нужно задавать иерархию твоего дерева.

При обновлении данных я шлю наверх сигнал layoutChanged() и dataChanged()

Если ты целиком перерисовываешь дерево, то тебе нужно по новой ставить курсор (selectionModel()), поскольку «старый» индекс может теперь указывать на другой элемент (если произошел сдвиг): он ведь определяется исходя из тройки <row, col, parent>. Если ты делаешь точечные действия, то тебе нужно слать сигналы rowsAboutToBeRemoved() итд., скорее всего selectionModel() это подхватит.

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

>> Кто ответственен за генерацию modelIndex'ов?

И ты и модель. Ты должен реализовать ...Model::index() , в который тебе с помощью ...Model::createIndex() нужно задавать иерархию твоего дерева.

Я пробовал, херня какая-то выходит, элементы просто не отображаются. Попробую еще раз.

Если ты целиком перерисовываешь дерево, то тебе нужно по новой ставить курсор (selectionModel()),

Но selectionModel - свойство QTableView, а не QAbstractTableModel.

Я, впринципе, сейчас так и сделал (шлю сигнал layoutAboutToBeChanged, по которому QTableView запоминает выделенный элемент и layoutChanged по которому элемент выделяется заново). Но мне казалось, что это как-то не очень правильно.

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

Но selectionModel - свойство QTableView, а не QAbstractTableModel.

Я, впринципе, сейчас так и сделал (шлю сигнал layoutAboutToBeChanged, по которому QTableView запоминает выделенный элемент и layoutChanged по которому элемент выделяется заново). Но мне казалось, что это как-то не очень правильно.

Если дерево целиком перерисовалось, то откуда внутренности Qt должны знать, что на самом деле только одна строка исчезла? Мерджить старое дерево с новым? :)

Selection model хранит индекс последнего выбранного элемента: <строка,столбец,родитель>, она его честно выделяет по новой, а на этом месте уже другой элемент... мне все кажется логичным.

Если бы изменение было точечным, то с помощью сигналов rowsAboutToBeRemoved и rowsRemoved ты бы сообщал всем участникам этого действия (view, selection model, делегат если есть итд), что действительно удалилась только одна строка, ребята, обработайте это корректно. И скорее всего selection model внутри себя пересчитала бы этот индекс так, чтобы с точки зрения пользователя выделенным остался все тот же элемент.

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

Да, логично :)

Ладно, спасибо, буду играться дальше.

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