В данной части материала мы будем работать с текстом. В первом примере мы покажем текст одной песни.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def on_draw(self, wid, cr): cr.set_source_rgb(0.1, 0.1, 0.1) cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) cr.set_font_size(13) cr.move_to(20, 30) cr.show_text("Most relationships seem so transitory") cr.move_to(20, 60) cr.show_text("They're all good but not the permanent one") cr.move_to(20, 120) cr.show_text("Who doesn't long for someone to hold") cr.move_to(20, 150) cr.show_text("Who knows how to love without being told") cr.move_to(20, 180) cr.show_text("Somebody tell me why I'm on my own") cr.move_to(20, 210) cr.show_text("If there's a soulmate for everyone") |
В данном коде мы показали часть текста песни Наташи Бедингфилдс – Soulmate.
1 2 |
cr.select_font_face("Purisa", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) |
Здесь мы выбрали шрифт. Метод принимает три параметра: семейство шрифта, его наклон и вес.
1 |
cr.set_font_size(13) |
Здесь мы определяем размер шрифта.
1 2 |
cr.move_to(20, 30) cr.show_text("Most relationships seem so transitory") |
Текст в окне отображен путем выбора позиции текста и вызова метода show_text().
Центрирование текста
Далее мы покажем, как центрировать текст в окне.
1 2 3 4 5 6 7 8 9 10 11 12 |
def on_draw(self, wid, cr): w, h = self.get_size() cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(60) (x, y, width, height, dx, dy) = cr.text_extents("ZetCode") cr.move_to(w/2 - width/2, h/2) cr.show_text("ZetCode") |
Данный код центрирует текст в окне. Текст остается в центре, даже если размер окна меняется.
1 |
w, h = self.get_size() |
Для того чтобы центрировать текст в окне, нужно получить размер клиентской области окна.
1 2 3 |
cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(60) |
Мы выбираем шрифт и его размер для отображения.
1 |
(x, y, width, height, dx, dy) = cr.text_extents("ZetCode") |
Мы получили экстенты текста. Здесь приведены числа, описывающие текст. Нам нужна ширина текста для нашего примера.
1 2 |
cr.move_to(w/2 - width/2, h/2) cr.show_text("ZetCode") |
Мы позиционируем текста в центре окна и отображаем его при помощи метода show_text() .
Текст с тенью
В данном примере мы создадим текст с тенью в нашем окне.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def on_draw(self, wid, cr): cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(50) cr.set_source_rgb(0, 0, 0) cr.move_to(40, 60) cr.show_text("ZetCode") cr.set_source_rgb(0.5, 0.5, 0.5) cr.move_to(43, 63) cr.show_text("ZetCode") |
Для того, чтобы создать тень, нам нужно написать текст дважды, разными цветами. Второй текст будет смещен чуть правее и ниже.
1 2 3 |
cr.set_source_rgb(0, 0, 0) cr.move_to(40, 60) cr.show_text("ZetCode") |
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Первый текст написан черным цветом и будет служить в качестве тени.
1 2 3 |
cr.set_source_rgb(0.5, 0.5, 0.5) cr.move_to(43, 63) cr.show_text("ZetCode") |
Для второго текста мы выбираем серый цвет. Он смещён на 3 пикселя вправо и вниз.
Градиентный текст
В следующем примере мы интересный эффект. Мы заполним текст линейным градиентом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
def on_draw(self, wid, cr): cr.set_source_rgb(0.2, 0.2, 0.2) cr.paint() h = 90 cr.select_font_face("Serif", cairo.FONT_SLANT_ITALIC, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(h) lg = cairo.LinearGradient(0, 15, 0, h*0.8) lg.set_extend(cairo.EXTEND_REPEAT) lg.add_color_stop_rgb(0.0, 1, 0.6, 0) lg.add_color_stop_rgb(0.5, 1, 0.3, 0) cr.move_to(15, 80) cr.text_path("ZetCode") cr.set_source(lg) cr.fill() |
Мы написали текст в окне и залили его линейным градиентом. В качестве цвета были выбраны оттенки оранжевого.
1 2 |
cr.set_source_rgb(0.2, 0.2, 0.2) cr.paint() |
Чтобы сделать его визуально более привлекательным, мы закрасим задний фон темно-серым цветом.
1 2 3 4 |
lg = cairo.LinearGradient(0, 15, 0, h*0.8) lg.set_extend(cairo.EXTEND_REPEAT) lg.add_color_stop_rgb(0.0, 1, 0.6, 0) lg.add_color_stop_rgb(0.5, 1, 0.3, 0) |
Линейный градиент создан.
1 2 3 4 |
lg = cairo.LinearGradient(0, 15, 0, h*0.8) lg.set_extend(cairo.EXTEND_REPEAT) lg.add_color_stop_rgb(0.0, 1, 0.6, 0) lg.add_color_stop_rgb(0.5, 1, 0.3, 0) |
Текст отображается в окне, мы выбрали градиент в качестве исходника для рисования.
Пропись по буквам
В данном эффекте текст будет прописан побуквенно. Буквы будут прописаны с небольшой задержкой.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
#!/usr/bin/python from gi.repository import Gtk, GLib import cairo class cv(object): SPEED = 800 TEXT_SIZE = 35 COUNT_MAX = 8 class Example(Gtk.Window): def __init__(self): super(Example, self).__init__() self.init_ui() self.init_vars() def init_ui(self): self.darea = Gtk.DrawingArea() self.darea.connect("draw", self.on_draw) self.add(self.darea) GLib.timeout_add(cv.SPEED, self.on_timer) self.set_title("Letter by letter") self.resize(350, 200) self.set_position(Gtk.WindowPosition.CENTER) self.connect("delete-event", Gtk.main_quit) self.show_all() def init_vars(self): self.timer = True self.count = 0 self.text = [ "Z", "e", "t", "C", "o", "d", "e" ] def on_timer(self): if not self.timer: return False self.darea.queue_draw() return True def on_draw(self, wid, cr): cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) cr.set_font_size(cv.TEXT_SIZE) dis = 0 for i in range(self.count): (x, y, width, height, dx, dy) = cr.text_extents(self.text[i]) dis += width + 2 cr.move_to(dis + 30, 50) cr.show_text(self.text[i]) self.count += 1 if self.count == cv.COUNT_MAX: self.timer = False self.count = 0 def main(): app = Example() Gtk.main() if __name__ == "__main__": main() |
В нашем примере мы напишем строку «ZetCode» в окне GTK по буквам с небольшой задержкой.
1 |
self.text = [ "Z", "e", "t", "C", "o", "d", "e" ] |
Вот список букв, которые будут отображаться в окне.
1 2 |
cr.select_font_face("Courier", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD) |
Мы выбираем шрифт Courier и выделяем его жирным.
1 2 3 4 5 6 7 |
for i in range(self.count): (x, y, width, height, dx, dy) = cr.text_extents(self.text[i]) dis += width + 2 cr.move_to(dis + 30, 50) cr.show_text(self.text[i]) |
Здесь мы прописали текст по буквам. Мы получили ширину каждой буквы и вычисляем расстояния на оси Х.
Глиф
Метод show_text() подходит только для простого рендеринга текста. Разработчики Cairo называют его игрушечным. Рендеринг на более профессиональном уровне выполняется с применением глифа. Глиф – это графический символ, определяющий форму символа. Символ, в свою очередь, определяет значение и может сочетать в себе несколько глифов. Сам по себе символ не имеет вида, также как и глиф, сам по себе, не имеет значения.
Обратите внимание на то, что множество базовых программных требований, обращенных к тексту, рассматриваются библиотекой Pango.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def on_draw(self, wid, cr): cr.select_font_face("Serif", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) cr.set_font_size(13) glyphs = [] index = 0 for y in range(20): for x in range(35): glyphs.append((index, x*15 + 20, y*18 + 20)) index += 1 cr.show_glyphs(glyphs) |
Данный код демонстрирует 700 глифов выбранного шрифта.
1 |
glyphs = [] |
Список глифов хранится в качестве трех целых чисел. Первое число является индексом глифа выбранного типа шрифта. Второе и третье число являются позициями осей глифа Х и Y.
1 |
cr.show_glyphs(glyphs) |
Метод show_glyphs() отображает глифы в окне.
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»