На этом шаге рассмотрим иерархию классоы рисования.
Под технологией рисования подразумевается новая архитектура для рисования, создание которой началось с желания использовать методы рисования QPainter в OpenGL. Затем появилось множество других идей: от точного представления в вещественных координатах до отображения векторной графики, которые получили свое воплощение в этой архитектуре.
Три краеугольных камня этой технологии составляют классы QPainter, QPaintEngine и QPaintDevice (рис. 1).
Рис.1. Взаимосвязь классов
Класс QPaintEngine используется классами QPainter и QPaintDevice неявно и для разработчиков не интересен, если нет необходимости создавать свой собственный контекст рисования. Если же такая необходимость возникла, то вам придется унаследовать этот класс и реализовать некоторые методы.
Основной класс для программирования графики, с которым придется иметь дело, — это QPainter. С его помощью можно рисовать точки, линии, эллипсы, полигоны, кривые Безье, растровые изображения, текст и многое другое. Более того, класс QPainter поддерживает режим сглаживания (antialiasing), прозрачность и градиенты.
Контекст рисования QPaintDevice можно представить себе как поверхность для вывода графики. QPaintDevice — это основной абстрактный класс для всех классов объектов, которые можно рисовать. От него унаследована целая серия классов, показанных на рис. 2.
Рис.2. Иерархия классов контекста рисования
В основном, рисование выполняется из метода обработки события QPaintEvent. Если пользователь запустит программу и выполнит некоторые действия, вследствие которых будет перекрыто, частично или полностью, окно программы, то после того, как оно откроется, будет сгенерировано событие перерисовки и вызван метод QWidget::paintEvent() для тех виджетов, которые должны быть перерисованы. Сам объект события QPaintEvent содержит метод region(), который возвращает область для перерисовки. Метод QPaintEvent::rect() возвращает прямоугольник, который охватывает эту область.
Для подавления эффекта мерцания Qt использует технику двойной буферизации (double buffering). Двойная буферизация представляет собой очень распространенное и простое решение этой проблемы. Суть заключается в формировании изображения в невидимой области (буфере). Когда изображение будет сформировано, оно помещается в видимую область (буфер) за один раз. Это выполняется автоматически, и вам не нужно реализовывать код для этого в paintEvent().
Эффекта прозрачности можно добиться, установив для рисования цвет, содержащий значение прозрачности альфа-канала. Это значение может изменяться от 0 до 255. Значение 0 говорит том, что цвет полностью прозрачен, а 255 означает полную непрозрачность.
На следующем шаге рассмотрим класс QPainter.