Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Архитектура Модель-Представление
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Модель/Представление
vo.borodin
В последнее время отошел от C++, но сейчас хочу возвратить навыки по нему. Реализация архитектуры Модель-Представление в Qt - тема интересная и сложная, хочу в ней разобраться. Есть много непонятных моментов и фундаментальных вопросов. Обо всём по порядку:
1) Класс QAbstractItemModel, как я понимаю, представляет собой самый общий интерфейс для модели, представляющей собой обертку над древовидной структурой данных. Есть корневой элемент данных, у корневого элемента есть потомки. Каждый из потомков является (или может являться) верхним левым элементом в некоей таблице элементов. Каждый из элементов в этой таблице сам может иметь потомков, и т. д. Так вот, я правильно понимаю, что модельный индекс QModelIndex - это некий объект, который ставится в соответствие каждому элементу данных в этой структуре и по которому можно этот элемент найти?
2) Лейтмотивом создания архитектуры MVC являлось отделение данных от способа их представления. Допустим, моё представление должно на основе данных в моей модели что-то нарисовать. Представление, я так понимаю, доступается до данных в модели через модельные индексы QModelIndex. Так вот, должно ли представление знать о способе организации данных в модели? Или смысл следующий: для одной модели мы можем создать несколько представлений, каждое из которых знает структуру данных в модели и отображает данные по-своему?
3) В чем суть делегатов? Должны ли они участвовать в отображении данных или только в обработке действий пользователя?
4) Допустим, в моей модели есть древовидная структура данных, в которой узлы дерева разных уровней представляются разными пользовательскими классами. Т. е. примерно так:
class E
{
private:
    // Некоторые собственные данные класса
    int m_e1;
    double m_e2;
};

class D
{
private:
    // Некоторые собственные данные класса
    QVector<E> vectorE;
};

class C
{
private:
   // Некоторые собственные данные класса
   bool m_c1;
   double m_c2;
   double m_c3;
};

class B
{
private:
    // Некоторые собственные данные класса
    C m_b1;
    int m_b2;
    QVector<D> vectorD;
};

class A: public QAbstractItemModel
{
private:
    QVector<B> vectorB;
};


Возвращать QModelIndex должен метод index() в классе A. Но как в этом методе организовать генерацию индексов для объектов классов B, C, D, E и содержащихся в них данных?
Анна
1. Да, QModelIndex ставится в соответствие каждому элементу. Он кроме i и j ещё имеет третью координату parent. Этого достаточно, чтобы добраться до любого элемента.
2. Так вот, должно ли представление знать о способе организации данных в модели? Ну, если учесть, что есть несколько потомков от QAbstractItemView, легко предположить, что представление считает, что оно имеет представление о модели. Если вы предложите QTableView отобразить дерево, думаю ничего хорошего не получится, отобразится максимум один столбец, потому что QTableView не предназначено для отображения дерева
3) "В чем суть делегатов? Должны ли они участвовать в отображении данных или только в обработке действий пользователя?" Посмотрите на методы класса: он может отрисовывать данные элемента, и предоставляет виджет-редактор для редактирования данных элемента.
4. определите во всех классах метод index() + рекурсия, и будет вам счастье. Вот примеры древовидной модели:
http://qt-project.org/doc/qt-5.0/qtwidgets...etreemodel.html
http://qt-project.org/doc/qt-5.0/qtwidgets...etreemodel.html
И ещё, читайте внимательно обзорную статью по MVC, там всё описано, просто не сразу осознаётся весь принцип. Но после разборки пары примеров и собственных опытов всё становится на свои места.
Litkevich Yuriy
Цитата(vo.borodin @ 31.3.2014, 10:14) *
Так вот, должно ли представление знать о способе организации данных в модели?
да, оно должно оперировать модельными индексами (координатами данных) для доступа к данным и ролями модели (альтернативные данные по этим же координатам)
Litkevich Yuriy
Также соит отметить что есть ещё одна вспомогательная модель - Модель выделения (SelectionModel), посмотри пример
%QTDIR%\examples\itemviews\chart

Цитата(vo.borodin @ 31.3.2014, 10:14) *
Но как в этом методе организовать генерацию индексов для объектов классов B, C, D, E и содержащихся в них данных?
Связать индекс с реальными данными можно с помощью метода:
QModelIndex QAbstractItemModel::createIndex ( int row, int column, void * ptr = 0 ) const [protected]

Посмотри пример "Simple Tree Model"
vo.borodin
Всем спасибо за ответы. У меня в ходе разработки моего проекта появился ещё один вопрос относительно модели/представления в Qt. Допустим, мы находимся в рамках того кода, который я привёл выше. По определенному действию (например, нажатию на пункт главного меню) мне нужно добавить новый элемент в вектор vectorB (член данных класса A), а представление должно отреагировать на это добавление созданием нового виджета (скажем, созданием новой вкладки в объекте класса QTabWidget). Как это всё организовать? Начальные этапы понятны: при нажатии на пункт главного меню я вызываю у модели метод insertRow, передав ему такие параметры, чтобы добавился элемент в корневом классе иерархии, т.е. классе A; а что делать дальше?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.