Одним из наиболее распространенных и эффективных методов разработки программ является использование шаблона программирования MVC (Модель-Представление-Контроллер).
MVC позволяет разделить части программы, отвечающие за хранение и доступ к данным, отображение данных и взаимодействие с пользователем, на отдельные слабосвязанные модули.
Такое разделение ответственности упрощает структуру программы и позволяет вносить изменения в одну из этих частей, не затрагивая другие.
Этот подход активно используется в Qt, да и в QML вообще он является краеугольным.
Так что для тех, кто изучает QML, понимание принципов MVC лишним не будет. Представление модели в QML:
- Модель-представление в QML. Часть нулевая, вводная.
- Модель-представление в QML. Часть первая: представления на основе готовых компонентов
- Модель-представление в QML. Часть вторая: Пользовательские представления
- Модель-представление в QML. Часть третья: Модели в QML и JavaScript
- Модель-представление в QML. Часть четвертая: Модели C++
Что такое МВК
Разделение обязанностей — один из фундаментальных принципов программирования.Его суть заключается в разделении программы на функциональные блоки, каждый из которых отвечает за свою часть работы.
Этими блоками могут быть функции, объекты, модули и т. д. Блоки взаимодействуют друг с другом через определенные интерфейсы.
Это дает некоторую независимость блоков относительно друг друга и снижает сложность системы.
Основные концепции графического пользовательского интерфейса (GUI) были разработаны в лаборатории Xerox в 70-х годах двадцатого века.
К ним относится шаблон проектирования MVC, разработанный для уменьшения сложности и упрощения архитектуры программ с графическим пользовательским интерфейсом с использованием того же разделения задач.
Итак, суть этого паттерна в том, чтобы разделить программу на три компонента.
- Модель.
Отвечает за данные и обеспечивает доступ к ним.
- Производительность.
Отвечает за отображение данных, полученных из модели.
- Контроль.
Отвечает за взаимодействие с пользователем.
Можно изменять данные в модели.
Между этими компонентами существуют определенные интерфейсы, которые позволяют отделить их друг от друга.
В идеале эти модули должны быть вообще независимы друг от друга и позволять вносить изменения или даже полную замену любого модуля без переделки остальных.
С развитием графических интерфейсов и появлением новых типов программ, например веб-приложений, такой вариант разделения подходит уже не везде.
Поэтому и появились его разновидности, такие как MVVC, MVP и т. д. Все разновидности этой модели в дальнейшем я буду вообще называть MVC. Многие современные фреймворки используют MVC и содержат инструменты для разделения программы в соответствии с этим шаблоном.
Поскольку одним из основных предназначений Qt является разработка графических пользовательских интерфейсов, без MVC также не обойтись и в состав Qt входит его собственная вариация — фреймворк Model-View.
MVC в Qt и QML
Основная идея использования этого паттерна в Qt — разделение данных и их отображение.
Здесь модель отвечает за данные и доступ к ним.
Поскольку в графическом интерфейсе за отображение элементов и получение входных данных от пользователя часто отвечают одни и те же элементы, логично объединить представление и управление.
Именно это и сделано в Qt: представление не только отображает данные, но и выполняет функции управления и отвечает за взаимодействие с пользователем.
Но чтобы не потерять гибкость из-за такого объединения, было введено понятие делегата.
Делегат позволяет определить, как эти данные будут отображаться и как пользователь может их изменить.
Представление, по сути, теперь является контейнером для экземпляров делегатов.
В QML этот принцип также применим, даже в гораздо большей степени.
Как я уже говорил, Model-View — это одна из фундаментальных концепций QML. Одна из основных целей QML — выделить интерфейс программы в отдельную часть, которая может быть очень гибкой и легко адаптируемой к различным потребностям.
Например, для десктопного приложения может быть один вариант интерфейса, а для мобильного — другой.
В этом случае ядро программы (модели) можно написать на языке C++ и оставить неизменным.
Также стоит отметить, что для некоторых моделей в QML делегаты могут только отображать данные, но не редактировать их.
Несмотря на то, что интерфейсная часть является основным местом использования QML, модель можно реализовать и на ней, для этого есть соответствующие инструменты.
При желании программу можно практически полностью сделать на QML/JavaScript и сократить количество кода на C++ до минимума.
Это программа, с которой мы начнем.
Простой пример MVC в QML
Рассмотрим программу, которая отображает пару цветных прямоугольников с текстом посередине.
Модель здесь представляет собой объект типа ListModel. В качестве элементов модели мы используем два дочерних объекта специального типа ListElement, в которых мы определили два свойства: цвет и текст. Для отображения мы используем объект типа ListView, которому в качестве модели указываем id нашего объекта типа ListModel. Представление само по себе не знает, какие данные отображать, поэтому нам также необходимо предоставить ему делегат. Делегат в QML — это тип объекта, экземпляр которого создается для каждого элемента модели.import QtQuick 2.0 Rectangle { width: 360 height: 360 ListModel { id: dataModel ListElement { color: "orange" text: "first" } ListElement { color: "skyblue" text: "second" } } ListView { id: view anchors.margins: 10 anchors.fill: parent spacing: 10 model: dataModel delegate: Rectangle { width: view.width height: 100 color: model.color Text { anchors.centerIn: parent renderType: Text.NativeRendering text: model.text } } } }
А ListView в свою очередь создает эти объекты, отображает их в виде списка и обеспечивает навигацию по ним.
Делегат представляет собой прямоугольник с текстом посередине.
Цвет и текст прямоугольника взяты из модели.
Внутри делегата видны все свойства элементов модели — т.н.
«роли».
Доступ к ним возможен через специальный объект модели, а также напрямую, т.е.
можно просто написать цвет. Я предпочитаю писать полностью, так понятнее откуда берутся данные и не будет конфликтов, если у делегата будут свойства с одинаковыми именами.
Результат выполнения выглядит примерно так:
Динамика в представлении модели
В MVC модель может быть пассивной или активной.Пассивная модель — это модель, которая просто хранит данные и никак не влияет на контроллер или представление.
Соответственно, когда данные в модели меняются, она никак не может сообщить об этом представлению.
В этом случае контроллер отслеживает все изменения в модели, а также сообщает представлению, что информацию необходимо обновить.
Активная модель может уведомлять представления об изменении данных.
В свою очередь, вид может отражать эти изменения.
Этот вариант считается классической реализацией MVC. Qt и QML используют активную модель.
Это дает нам возможность изменять данные в модели и не беспокоиться об отображении обновленных данных — представление сделает все за нас.
Давайте существенно улучшим предыдущий пример: добавим кнопку, которая будет добавлять элементы в модель при нажатии.
import QtQuick 2.0
Rectangle {
width: 360
height: 360
ListModel {
id: dataModel
}
Column {
anchors.margins: 10
anchors.fill: parent
spacing: 10
ListView {
id: view
width: parent.width
height: parent.height - button.height - parent.spacing
spacing: 10
model: dataModel
clip: true
delegate: Rectangle {
width: view.width
height: 40
color: "skyblue"
Text {
anchors.centerIn: parent
renderType: Text.NativeRendering
text: model.index
}
}
}
Rectangle {
id: button
width: 100
height: 40
anchors.horizontalCenter: parent.horizontalCenter
border {
color: "black"
width: 1
}
Text {
anchors.centerIn: parent
renderType: Text.NativeRendering
text: "Add"
}
MouseArea {
anchors.fill: parent
onClicked: dataModel.append({})
}
}
}
}
Изначально модель не содержит никаких элементов.
При нажатии кнопки в модель добавляется пустой элемент без свойств.
Модель сообщает представлению, что был добавлен новый элемент. Для каждого нового элемента представление создает объект, тип которого мы указали как делегат. Помимо свойств, которые мы описываем в элементах модели, в делегате будет доступно еще одно — index (или model.index), содержащий индекс элемента в модели и, соответственно, в отображении.
Итак, несмотря на то, что мы добавляем в модель пустой элемент, одно свойство там все равно есть и именно индекс мы используем в качестве текста.
Запустив программу и нажав кнопку, получим примерно следующее:
Я показал два простых примера, иллюстрирующих отделение данных от отображения и использование делегатов для управления отображением данных.
В следующем тексте я буду ссылаться на эти два примера, чтобы не приводить весь их код.
Небольшой вывод
Разработанная более 30 лет назад технология MVC не утратила своей актуальности.По сей день это основа для разработки программ с графическим интерфейсом; Сейчас сложно представить такую программу, которая не использует MVC. Как технология, предназначенная для создания графических интерфейсов, Qt и особенно QML имеют полную поддержку MVC. Необходимые инструменты включены в библиотеки; более того, в самой Qt достаточно четко видна идеология этого шаблона.
Соответственно, использование MVC здесь естественно и это именно то, что задумали разработчики и именно с таким видением создавался фреймворк.
На этом вводную часть можно считать завершенной, и в следующей статье мы рассмотрим презентации более подробно.
Теги: #Qt #qt5 #qml #qt fast #контроллер представления модели #MVC #программирование #Qt #проектирование и рефакторинг
-
Положение О Сертификации Фстэк России
19 Oct, 24 -
Какие Адреса Мы Видим В Трассировке?
19 Oct, 24 -
Инфографика: Взлет И Падение Yahoo
19 Oct, 24 -
Корпоративная Свинья
19 Oct, 24 -
Умей Говорить «Нет» И Умей Говорить «Да»
19 Oct, 24 -
Газеты Сша Создают Единую Рекламную Площадку
19 Oct, 24