QT 4: программирование GUI на С++
Шрифт:
Преобразования рисовальщика
В используемой по умолчанию координатной системе рисовальщика QPainter точка (0, 0) находится в левом верхнем углу устройства рисования; значение координат x увеличивается при перемещении вправо, а значение координат у увеличивается при перемещении вниз. Каждый пиксель занимает область 1 × 1 в координатной системе, применяемой по умолчанию.
Необходимо помнить об одной важной особенности: центр пикселя имеет «полупиксельные» координаты. Например, пиксель в верхнем левом углу занимает область между точками (0, 0)
На первый взгляд эта особенность представляет лишь теоретический интерес, однако она имеет важные практические последствия. Во-первых, смещение +0.5 действует только при отключении сглаживания линий (режим по умолчанию); если режим сглаживания линий включен и мы пытаемся нарисовать пиксель черного цвета в точке (100, 100), QPainter фактически выведет на экран четыре светло-серых пикселя в точках (99.5, 99.5), (99.5, 100.5), (100.5, 99.5) и (100.5, 100.5), чтобы создалось впечатление расположения пикселя точно в точке соприкосновения всех этих четырех пикселей. Если этот эффект нежелателен, его можно избежать, указывая полупиксельные координаты, например (100.5, 100.5).
При начертании таких фигур, как линии, прямоугольники и эллипсы, действуют аналогичные правила. На рис 8.7 показано, как изменяется результат вызова drawRect(2, 2, 6, 5) в зависимости от ширины пера, когда сглаживание линий отключено. В частности, важно отметить, что прямоугольник 6 × 5, вычерчиваемый пером с шириной 1, фактически занимает область размером 7 × 6. Это не делалось прежними инструментальными средствами, в том числе в ранних версиях Qt, но такой подход существенен для получения действительно масштабируемой, независимой от разрешающей способности векторной графики.
Рис. 8.7. Вычерчивание прямоугольника 6 × 5 при отсутствии сглаживания линий.
Теперь, когда мы ознакомились с используемой по умолчанию координатной системой, мы можем внимательно рассмотреть возможные ее изменения при использовании рисовальщиком QPainter области отображения, окна и универсальной матрицы преобразования. (В данном контексте термин «окно» не является обозначением окна виджета верхнего уровня, а термин «область отображения» никак нe связан с областью отображения QScrollArea.)
Термины «область отображения» и «окно» сильно связаны друг с другом. Область отображения является произвольным прямоугольником, заданным в физических координатах. Окно определяет такой же прямоугольник, но в логических координатах. При рисовании мы задаем координаты точек в логической системе координат, и эти координаты с помощью линейного алгебраического преобразования переводятся в физическую систему координат на основе текущих настроек связи «окно—область отображения».
По умолчанию область отображения и окно устанавливаются на прямоугольную область устройства рисования. Например, если этим устройством является виджет размером 320 × 200, область отображения и окно представляют собой одинаковый прямоугольник 320 × 200, верхний левый угол которого располагается в позиции (0, 0). В данном случае системы логических и физических координат совпадают.
Механизм
Пара аргументов (—50, —50) задает начальную точку, а пара аргументов (100, 100) задает ширину и высоту. Это означает, что точка с логическими координатами (—50, —50) теперь соответствует точке с физическими координатами (0, 0), а точка с логическими координатами (+50, +50) соответствует точке с физическими координатами (320, 200). В этом примере мы не изменяли область отображения.
Рис. 8.8. Преобразование логических координат в физические координаты.
Теперь очередь дошла до универсальной матрицы преобразования. Эта матрица используется как дополнение к преобразованию «окно—область отображения». Она позволяет нам перемещать начало координат, изменять масштаб, поворачивать и обрезать графические элементы. Например, если бы нам понадобилось отобразить текст под углом 45°, мы бы использовали такой программный код:
Логические координаты, которые мы передаем функции drawText, преобразуются при помощи универсальной матрицы и затем переводятся в физические координаты, используя связь «окно—область отображения».
Если мы задаем несколько преобразований, они осуществляются в порядке поступления. Например, если мы хотим использовать точку (10, 20) в качестве точки поворота, мы можем перенести начало координат окна, выполнить поворот и затем сделать обратный перенос начала координат окна, устанавливая его в прежнее положение.
Более удобно осуществлять преобразования путем применения соответствующих функций класса QPainter — translate, scale, rotate и shear:
Но если мы хотим регулярно делать одни и те же преобразования, то они будут выполняться более эффективно при их хранении в объекте QMatrix и затем применении универсальной матрицы преобразования для рисовальщика всякий раз, когда требуется выполнить преобразование.
Рис. 8.9. Виджет OvenTimer.