Журнал LinuxFormat - перейти на главную

LXF105:Qt4

Материал из Linuxformat
Версия от 09:13, 15 апреля 2009; Crazy Rebel (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск
Программирование в стиле Qt Осваиваем технологии, лежащие в основе нашумевшего KDE4

Новый взгляд на старую графику

ЧАСТЬ 4 Представьте себе Сокобан, а потом – замените ящики на кнопки и поля ввода. Ничего себе дизайнер интерфейсов? Со средой Graphics View возможно и не такое, утверждает Андрей Боровский.
– А что у них за игра? Шахматы? Или какой-нибудь «стартрек»?
– Нет, здесь игра для профессионалов... Садишься за штурвал воображаемого космолета и определяешь гравитацию незнакомой тебе планеты. Ее автомат подбирает случайным образом.
М. Пухов, Путь к Земле («Кон-Тики»).

Среда Graphics View Framework, появившаяся в Qt начиная с версии 4.2, пришла на смену графической системе, основанной на классе QCanvas. Graphics View Framework – это не только система вывода графики с широкими возможностями, но и готовая реализация парадигмы «модель-вид-контроллер» (Model-View-Controller, MVC) для программ, работающих с 2D-изображениями. Мы уже встречались с шаблоном MVC, когда изучали каркас Interview Framework, предназначенный для работы с данными, хранящимися в форме таблиц. Graphics View Framework распространяет те же идеи на двумерную графику. Для объяснения преимуществ Interview Framework мы пользовались программой, работающей с базой данных. Возможности же Graphics View Framework проще всего продемонстрировать на примере компьютерной аркады.

Предположим, вы решили написать двумерную видеоигру. Применение подхода «модель-контроллер-вид» может существенно упростить процесс создания такой программы. Описание игрового мира представляет собой модель данных программы. Визуализацию сцены выполняет объект отображения (вид). Контроллер транслирует действия пользователя в события модели. Система Graphics View Framework предоставляет вам заготовки для создания модели, контроллера и объекта отображения, изначально наделенные широкой функциональностью. Кроме того, Graphics View Framework берет на себя решение таких задач, как обнаружение столкновений (collision detection) и геометрические преобразования изображений.

Разумеется, Graphics View Framework может найти применение не только в играх, но и в любых программах, которым приходится отображать интерактивные графические модели, состоящие из большого числа элементов.


Основу Graphics View Framework составляют три Qt-класса, представленные на схеме (рис. 1).

Модель данных реализована с помощью объекта класса QGraphicsScene. Элементами модели данных являются графические примитивы (геометрические фигуры и растровые изображения). Все графические примитивы реализованы с помощью классов-потомков класса QGraphicsItem. Таким образом, объект класса QGraphicsScene можно рассматривать как контейнер для набора объектов классов- потомков QGraphicsItem. Для отображения модели, созданной в QGraphicsScene, служит объект класса QGraphicsView. Работая в среде Graphics View Framework, вы не рисуете изображение непосредственно в окне QGraphicsView (хотя в принципе это делать можно). Вместо этого вы управляете объектами, хранящимися в модели QGraphicsScene. Все изменения объектов модели автоматически отображаются в окне QGraphicsView. При этом вам не нужно заботиться о таких вещах, как перерисовка изображения при изменении размеров окна. Поскольку объект класса QGraphicsView связан с моделью, он «знает», что нужно отображать в окне, и обновляет содержимое автоматически.

Вторая важная задача, которую решает связка объектов QGraphicsView и QGraphicsScene – преобразование действий пользователя (таких, как щелчок мышью, перемещение курсора над объектом или нажатие клавиши) в события модели. Последние могут быть переданы отдельным примитивам, формирующим модель. Эта система передачи событий между разными уровнями Graphics View Framework именуется в документации Qt термином «event propagation».

Упомянутые выше функции обнаружения столкновений и геометрических преобразований реализованы в классах QGraphicsScene и QGraphicsItem. Все эти операции выполняются независимо от уровня отображения (на него передается только конечный результат операций). Так же, как и в системе Interview Framework, с одной моделью Graphics View может быть связано несколько объектов отображения.

Первая проба

Рассмотрим работу простейшего приложения Graphics View Framework, выводящего на экран статическое изображение. Эта программа должна выполнить минимальную последовательность операций, необходимых для работы с Graphics View Framework: создать объекты QGraphicsScene и QGraphicsView и связать их между собой, затем заполнить объект QGraphicsScene графическими примитивами и сделать объект QGraphicsView видимым. Написание программы мы начнем с редактирования визуальной части.

Виджет QGraphicsView расположен на панели виджетов Qt Designer в разделе Display Widgets. Класс QGraphicsView является потомком Qframe, и его удобно сделать центральным визуальным элементом главного окна. Далее в программе следует создать объект класса QGraphicsScene (это можно сделать, например, в конструкторе главного окна). С помощью метода setScene() объекта QGraphicsView мы связываем объект QGraphicsScene с объектом QGraphicsView.

  QGraphicsScene * scene = new QGraphicsScene;
  graphicsView->setScene(scene);

Добавлять графические примитивы в объект QGraphicsScene можно разными способами, в том числе с помощью методов группы Add* класса QGraphicsScene. Например, для того, чтобы добавить в сцену эллипс, следует вызвать:

scene->addEllipse(QRectF(-100.0, -100.0, 100.0, 100.0));

где scene – объект QGraphicsScene. Обратите внимание на то, что параметры эллипса (точнее, координаты углов прямоугольника, в который он вписан) задаются числами с плавающей точкой, а не целыми, как обычно принято в растровой графике. Ниже мы увидим, что встроенная в Graphics View система геометрических преобразований, а также наличие нескольких систем координат, делают использование чисел с плавающей точкой совершенно необходимым. Координаты, которые мы указали при добавлении эллипса, являются координатами модели, а не графического окна. При отображении модели объектом QGraphicsView они будут автоматически переведены в координаты окна QgraphicsView.

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

Коль скоро речь зашла о координатах, следует отметить, что помимо систем координат окна и модели нам придется иметь дело с еще одной системой координат – системой координат примитива. У каждого графического примитива есть своя система координат, которая используется при выполнении над ним геометрических преобразований (перенос, вращение, масштабирование). Мы подробно займемся ею ниже.

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

  Теперь мы должны сделать объект QGraphicsView видимым с

помощью метода show(). Далее можно скомпилировать программу. Система Graphics View является частью ядра Qt, поэтому подклю- чать дополнительные модули нам не требуется. В результате работы нашей программы мы получаем окно, в котором на белом фоне изо- бражена черная окружность. Рисунок этот, конечно, не особенно впе- чатляет, но зато наше знакомство с Graphics View Framework можно считать состоявшимся. Пишем свою игру Для более подробного знакомства с возможностями Graphics View мы напишем обещанную игру – подобие всем известного «Сокобана» (рис. 2). Напомню правила этой древней и мудрой игры: по лабирин- ту ходит грузчик, задача которого заключается в том, чтобы пере- нести хаотично разбросанные ящики в заранее определенное место. Грузчик может только толкать ящик перед собой (тащить его он не умеет), причем в каждый момент времени он может толкать только один ящик. Полный исходный текст программы вы найдете на диске в файле sokoban.tar.gz.

Персональные инструменты
купить
подписаться
Яндекс.Метрика