Home · All Classes · Main Classes · Grouped Classes · Modules · Functions

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

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

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

В архитектуре модель/представление, модель предоставляет стандартный интерфейс, используемый представлениями и делегатами для доступа к данным. В 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 © 2005 Trolltech Trademarks
Qt 4.1.0
Hosted by uCoz