Russian Qt Forum
Ноябрь 24, 2024, 23:55 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QAbstractTableModel и два представления: нужен совет...  (Прочитано 16302 раз)
Cyrax
Гость
« : Январь 02, 2008, 21:46 »

Вопрос следующий: каким образом модель данных (наследник QAbstractTableModel) может определить, какое из представлений вызывает её методы (в частности, data() и setData()) для случая, когда эта модель связана с двумя представлениями ?

Ситуация следующая. Имеется два представления: табличное (с двууровневыми заголовками) и древовидное (QTreeView). Табличное представление содержит значения некоторых параметров, имена которых указаны в горизонтальном заголовке. При наведении мышки на имя какого-либо параметра в горизонтальном заголовке всплывает подсказка с дополнительной информацией об этом параметре. Древовидное представление содержит подробную информацию об этих заголовках (дерево параметров): имя параметра/подпараметра (содержащееся также в табличном представлении в горизонтальном заголовке) + ещё несколько характеристик параметра (часть из которых указывается во всплывающей подсказке горизонтального хидера табличного представления).
Таким образом, почти вся информация, отображаемая древовидным представлением, отображается в табличном представлении. В то же время табличное представление отображает информацию, отсутствующую в древовидном представлении (значения параметров), и наоборот, древовидное представление содержит информацию, отсутствующую в табличном (некоторые характеристики параметров).
Оптимальный способ организации данных - создание общей модели данных (наследника QAbstractTableModel) для обоих представлений, каждое из которых будет работать с соответствующими методами этой модели. Задача заключается в определении моделью данных, какое из представлений вызвало её метод, поскольку для одного и того же индекса QModelIndex табличное и древовидное представления будут запрашивать/изменять разные данные.
Другой способ - создание для каждого представления своей модели данных (табличная и древовидная). Но при этом будет происходить дублирование данных, в связи с чем придётся синхронизировать эти модели. Но это уже отказ от архитектуры "модель-представление" (проще взять QTableWidget и QStandartItemModel + их синхронизация)...
Как лучше это всё организовать ?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Январь 02, 2008, 23:54 »

Я бы предложил один из 2 вариантов:
1. Модель насделуется от QAbstractTreeItemModel и содержит общие данные.
2. Общие данные содержатся в отдельном классе. Далее, создается один класс-модель для таблицы (с данными, уникальными для таблицы), и второй класс-дерево (с данными, уникальными для дерева). Оба этих класса содержат также указатели на класс с общими данными.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Cyrax
Гость
« Ответ #2 : Январь 03, 2008, 09:35 »

Цитировать
1. Модель насделуется от QAbstractTreeItemModel и содержит общие данные.
Наверное, имеешь ввиду QAbstractItemModel ?  (иерархическая структура)
Как в этом случае определить, какое из представлений запрашивает данные ?  Получили, например, некоторый индекс. Для этого индекса древовидному представлению нужно вернуть одни данные, табличному - другие...
И почему именно QAbstractItemModel, а не QAbstractTableModel ?

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

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

А вообще, хотелось бы иметь одну общую модель данных (например, наследник QAbstractTableModel).
Только вот модель всё-таки оказывается привязанной к структуре представления (для некоторого индекса табличному представлению нужно вернуть одни данные, древовидному - другие)...
« Последнее редактирование: Январь 03, 2008, 09:49 от Cyrax » Записан
vaprele07
Гость
« Ответ #3 : Январь 03, 2008, 10:30 »

Делается одна модель данный, работающая непосредственно с бд (множества А+Б) и 2 прокси модели (QAbstractProxyModel), реализующие нужные тебе представления. В таком случае тебе не придётся придумывать всяких костылей синхронизации данных.
Записан
Cyrax
Гость
« Ответ #4 : Январь 03, 2008, 11:25 »

Цитировать
Делается одна модель данный, работающая непосредственно с бд (множества А+Б) и 2 прокси модели (QAbstractProxyModel), реализующие нужные тебе представления. В таком случае тебе не придётся придумывать всяких костылей синхронизации данных.
Что значит "реализующие нужные тебе представления" ?  Одна прокси-модель работает с табличным представлением, другая - с древовидным ?  Т.е. задача прокси заключается в конвертировании индексов таким образом, чтобы их допустимые множества для обоих представлений не пересекались ?  Тогда компоненты многих индексов потеряют физический смысл. Скажем, для табличного представления смысл сохранится (строка, столбец), а для древовидного - исказится.
Для древовидного представления тоже можно сохранить физический смысл компонентов индекса, если, например, для древовидного представления в прокси будем менять знак строки и столбца на отрицательный...


Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Январь 03, 2008, 11:31 »

Именно так, две модели - одно для дерева, второе для таблицы (мой вариант 2 - та же идея). Обе модели берут реальные данные из третьей и конвертируют индексы так, как нужно представлениям.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Cyrax
Гость
« Ответ #6 : Январь 03, 2008, 11:46 »

