Короткий ответ
Qt MVC применяется только к одной структуре данных . Говоря о приложении 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.