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Двумерный путь, заданный векторами. Путь - это предел для рисуемого примитива в том смысле, что любая фигура (прямоугольник, эллипс) или комбинация фигур могут быть преобразованы в путь. Путь задается контуром и своей областью.
QPaintEngineThe 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
Hosted by uCoz