Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt] Как работает архитектура "Model->View"? Если класс "Item" не наслудуется 
V
    Опции темы
KaraKum
  Дата 10.10.2008, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Доброе время суток.
Кто знает, в Qt есть технология "Model->View architecture", в которой нужно организовать 3 класса: view, model, item.
Я по обучению организовал - работает, но как? (Я как View использовал QTreeView)
Как класс модели (или вида) находит дочерние элементы какого-либо элемента, если в классе модели хранится только коренной элемент (объект класса Item), а класс Item ни от кого не наследуется, причём его функции (getChild(), getParent() и так далее) можно переименовывать произвольным образом - всё равно работает!
Вопрос в основном из любопытсва, но всё-равно охота узнать.
PM MAIL WWW   Вверх
powerfox
Дата 11.10.2008, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 97





--------------------
user posted image
PM WWW   Вверх
KaraKum
  Дата 11.10.2008, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



Я по этому обучению и создал свой вид по типу дерева (как вид использовал QTreeView). Но в этом обучении вроде нет объяснения тому как этот механизм работает. То есть, например, если в виде деререва раскрывать папки, то как тогда вид (или модель) получает информацию о дочерних элементах раскрываемого элемента?
PM MAIL WWW   Вверх
powerfox
Дата 11.10.2008, 15:20 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 97



Цитата(KaraKum @  11.10.2008,  13:47 Найти цитируемый пост)
то как тогда вид (или модель) получает информацию о дочерних элементах раскрываемого элемента? 

Цитата

In the model/view architecture, the model provides a standard interface that views and delegates use to access data. In Qt, the standard interface is defined by the QAbstractItemModel class.


user posted image

Цитата

Rows and columns
The diagram shows a representation of a basic table model in which each item is located by a pair of row and column numbers. By passing the relevant row and column numbers to the model we obtain a model index that refers to an item of data.
 QModelIndex indexA = model->index(0, 0, QModelIndex());
 QModelIndex indexB = model->index(1, 1, QModelIndex());
 QModelIndex indexC = model->index(2, 1, QModelIndex());
Top level items in a model are always referenced by specifying QModelIndex() as their parent item. This is discussed in the next section.


Когда мы определяем свою модель, то мы реализуем функцию index. Которая всё это и обрабатывает. View получает данные, используя именно метод index.

Цитата(KaraKum @  10.10.2008,  14:52 Найти цитируемый пост)
если в классе модели хранится только коренной элемент (объект класса Item), а класс Item ни от кого не наследуется, причём его функции (getChild(), getParent() и так далее) можно переименовывать произвольным образом - всё равно работает!

Это внутренние методы модели. Главное то, что в интерфейсе (метод index). Это же «служебные» методы. Которые, наверняка, являются скрытыми (private).
Суть модели заключается в том, что мы можем хранить данные в любом виде, но при этом реализуем index, который знает, как мы храним данные и передаёт пользователям (view, delegate) элементы, которые они запрашивают по номеру колонки/столбца и родителю элемента. 


--------------------
user posted image
PM WWW   Вверх
KaraKum
  Дата 13.10.2008, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: нет
Всего: 1



То есть получается так что при инициализации (или добавлении новых) элементов Item, объект  класса Model сохраняет внутри себя (или расширяет) массив объектов QModelIndex, каждому из которых автоматически присваивается (в поле void*) указатель на объект класса Item?
Это можно представить как работает, но как, тогда, работает механизм добавления новых Item'ов уже после инициализации, который у меня реализован вот так:
Код

void CTreeModel::appendItem(CTreeItem *newItem, CTreeItem *parentItem)
{
    beginInsertRows(QModelIndex(), parentItem->childCount(), parentItem->childCount());
    
    parentItem->appendChild(newItem);
    
    endInsertRows();
}

То есть чтобы вставить новый элемент в нужное место в дереве нужно рекурсивно добраться от родитильского элемента вставляемого объекта к вершине всего дереве, но как это происходит, если, опять же, нет жёстко регламентированных функций (в классе CTreeItem) для получения этого родительского объекта?
PM MAIL WWW   Вверх
powerfox
Дата 13.10.2008, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 97



Цитата(KaraKum @  13.10.2008,  10:37 Найти цитируемый пост)
массив объектов QModelIndex

Нет. Это всего лишь класс для доступа к элементам. Главные фонкции, по сути, column(), row(), data(), parent(), child().

Цитата(KaraKum @  13.10.2008,  10:37 Найти цитируемый пост)
CTreeModel::appendItem

Это исключительно ваша функция, не переопределение Qt-й.

Цитата(KaraKum @  13.10.2008,  10:37 Найти цитируемый пост)
То есть чтобы вставить новый элемент в нужное место в дереве нужно рекурсивно добраться от родитильского элемента вставляемого объекта к вершине всего дереве, но как это происходит, если, опять же, нет жёстко регламентированных функций (в классе CTreeItem) для получения этого родительского объекта? 

Нет, вы это делаете так:

Цитата(KaraKum @  13.10.2008,  10:37 Найти цитируемый пост)
    parentItem->appendChild(newItem);

Стало быть всё остальное реализованов CTreeItem::appendChild().

Вся суть Model-View в том, что у вас есть класс Model, который имеет определённый набор функций. Вот фрагмент кода с KDevelop:
Код

class CommitLogModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    CommitLogModel(const QList<DVCScommit> revisions, QObject* parent = 0);
    ~CommitLogModel() {};

    QVariant data(const QModelIndex &index, int role) const;
    QModelIndex index(int r, int c, const QModelIndex& par = QModelIndex()) const;
    QModelIndex parent(const QModelIndex& index) const;

    int rowCount(const QModelIndex& par = QModelIndex()) const;
    int columnCount(const QModelIndex&) const;

private:
    QStringList headerInfo;
    QList<DVCScommit> revs;

    int rowCnt;
    int branchCnt;
};


Данные хранятся произвольным образом. В данном случае, в поле revs. Вся суть использования подели состоит в определении date, index, parent, Xcount, которые будут использованы другими классами (представлением (View) и делегатами представления). Они ничего не знают о том, как мы храним данные. Им лишь нужно уметь их получить. Наша же модель знает, как обработать то, что мы храним и передать другим классам данные.
Если подытожить, то основная идея в том, что *только* вы знаете, как хранятся элементы и как их добавлять/удалять. Классам же пользователям нужен лишь интерфейс доступа. Посмотрите документация по QAbstractItemModel.



--------------------
user posted image
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0471 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.