Чтение онлайн

на главную - закладки

Жанры

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

В цикле for мы рисуем минутные отметки по внешней окружности и отображаем количество минут через каждые 5 минутных меток. Текст размещается в невидимом прямоугольнике под минутной отметкой. В конце каждой итерации цикла мы поворачиваем рисовальщик по часовой стрелке на 7°, что соответствует одной минуте. При рисовании минутной отметки следующий раз она будет отображаться в другом месте окружности, хотя мы передаем одни и те же координаты функциям drawLine и drawText.

В этом программном коде в цикле for имеется незаметная погрешность, которая

быстро стала бы очевидной, если бы мы выполнили больше итераций. При каждом вызове rotate мы фактически умножаем текущую универсальную матрицу преобразования на матрицу поворота, получая новую универсальную матрицу преобразования. Ошибка округления чисел с плавающей точкой еще больше увеличивает неточность универсальной матрицы преобразования. Ниже показан один из возможных способов решения этой проблемы путем перезаписи программного кода с использованием save и restore для сохранения и восстановления первоначальной матрицы преобразования на каждом шаге итерации:

41 for (int i = 0; i <= MaxMinutes; ++i) {

42 painter->save;

43 painter->rotate(-i * DegreesPerMinute);

44 if (i % 5 == 0) {

45 painter->setPen(thickPen);

46 painter->drawLine(0, -41, 0, -44);

47 painter->drawText(-15, -41, 30, 25,

48 Qt::AlignHCenter | Qt::AlignTop,

49 QString::number(i));

50 } else {

51 painter->setPen(thinPen);

52 painter->drawLine(0, -42, 0, -44);

53 }

54 painter->restore;

55 }

При другом способе реализации таймера духовки нам нужно было бы самим рассчитывать координаты (x, y), используя функции sin и cos для определения их позиции на окружности. Но тогда нам все же пришлось бы выполнять перенос и поворот системы координат для отображения текста под некоторым углом.

Высококачественное воспроизведение изображения при помощи QImage

При рисовании мы можем столкнуться с необходимостью принятия компромиссных решений относительно скорости и точности. Например, в системах X11 и Mac OS X рисование по виджету QWidget или по пиксельной карте QPixmap основано на применении родного для платформы графического процессора (paint engine). В системе X11 это обеспечивает минимальную связь с Х—сервером; посылаются только команды рисования, а не данные реального изображения. Основным недостатком этого подхода является то, что возможности Qt ограничиваются родными для данной платформы средствами поддержки:

• в системе Х11 такие возможности, как сглаживание линий и поддержка дробных координат, доступны только в том случае, если Х—сервер использует расширение X Render;

• в системе Mac OS X родной графический процессор, обеспечивающий сглаживание линий, использует алгоритмы рисования многоугольников, которые отличаются от алгоритмов в X11 и Windows, что приводит к получению немного других результатов.

Когда точность важнее эффективности, мы можем рисовать по QImage и

копировать результат на экран. В этом случае Qt всегда использует собственный внутренний графический процессор и результат на всех платформах получается идентичным. Единственное ограничение заключается в том, что QImage, по которому мы рисуем, должен создаваться с аргументом QImage::Format_RGB32 или QImage::Format_ARGB32_Premultiplied.

Второй формат почти идентичен обычному формату ARGB32 (0xaarrggbb); отличие в том, что красный, зеленый и синий компоненты «предварительно умножаются» на альфа—компонент. Это значит, что значения RGB, которые обычно находятся в диапазоне от 0x00 до 0xFF, теперь принимают значения от 0x00 до значения альфа-компонента. Например, синий цвет с прозрачностью 50% представляется значением 0x7F0000FF в формате ARGB32, но он имеет значение 0x7F00007F в формате ARGB32 с предварительным умножением компонент, и, аналогично, темно-зеленый цвет с прозрачностью 75% имеет значение 0x3F008000 в формате ARGB32 и значение 0x3F002000 в фopмaтe ARGB32 с предварительным умножением компонент.

Предположим, что мы хотим использовать сглаживание линий при рисовании виджета и нам нужно получить хорошие результаты даже в системах X11, которые не используют расширение X Render. Обработчик событий paintEvent, предполагающий применение X Render для сглаживания линий, мог бы выглядеть следующим образом:

01 void MyWidget::paintEvent(QPaintEvent *event)

02 {

03 QPainter painter(this);

04 painter.setRenderHint(QPainter::Antialiasing, true);

05 draw(&painter);

06 }

Ниже показано, как можно переписать виджетную функцию paintEvent для применения независимого от платформы графического процессора Qt:

01 void MyWidget::paintEvent(QPaintEvent *event)

02 {

03 QImage image(size, QImage::Format_ARGB32_Premultiplied);

04 QPainter imagePainter(&image);

05 imagePainter.initFrom(this);

06 imagePainter.setRenderHint(QPainter::Antialiasing, true);

07 imagePainter.eraseRect(rect);

08 draw(&imagePainter);

09 imagePainter.end;

10 QPainter widgetPainter(this);

11 widgetPainter.drawImage(0,0, image);

12 }

Мы создаем объект QImage с тем же размером, который имеет виджет, в формате ARGB32 с умножением компонент, и объект QPainter для рисования по изображению. Вызов initFrom инициализирует в рисовальщике перо, фон и шрифт значениями, используемыми виджетом. Мы рисуем, используя QPainter как обычно, а в конце еще раз используем объект QPainter для копирования изображения на виджет.

Поделиться:
Популярные книги

Жена со скидкой, или Случайный брак

Ардова Алиса
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Жена со скидкой, или Случайный брак

Осколки маски

Метельский Николай Александрович
7. Унесенный ветром
Фантастика:
боевая фантастика
альтернативная история
6.71
рейтинг книги
Осколки маски

Мастер 4

Чащин Валерий
4. Мастер
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Мастер 4

Горизонт Вечности

Вайс Александр
11. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Горизонт Вечности

Потомок бога 3

Решетов Евгений Валерьевич
3. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Потомок бога 3

Запечатанный во тьме. Том 1. Тысячи лет кача

NikL
1. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 1. Тысячи лет кача

Путь

Yagger Егор
Фантастика:
космическая фантастика
4.25
рейтинг книги
Путь

Ученик. Книга третья

Первухин Андрей Евгеньевич
3. Ученик
Фантастика:
фэнтези
7.64
рейтинг книги
Ученик. Книга третья

Хозяин Теней 5

Петров Максим Николаевич
5. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 5

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Сильнейший Столп Империи. Книга 5

Ермоленков Алексей
5. Сильнейший Столп Империи
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 5

Кодекс Охотника. Книга XXII

Винокуров Юрий
22. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXII

Чевенгур

Платонов Андрей Платонович
Проза:
советская классическая проза
6.75
рейтинг книги
Чевенгур

Новые горизонты

Лисина Александра
5. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Новые горизонты