vaprele07
А ещё лучше рассмотреть конкретный пример.
Горизонтальный заголовок таблицы содержит имена параметров. Вертикальный - номера значений параметров. Т.е., если в таблице 50 строк, то для каждого параметра будет 50 значений.
Древовидное представление содержит иерархию параметров (имена которых указаны в горизонтальном заголовке табличного представления) с их характеристиками/описанием.
Пусть M - главная модель с данными, работающая с БД.
V_tree - древовидное представление
V_table - табличное представление
P_tree - прокси-модель, работающая с древовидным представлением
P_table - прокси-модель, работающая с табличным представлением
Скажем, табличное представление V_table запросило у своей модели (у прокси-модели P_tree) данные по индексу (0, 0, null) для роли DisplayRole. Т.е. данные для своей ячейки в первом столбце первого ряда (это первое значение первого параметра X). Затем древовидное представление V_tree запросило данные у своей прокси-модели P_tree по индексу (0, 0, null) для роли DisplayRole. Т.е. данные для своего первого столбца первого ряда (это имя первого параметра X).
Какие значения индексов должны передать прокси-модели P_table и P_tree главной модели M ?
(учитываем, что модель M должна получать разные индексы для разных данных)
Записан
Cyrax
Гость
« Ответ #7 : Январь 03, 2008, 11:50 »

Цитировать
Именно так, две модели - одно для дерева, второе для таблицы (мой вариант 2 - та же идея). Обе модели берут реальные данные из третьей и конвертируют индексы так, как нужно представлениям.
А что лучше взять - 2 модели, конвертирующие индексы, или 2 прокси, конвертирующих индексы ?

Racheengel , предлагаю рассмотреть конкретный пример из моего предыдущего поста касательно конвертирования индексов ?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #8 : Январь 03, 2008, 14:55 »

А что лучше взять - 2 модели, конвертирующие индексы, или 2 прокси, конвертирующих индексы ?
В данном случае это одно и тоже. Прокси - это модель, которая не содержит реальных данных.

Что касается индексов, надо сначала ответить на вопрос: как представлены данные в модели М?
Совсем необязательно, что они будут вообще основаны на индексах. Индекс всего лишь указывает на то, какие данные реально нужны. Для P_table по индексу (0, 0, null)  нужно будет вернуть значение 0 параметра 0 из модели М, а для P_tree - имя параметра 0 из модели М.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Cyrax
Гость
« Ответ #9 : Январь 03, 2008, 15:20 »

Цитировать
Что касается индексов, надо сначала ответить на вопрос: как представлены данные в модели М?
2 структуры данных: таблица (двумерный массив) и дерево параметров (списки + указатели, либо двумерный массив). Вся информация, необходимая для формирования этих двух структур данных, извлекается из БД в конструкторе модели M (вопросы синхронизации данных модели M с данными в БД пока не рассматривает - это отдельный вопрос).
А вот здесь желателен пример, какие индексы могут формировать прокси-модели P_tree и P_table из получаемого индекса (0, 0, null) с учётом указанных структур данных модели M.

Цитировать
Совсем необязательно, что они будут вообще основаны на индексах. Индекс всего лишь указывает на то, какие данные реально нужны. Для P_table по индексу (0, 0, null)  нужно будет вернуть значение 0 параметра 0 из модели М, а для P_tree - имя параметра 0 из модели М.
Да, данные в модели M не обязательно должны быть основаны на индексах, но иначе как по индексам модель M не сможт определить, какие данные запрашивают представления V_tree и V_table. Т.е. в любом случае данные модели M придётся привязывать к индексам.


Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #10 : Январь 03, 2008, 15:35 »

Нет, я имею в виду, что индексы нужны для доступа представлений к прокси-моделям. А уже прокси-модели будут извлекать реальные данные из М в зависимости от того, какой был запрошен индекс, и передавать представлению в виде QVariant.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Cyrax
Гость
« Ответ #11 : Январь 03, 2008, 16:15 »

Цитировать
А уже прокси-модели будут извлекать реальные данные из М в зависимости от того, какой
был запрошен индекс
Т.е. предлагаешь изменить (расширить) стандартный Qt-интерфейс для "общения" модели M с M_tree и M_table ?
Потому что если оставить тот же интерфейс (data, setData и др.), то придётся модель M привязывать к индексам...
Записан
ритт
Гость
« Ответ #12 : Январь 03, 2008, 16:41 »

извините, конечно, что вмешиваюсь...
"расширять интерфейс" не нужно. нужно почитать/перечитать документацию по модель-вью и по прокси-моделям в частности. доступ к данным во ВСЕХ моделях кутэ осуществляется через некий индекс и категоризацию через роли. в худшем случае (в зависимости от конкретной задачи) придётся написать наследника прокси-модели и перегрузить некоторые методы, чтобы заточить под конкретные нужды.
Записан
Cyrax
Гость
« Ответ #13 : Январь 03, 2008, 17:06 »

Цитировать
доступ к данным во ВСЕХ моделях кутэ осуществляется через некий индекс и категоризацию
через роли. в худшем случае (в зависимости от конкретной задачи) придётся написать наследника прокси-модели и перегрузить некоторые методы, чтобы заточить под конкретные нужды.
Поконкретнее, пожалуйста. Ближе к моей "задаче".
Предлагаешь обходиться дополнительными пользовательскими ролями ?
(схема "одна общая модель + 2 представления + дополнительные роли") ?
Записан
ритт
Гость
« Ответ #14 : Январь 03, 2008, 20:48 »

да
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.055 секунд. Запросов: 23.