Библиотека сайта rus-linux.net
Программирование с использованием gtkmm 3. Виджет области рисования (DrawingArea)
Оригинал: Programming with gtkmm 3Авторы: Murray Cumming, Bernhard Rieder, Jonathon Jongsma, Ole Laursen, Marko Anastasov, Daniel Elstner, Chris Vine, David King, Pedro Ferreira, Kjell Ahlstedt
Перевод: А.Панин
17.5. Вывод текста
17.5.1. Вывод текста с помощью библиотеки Pango
Вывод текста осуществляется с помощью областей вывода текста Pango (Pango Layouts). Простейшим способом создания экземпляра класса области вывода текста Pango Pango::Layout
является вызов функции Gtk::Widget::create_pango_layout()
. После создания область вывода текста Pango может использоваться для различных манипуляций с текстом, включая изменение текста, шрифта, и.т.д. Наконец, область вывода текста Pango может быть размещена в области рисования с помощью метода Pango::Layout::show_in_cairo_context()
.
17.5.2. Пример
Ниже приведен пример программы, которая с помощью области рисования выводит текст, часть которого является перевернутой. Глава "Печать" содержит другой пример вывода текста.
Рисунок 17-6: Область рисования - Текст
Файл: myarea.h
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: mayarea.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: main.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
17.6. Вывод существующих изображений
Существует метод для вывода объекта буфера пикселей на основе класса Gdk::Pixbuf
с помощью контекста Cairo на основе класса Cairo::Context
. Класс буфера пикселей Gdk::Pixbuf
является удобной оберткой над набором пикселей, который может формироваться на основе прочитанных из файлов изображений данных и подвергаться различным модификациям впоследствии.
Самым часто используемым способом создания объектов на основе класса Gdk::Pixbuf
, скорее всего, является вызов метода Gdk::Pixbuf::create_from_file()
, который позволяет прочитать данные из файла изображения, такого, как файл формата PNG, в готовый для вывода буфер пикселей.
Данные буфера пикселей на основе класса Gdk::Pixbuf
могут быть выведены с помощью контекста Cairo после объявления этого буфера источником данных шаблона изображения контекста Cairo путем вызова метода Gdk::Cairo::set_source_pixbuf()
. После этого изображение может прорисовываться либо путем вызова метода Cairo::Context::paint()
(для прорисовки всего изображения), либо путем вызова методов Cairo::Context::rectangle()
и Cairo::Context:fill()
(для прорисовки изображения в заданной прямоугольной области). Функция set_source_pixbuf()
не является методом класса Cairo::Context
. Она принимает экземпляр класса Cairo::Context
в качестве первого параметра.
bool MyArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr) { Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_file("myimage.png"); // Прорисовка изображения в точке с координатами 110, 90 за исключением 10 пикселей на внешних границах. Gdk::Cairo::set_source_pixbuf(cr, image, 100, 80); cr->rectangle(110, 90, image->get_width()-20, image->get_height()-20); cr->fill(); return true; }
17.6.1. Пример
Ниже приведен пример простой программы, предназначенной для вывода изображения в области рисования.
Рисунок 17-7: Область рисования - Изображение
Файл: myarea.h
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: myarea.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: main.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
17.7. Пример приложения: часы на основе Cairo
После того, как мы рассмотрели основные методы рисования с помощью библиотеки Cairo, давайте попытаемся обобщить полученную информацию и создать простое приложение, которое выполняет полезную функцию. В примере библиотека Cairo используется для создания специального виджета часов. Часы имеют секундную, минутную и часовую стрелки и обновляют их положение каждую секунду.
Рисунок 17-8: Область рисования - Часы
Файл: clock.h
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: clock.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Файл: main.cc
(Для использования совместно с gtkmm 3, а не с gtkmm 2)
Как и раньше, в данном случае практически все интересные вещи реализованы в рамках обработчика сигналов on_draw()
. Перед тем, как мы будем исследовать обработчик сигналов перерисовки, следует обратить внимание на то, что конструктор класса виджета Clock
устанавливает функцию обработчика on_timeout()
для таймера с временем срабатывания в 1000 миллисекунд (или 1 секунду). Это означает, что функция on_timeout()
будет вызываться один раз в секунду. Единственной задачей этой функции является установка флага устаревания изображения окна для того, чтобы принудить gtkmm перерисовать его.
Теперь давайте рассмотрим код, в рамках которого выполняются сами операции рисования. Первая часть функции on_draw()
на данный момент должна быть достаточно знакомой. В данном примере снова производится масштабирование координатной системы до единичного квадрата с целью упрощения рисования часов с использованием процентного соотношения размеров окна, поэтому изображение будет автоматически масштабироваться при изменении размеров окна. Более того, впоследствии производится еще одно масштабирование координатной системы таким образом, что точка с координатами (0,0) находится в самом центре окна.
Функция Cairo::Context::paint()
в данном случае используется для установки цвета фона окна. Эта функция не принимает аргументов и заполняет текущую поверхность (или ограниченную часть поверхности) активным на данный момент цветом. Выполнив установку цвета фона окна, мы рисуем внешнюю окружность циферблата часов и закрашиваем ее белым цветом с последующей обводкой этой окружности черным цветом. Обратите внимание на то, что при выполнении всех описанных действий используются варианты функций с суффиксами _preserve
для сохранения текущего контура, причем впоследствии этот же контур используется для выравнивания будущих линий с гарантией того, что ни одна из этих линий не пересечет внешнюю окружность циферблата часов.
После изображения внешней окружности часов мы обходим циферблат и рисуем деления для каждого часа, причем деления для 12, 3, 6 и 9 часов имеют больший размер. Теперь мы наконец готовы к реализации функции отображения текущего времени наших часов, которая заключается в простом получении текущих значений часов, минут и секунд и рисовании стрелок под корректными углами.
Следующий раздел : Механизм захвата и перемещения данных (Drag and Drop).