Рис. 10.1. Архитектура модель/представление в Qt.
В Qt используется вдохновленная подходом MVC архитектура модель/представление. Здесь модель имеет такие же функции, как и в классическом методе MVC. Но вместо контроллера в Qt используется немного другое понятие: делегат (delegate). Делегат обеспечивает более тонкое управление воспроизведением и редактированием элементов. Для каждого типа представления в Qt предусмотрен делегат по умолчанию. Для большинства приложений вполне достаточно пользоваться таким делегатом, поэтому обычно нам не приходится заботиться о нем.
Применяя архитектуру Qt модель/представление, мы можем использовать модели, которые представляют только те данные, которые действительно необходимы для отображения в представлении. Это значительно повышает скорость обработки очень больших наборов данных и уменьшает потребности в памяти по сравнению с подходом, требующим считывания всех данных. Связывая одну модель с двумя или более представлениями, мы можем предоставить пользователю возможность за счет незначительных дополнительных издержек просматривать данные и взаимодействовать с ними различными способами. Qt автоматически синхронизирует множественные представления данных — изменения в одном из представлений отражаются во всех других. Дополнительное преимущество архитектуры модель/представление проявляется в том, что если мы решаем изменить способ хранения исходных данных, нам просто потребуется изменить модель; представления по-прежнему будут работать правильно.
Во многих случаях пользователю необходимо работать только с относительно небольшим количеством элементов. В такой ситуации, как правило, мы можем использовать удобные классы Qt по отображению элементов (QListWidget, QTableWidget и QTreeWidget), непосредственно заполняя все элементы значениями. Эти классы работают подобно классам отображения элементов в предыдущих версиях Qt. Они хранят свои данные в «элементах» (например, QTableWidget содержит элементы QTableWidgetltem). При реализации этих удобных классов используются пользовательские модели, обеспечивающие появление требуемых элементов в представлениях.
Рис. 10.2. Одна модель может обслуживать несколько представлений.
При использовании больших наборов данных часто оказывается недопустимым дублирование данных. В этих случаях мы можем применять классы Qt по отображению элементов (QListView, QTableView и QTreeView) в сочетании с моделью данных, которой может быть как пользовательская модель, так и одна из заранее определенных в Qt моделей. Например, если набор данных хранится в базе данных, мы можем использовать QTableView в сочетании с QSqlTableModel.
Применение удобных классов отображения элементов
Удобные Qt—подклассы отображения элементов обычно использовать проще, чем определять пользовательскую модель, и они особенно удобны, когда разделение модели и представления нам не дает преимущества. Мы использовали этот подход в главе 4, когда создавали подклассы QTableWidget и QTableWidgetItem для реализации функциональности электронной таблицы.
В данном разделе мы покажем, как можно применять удобные классы отображения элементов для вывода на экран элементов. В первом примере приводится используемый только для чтения виджет QListWidget, во втором примере — редактируемый QTableWidget и в третьем примере — используемый только для чтения QTreeWidget.
Мы начинаем с простого диалогового окна, которое позволяет пользователю выбрать из списка символ, используемый в блок-схемах программ. Каждый элемент состоит из пиктограммы, текста и уникального идентификатора.