Модели и представления в виджетах

Введение в архитектуру View/Model

Последнее обновление: 11.01.2024

Для организации сложных комплексных приложений фреймворк Qt применяет архутектуру View/Model (Представление/Модель), которая является модификацией паттерна MVC.

Традиционный паттерн MVC или Model-View-Controller (Модель-Представление-Контроллер) состоит из трех элементов:

  • Модель: описывает используемые в приложении данные, а также логику, которая связана с данными, например, логику валидации данных или другую бизнес-логику.

  • Представление: компонент, который определяет визуальный интерфейс

  • Контроллер: компонент для обработки пользовательского ввода. Через контроллер идет взаимодействие пользователя с приложением

архитектура MVC - Model-View-Controller в Qt

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

В Qt представление и контроллер объединены, в результате чего образуется архитектура Model/View (модель/представление). Такая архитектура обеспечивает более простую структуру, и при этом механизм хранения данных и работы с ними по-прежнему отделен их представления пользователю. Такое разделение позволяет отображать одни и те же данные в нескольких разных представлениях и реализовывать новые типы представлений без изменения базовых структур данных. Для обеспечения гибкой обработки пользовательского ввода фреймворк Qt вводит концепцию делегата. Преимущество наличия делегата в этой структуре заключается в том, что он позволяет настраивать способ отображения и редактирования элементов данных.

архитектура Model-View в Qt

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

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

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

Модель

Базовым классом всех моделей является класс QAbstractItemModel. Этот класс определяет интерфейс, который используется представлениями и делегатами для доступа к данным. Сами данные не обязательно должны храниться в модели. Они может храниться в структуре данных или репозитории, предоставляемом отдельным классом, файле, базе данных или в каком-либо другом компоненте приложения.

Тип QAbstractItemModel предоставляет интерфейс для данных, достаточно гибкий для работы с самыми разными представлениями данных - в виде таблиц, списков и деревьев.

Представление данных с помощью моделей в Qt

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

  • QStringListModel: используется для хранения простого списка элементов QString

  • QStandardItemModel управляет более сложными древовидными структурами элементов, каждый из которых может содержать произвольные данные.

  • QFileSystemModel предоставляет информацию о файлах и каталогах в локальной файловой системе.

  • QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel используются для доступа к базам данных

Иерархия классов моделей в Qt

Представления

Представления (Views) представляют объекты классов, унаследованных от абстрактного класса QAbstractItemView. Для различных типов представлений предусмотрен ряд реализаций:

  • QListView отображает список элементов

  • QTableView отображает данные из модели в виде таблицы

  • QTreeView показывает данные модели в виде дерева

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

Иерархия классов представлений view в Qt

Делегаты

Делегаты обеспечивают контроль над представлением элементов, отображаемых в представлении. Шаблон M/V, в отличие от шаблона MVC, не имеет специального компонента для обработки ввода пользователя. Представление в первую очередь отвечает за отображение данных модели пользователю и позволяет ему взаимодействовать с ней. Чтобы добавить некоторую гибкость в способ получения действий пользователя, ввод пользователя обрабатываются делегатами.

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

Иерархия классов делегатов в Qt

Простейший пример View-Model

Рассмотрим простейший пример связи модели и представления:

#include <QApplication>
#include <QWidget>
#include <QListView>
#include <QStringListModel>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget* widget = new QWidget;
    widget->setWindowTitle("METANIT.COM");
    widget->setMinimumHeight(150);
    widget->setMinimumWidth(250);

    // определяем данные для модели
    QStringList list = { "Tom", "Bob", "Sam" };
    // определяем модель
    QStringListModel *model = new QStringListModel(list);

    // определяем представление
    QListView *view = new QListView(widget);
    // устанавливаем модель для представления
    view->setModel(model);

    widget->show();
    return a.exec();
}

Здесь модель представляет объект QStringListModel, который инкапсулирует список строк. Собственно список строк - QStringList - это и есть те данные, с которыми работает модель.

В качестве представления здесь применяется объект QListView - виджет, который отображает элементы модели в сиде списка. Для установки модели у представления применяется метод setModel(), в который передается объект модели:

view->setModel(model);

Таким образом, QListView будет связан с моделью QStringListModel и автоматически отобразит ее данные.

связь модели и представления в Qt
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850