Краткий ответ
MVC Qt применяется только к одной структуре данных . Говоря о приложении MVC , вы не должны думать о QAbstractItemModel
или QListView
.
Если вам нужна архитектура MVC для всей вашей программы, у Qt нет такой «огромной» структуры модель / представление. Но для каждого списка / дерева данных в вашей программе вы можете использовать подход Qt MVC, который действительно имеет контроллер в своем представлении. Данные находятся внутри или снаружи модели; это зависит от того, какой тип модели вы используете (собственный подкласс модели: возможно, внутри модели; например, QSqlTableModel: вне (но может быть кэшировано внутри) модели). Чтобы соединить ваши модели и представления, используйте собственные классы, которые затем реализуют бизнес-логику .
Длинный ответ
Подход и терминология модели / представления Qt:
Qt предоставляет простые представления для своих моделей. В них встроен контроллер : выбор, редактирование и перемещение элементов - это то, что в большинстве случаев контролирует «контроллер». То есть интерпретировать пользовательский ввод (щелчки и движения мыши) и давать соответствующие команды модели.
Qt модели действительно являются моделями, имеющими базовые данные. Конечно, абстрактные модели не содержат данных, поскольку Qt не знает, как вы хотите их хранить. Но вы расширяете QAbstractItemModel для ваших нужд, добавляя контейнеры данных в подкласс и предоставляя интерфейсу модели доступ к вашим данным. На самом деле, и я предполагаю, что вам это не нравится, проблема в том, что вам нужно запрограммировать модель, чтобы получить доступ к данным и их изменение в структуре данных.
В терминологии MVC модель содержит как данные , так и логику . В Qt вам решать, включать или не включать часть вашей бизнес-логики в вашу модель или не использовать ее как отдельную «точку зрения». Непонятно даже, что подразумевается под логикой: выбор, переименование и перемещение предметов? => уже реализовано. Делать с ними расчеты? => Поместите его снаружи или внутри подкласса модели. Хранение или загрузка данных из / в файл? => Поместите его в подкласс модели.
Мое личное мнение:
Очень сложно обеспечить хорошую и общую систему MV (C) для программиста. Поскольку в большинстве случаев модели просты (например, только списки строк), Qt также предоставляет готовый к использованию QStringListModel. Но если ваши данные более сложны, чем строки, вам решать, как вы хотите представить данные через интерфейс модели / представления Qt. Если у вас есть, например, структура с 3 полями (скажем, лица с именем, возрастом и полом), вы можете назначить 3 поля для 3 разных столбцов или 3 разных ролей. Мне не нравятся оба подхода.
Я думаю, что каркас модели / представления Qt полезен только тогда, когда вы хотите отобразить простых структур данных . Обработка становится затруднительной, если данные имеют пользовательских типов или структурированы не в виде дерева или списка (например, графика). В большинстве случаев списков достаточно, и даже в некоторых случаях модель должна содержать только одну запись. Особенно, если вы хотите смоделировать одну единственную запись, имеющую разные атрибуты (один экземпляр одного класса), каркас модели / представления Qt не является правильным способом отделения логики от пользовательского интерфейса.
Подводя итог, я думаю, что каркас модели / представления Qt полезен тогда и только тогда, когда ваши данные просматриваются одним из виджетов средства просмотра Qt . Это абсолютно бесполезно, если вы собираетесь написать своего собственного зрителя для модели, содержащей только одну запись, например настройки вашего приложения, или если ваши данные не для печати.
Как я использовал модель / представление Qt в (большем) приложении?
Я однажды написал (в команде) приложение, которое использует несколько моделей Qt для управления данными.Мы решили создать DataRole
для хранения фактических данных различного пользовательского типа для каждого подкласса модели.Мы создали внешний класс модели под названием Model
, содержащий все различные модели Qt.Мы также создали внешний класс представления под названием View
, содержащий окна (виджеты), которые связаны с моделями в Model
.Таким образом, этот подход представляет собой расширенный Qt MVC, адаптированный к нашим собственным потребностям.Сами классы Model
и View
не имеют никакого отношения к Qt MVC.
Куда мы поместили логику ?Мы создали классы, которые выполняли фактические вычисления данных, считывая данные из исходных моделей (когда они изменились) и записывая результаты в целевые модели.С точки зрения Qt, эти логические классы будут представлениями, так как они «подключаются» к моделям (не «представление» для пользователя, а «представление» для части бизнес-логики приложения).
Где контроллеры ?В исходной терминологии MVC контроллеры интерпретируют пользовательский ввод (мышь и клавиатура) и дают команды модели для выполнения запрошенного действия.Поскольку представления Qt уже интерпретируют пользовательский ввод, такой как переименование и перемещение элементов, в этом не было необходимости.Но нам нужна была интерпретация взаимодействия с пользователем, которая выходит за рамки представлений Qt.