Главная · Все классы · Основные классы · Классы по группам · Модули · Функции

[Предыдущая: Использование моделей и представлений] [Содержание] [Следующая: Создание новых моделей]

Классы моделей

Основные концепции

В архитектуре модель/представление, модель предоставляет стандартный интерфейс, используемый представлениями и делегатами для доступа к данным. В Qt, стандартный интерфейс определен с помощью класса QAbstractItemModel. Независимо от того, как элементы данных хранятся в структуре данных, все подклассы QAbstractItemModel представляют данные в виде иерархической структуры, содержащей таблицы элементов. Представления используют это соглашение для доступа к элементам данных модели, но они не ограничены в способах предоставления информации пользователю.

С помощью механизма сигналов и слотов, модели уведомляют связанные представления об изменениях в данных.

Данная глава описывает некоторые концепции, являющиеся важнейшими для получения другими компонентами доступа к элементам данных через класс модели. Более продвинутые концепции обсуждаются в следующих главах.

Модельные индексы

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

В результате, только модели требуется знать, как хранятся данные, а тип данных, управляемых моделью, может быть определен довольно приблизительно. Модельные индексы содержат указатель на модель, которая их создала, что предотвращает беспорядок при работе с более, чем одной моделью.

 QAbstractItemModel *model = index.model();

Модельные индексы предоставляют временные ссылки на части информации и могут использоваться для получения или изменения данных посредством модели. В связи с тем, что модели могут время от времени реорганизовывать свою структуру, модельные индексы могут стать недействительными и не должны храниться. Если требуется долгоживущая ссылка на часть данных, должен быть создан постоянный модельный индекс. Он предоставляет ссылку на данные, которая поддерживается моделью актуальной. Временные модельные индексы предоставляются классом QModelIndex, а постоянные модельные индексы предоставляются классом QPersistentModelIndex.

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

Строки и столбцы

Основной формой представления модели является таблица, в которой элемент задается номерами строки и столбца. Это не означает, что основные части информации хранятся в виде массива; использование номеров строк и столбцов является лишь соглашением, позволяющим элементам взаимодействовать друг с другом. Мы можем получить информацию о любом элементе, указав модели номер строки и столбца и получив индекс, представляющий элемент:

 QModelIndex index = model->index(row, column, ...);

Модели, предоставляющие интерфейсы к простым одноуровневым структурам данных, таким как списки и таблицы, не нуждаются в другой информации помимо номеров строк и столбцов, но, поскольку вышеупомянутый код требует этого, мы должны сообщить несколько больше данных для получения модельного индекса.

Строки и столбцы

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

 QModelIndex indexA = model->index(0, 0, QModelIndex());
 QModelIndex indexB = model->index(1, 1, QModelIndex());
 QModelIndex indexC = model->index(2, 1, QModelIndex());

Элементы верхнего уровня модели всегда имеют в качестве родителя специфический QModelIndex(). Он будет описан в следующем разделе.

Родители элементов

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

При запросе индекса элемента модели, мы должны предоставить некоторую информацию о родительском элементе. Единственным способом обращения к элементу вне модели является модельный индекс, так что модельный индекс родителя также должен быть известен:

 QModelIndex index = model->index(row, column, parent);

Родители, строки и столбцы

Диаграмма показывает представление модели дерева, в которой каждый элемент определяется родителем, номером строки и номером столбца.

Элементы "A" и "C" представлены как верхнеуровневые элементы модели:

 QModelIndex indexA = model->index(0, 0, QModelIndex());
 QModelIndex indexC = model->index(2, 1, QModelIndex());

Элемент "A" имеет множество дочерних объектов. Модельный индекс элемента "B" может быть получен с помощью следующего кода:

 QModelIndex indexB = model->index(1, 0, indexA);

Роли элемента

Элементы модели могут выполнять различные роли для других компонентов, позволяя в различных ситуациях получать различные виды данных. Например, Qt::DisplayRole используется для доступа к строке, которая может отображаться в представлении как текст. Как правило, элементы содержат информацию для нескольких различных ролей, а стандартные роли определяются с помощью Qt::ItemDataRole.

Мы можем запросить у модели информацию об элементе, передав ей модельный индекс, соответствующий элементу и задав роль для получения данных желаемого типа:

 QVariant value = model->data(index, role);

Роли элемента

Роль указывает модели, данные какого типа будут переданы. Представления могут отображать роли различными способами, поэтому важно обеспечить информацию, соответствующую каждой роли.

Раздел Создание новых моделей более подробно описывает несколько необычное использование ролей.

Наиболее частые способы использования элементов данных описываются стандартными ролями, определенными в Qt::ItemDataRole. Снабжая элемент данных информацией для каждой роли, модель может предоставить предпочтения для отображения элемента пользователю представлениями и делегатами. Различные виды представлений имеют возможность интерпретировать эти данные или игнорировать эту информацию, если требуется. Также имеется возможность определять дополнительные, специфические для приложения, роли.

Резюме концепций

Использование модельных индексов

Чтобы продемонстрировать, как данные могут быть получены из модели с помощью модельных индексов, мы создаем QDirModel без представления и отображаем в виджете имена файлов и директорий. Хотя этот пример и не показывает нормального способа использования модели, он демонстрирует соглашения, используемые моделями при работе с модельными индексами.

Мы создаем модель директорий следующим способом:

     QDirModel *model = new QDirModel;
     QModelIndex parentIndex = model->index(QDir::currentPath());
     int numRows = model->rowCount(parentIndex);

В этом случае, мы создаем QDirModel по умолчанию, получив родительский индекс с помощью специфической реализации index(), предоставляемой этой моделью, а с помощью функции rowCount() мы получаем количество строк в модели.

Для простоты, мы интересовались лишь элементами первого столбца модели. Мы рассмотрим каждую строку по очереди, получая модельный индекс для первого элемента каждой строки, и читаем данные, хранящиеся в модели для этого элемента.

     for (int row = 0; row < numRows; ++row) {
         QModelIndex index = model->index(row, 0, parentIndex);

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

         QString text = model->data(index, Qt::DisplayRole).toString();
         // Отображение текста в виджете.

     }

Вышеприведенный пример демонстрирует основные принципы, используемые для восстановление данных из модели:

Дополнительные материалы

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

[Предыдущая: Использование моделей и представлений] [Содержание] [Следующая: Создание новых моделей]


Copyright © 2008 Trolltech Торговые марки
Qt 4.3.5