| Home · All Classes · Main Classes · Grouped Classes · Modules · Functions |
Устройство рисования Qt - это двумерная поверхность, на которой может производиться рисование. QWidget, QPixmap, QPicture и QPrinter - все это устройства рисования. QPainter - это объект, который может рисовать на этих устройствах.
По умолчанию, начало системы координат располагается в левом-верхнем углу. Координата x увеличивается слева-направо, а координата y увеличивается сверху-вниз. По умолчанию, единицей измерения считается пиксель для устройств рисования, основанных на пикселях, и пункт (1/72 дюйма) для принтеров.
На следующей иллюстрации показан сильно увеличенный верхний-правый угол устройства рисования.

Прямоугольник и линия на диаграмме нарисованы с помощью следующего кода (добавлены лишь сетка и обозначения координат):
void MyWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setPen(Qt::darkGray);
painter.drawRect(1, 2, 4, 3);
painter.setPen(Qt::lightGray);
painter.drawLine(9, 2, 7, 7);
}
Обратите внимание на то, что, хотя мы и задали размеры QPainter::drawRect() 3 x 4, фактически, прямоугольник нарисован с размерами 5 x 4 пикселей. Это соответствует современным графическим API.
Заданный размер прямоугольника - это математический размер без учета толщины пера. Он имеет смысл при выполнении преобразований (масштабирование, обрезание и т.д.). Тоже относится ко всем соответствующим функциям QPainter (например, drawRoundRect(), drawEllipse()).
QPainter::drawLine() выполняет рисование линии по двум точкам.
Вот классы, имеющие наиболее близкое отношение к системе координат. Некоторые классы имеют две версии: версия на основе значений int и версия на основе значений qreal. В этом случае, название версии для qreal оканчивается на F.
| Класс | Описание |
|---|---|
| QPoint(F) | Простая точка на плоскости. Большинство функций Qt, которые имеют дело с точками, могут принимать в качестве параметров QPoint, QPointF, два значения int, или два значения qreal. |
| QSize(F) | Простой вектор на плоскости. Внутренне, QPoint и QSize одинаковы, но точка не то-же самое, что и размер, поэтому имеют место оба класса. И снова, большинство классов, принимают QSizeF, QSize, два значения int, или два значения qreal. |
| QRect(F) | Прямоугольник на плоскости. Большинство функций принимают QRectF, QRect, четыре значения int, или четыре значения qreal. |
| QLine(F) | Линия конечной длины на плоскости, задаваемая начальной и конечной точками. |
| QPolygon({QPolygonF}{F}) | Многоугольник на плоскости. Многоугольник - это вектор значений QPoint(F). Если первая и последняя точки совпадают, то многоугольник замкнут. |
| QPaintDevice | Устройство, на котором Вы можете рисовать. В Qt уже есть несколько устройств: виджеты, пиксельный карты, рисунки и др. |
| QPainter | Рисующий класс. С помощью одного и того-же кода может рисовать на любом устройстве рисования. Между устройствами рисования есть различия (QPrinter::newPage() служит хорошим примером этому), но QPainter работает одинаково со всеми устройствами рисования. |
| QMatrix | Матрица трансформаций размером 3 x 3. QMatrix используется для вращения, обрезки, масштабирования и трансформаций системы координат. |
| QPainterPath | Двумерный путь, заданный векторами. Путь - это предел для рисуемого примитива в том смысле, что любая фигура (прямоугольник, эллипс) или комбинация фигур могут быть преобразованы в путь. Путь задается контуром и своей областью. |
| QPaintEngine | The base class for painter backends. Qt includes several backends. You normally don't need to use this class directly. |
| QRegion | Область устройства рисования, определяемая списком QRect. Вообще, мы рекомендуем, для задания области, использовать векторный класс QPainterPath вместо QRegion, так как QPainterPath намного лучше работает с преобразованиями живописца. |
По умолчания начало системы координат (0, 0) расположено в верхнем-левом углу. Также QPainter поддерживает произвольные преобразования, осуществляемые с помощью матрицы преобразований. Используйте эту матрицу для расположения Ваших объектов в Вашей модели. Для работы с этой матрицей, Qt предоставляет методы типа QPainter::rotate(), QPainter::scale(), QPainter::translate() и т.д.
QPainter::save() и QPainter::restore() сохраняют и восстанавливают эту матрицу. Если Вам многократно требуются одни и те же преобразования, то Вы можете использовать объекты QMatrix и функции QPainter::matrix() и QPainter::setMatrix().
Часто матрица требуется для выполнения одних и тех-же преобразований на разных устройствах рисования. Без преобразований, результаты сильно зависят от разрешения устройства рисования. Принтеры, обычно, имеют разрешение, равное 600 точкам на дюйм, в то время, как разрешение монитора, обычно, имеет значение между 75 и 100 точками на дюйм.
Вот короткий пример использования матрицы для рисования циферблата часов из примера widgets/analogclock. Мы рекомендуем откомпилировать и запустить этот пример прежде, чем Вы продолжите чтение. В частности, попытайтесь установить различные размеры окна приложения.
void AnalogClock::paintEvent(QPaintEvent *)
{
static const QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40)
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70)
};
QColor hourColor(127, 0, 127);
QColor minuteColor(0, 127, 127, 191);
int side = qMin(width(), height());
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2);
painter.scale(side / 200.0, side / 200.0);
Сперва мы настраиваем живописца. Мы перемещаем точку (0, 0) системы координат в центр виджета, вместо верхнего-левого угла. Мы также масштабируем систему координат на side / 100, где side - является минимальным значением из ширины или высоты виджета. Мы хотим, чтобы часы были квадратными, даже, если устройство рисования не квадратно.
Мы получаем квадратную область размером 100 x 100, в которой мы можем рисовать, с точкой (0, 0), расположенной в центре. В результате мы рисуем в максимально возможной квадратной области, при данных размерах виджета.
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
Мы рисуем часовую стрелку с помощью вращения системы координат и вызова QPainter::drawConvexPolygon(). Благодаря вращению, мы можем ограничиться рисованием стрелки, направленной вниз.
Многоугольник задается массивом чередующихся значений x и y, хранящимся в статической переменной hourHand (определенной в начале функции), который соответствует четырем точкам (2, 0), (0, 2), (-2, 0) и (0, -25).
Окружение кода вызовами QPainter::save() и QPainter::restore() гарантирует, что окружающий код не будет поврежден использоваными нами преобразованиями.
painter.save();
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
То-же самое мы далаем для минутной стрелки, которая определяется четырьмя точками (1, 0), (0, 1), (-1, 0) и (0, -40). Эти координаты определяют более тонкую и длинную, чем часовая, стрелку.
for (int j = 0; j < 60; ++j) {
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
И, наконец, мы рисуем циферблат часов, который состоит из двенадцати коротких отрезков, расположенных через 30 градусов. При этом мы вращаем живописец, это не очень практично, но так тоже можно.
| Copyright © 2005 Trolltech | Trademarks | Qt 4.1.0 |