Для отрисовки графики на виджетах фреймворк Qt предоставляет ряд удобных классов, наиболее важными из которых являются QPainter, QPaintDevice и QPaintEngine.
QPainter применяется для отрисовки самых различных фигур - от простейших линий и текста до диаграмм и управляет системой координат. То есть это то, с помощью чего рисуем.
QPaintDevice является базовым классом объектов, который позволяют 2D-отрисовку с помощью QPainter. QPaintDevice представляет собой абстракцию двумерного пространства, на котором выполняется отрисовка с помощью QPainter. То есть грубо говоря, QPaintDevice - это то, на чем рисуем. Этот класс и вместе с ним функционал отрисовки наследуется такими классами как QWidget, QImage, QPixmap, QPicture и QOpenGLPaintDevice.
QPaintEngine предоставляет интерфейс, который определяет, как QPainter будет выполнять отрисовку на конкретном объекте на конкретной платформе.
QPainter определят несколько функций для рисования графических примитивов:
drawLine(): рисует линию
drawLines(): рисует набор линий
drawRect(): рисует прямоугольник
drawEllipse(): рисует овал
drawArc(): рисует дугу
drawPie(): рисует сектор окружности
drawPath(): рисует геометрический путь
drawPolygon(): рисует многоугольник
drawText(): рисует текст
Кроме того, QPainter предоставляет пару функцию для завливки фигур:
fillRect(): заливает цветом прямоугольную область
fillPath(): заливает цветом геометрический путь
Данные методы могут иметь множество версий с различным набором параметров. Рассмотрим только некоторые.
Если поверхность рисования представлена виджетом Qt, то отрисовка происходит в функции paintEvent
, который имеет следующую сигнатуру:
void QWidget::paintEvent(QPaintEvent *event)
Данная функция является обработчиком события отрисовки виджета. Событие отрисовки может генерироваться при вызове у виджета методов repaint()
или
update()
, после того, как виджет сначала был скрыт, а затем снова стал отображаться, либо в других ситуациях.
Но стоит учитывать, что эта функция определена как виртуальная и имеет модификатор доступа protected, то есть доступна только для классов-наследников.
Поэтому для реализации функции QWidget::paintEvent
, надо создать свой класс виджета, который унаследован от QWidget.
class MyWidget : public QWidget { void paintEvent(QPaintEvent *event) { // отрисовка } };
Начало отрисовки начинается с вызова метода begin() объекта QPainter:
bool QPainter::begin(QPaintDevice *device)
В качестве параметра в метод передается виджет, на котором происходит отрисовка. Если отрисовка началась успешно, то метод возвращает true
, в ином случае возвращается false
Для окончания отрисовки вызывается метод end
bool QPainter::end()
При завершении освобождаются все ресурсы, связанные с отрисовкой. И если объект QPainter больше не является активным, то метод возвращает true
Применение методов:
class MyWidget : public QWidget { void paintEvent(QPaintEvent *event) { QPainter p; p.begin(this); // передаем текущий объект // отрисовка p.end(); } };
Также можно использовать другой подход - вызов конструктора:
class MyWidget : public QWidget { void paintEvent(QPaintEvent *event) { QPainter p(this); // отрисовка } };
Вызов конструктора автоматически вызывает метод begin()
, а вызов деструктора - метод end()
.