В этом разделе учебного материала мы будем работать с корневым окном. Корневое окно это окно рабочего стола, на котором обычно располагаются значки ярлыков.
Над корневым окном можно выполнять различные манипуляции. С точки зрения программиста, это просто особый тип окна.
Прозрачное окно
В нашем первом примере мы создадим прозрачное окно. Мы увидим, что находится под объектом окна.
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 |
#!/usr/bin/python from gi.repository import Gtk import cairo class Example(Gtk.Window): def __init__(self): super(Example, self).__init__() self.tran_setup() self.init_ui() def init_ui(self): self.connect("draw", self.on_draw) self.set_title("Transparent window") self.resize(300, 250) self.set_position(Gtk.WindowPosition.CENTER) self.connect("delete-event", Gtk.main_quit) self.show_all() def tran_setup(self): self.set_app_paintable(True) screen = self.get_screen() visual = screen.get_rgba_visual() if visual != None and screen.is_composited(): self.set_visual(visual) def on_draw(self, wid, cr): cr.set_source_rgba(0.2, 0.2, 0.2, 0.4) cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() def main(): app = Example() Gtk.main() if __name__ == "__main__": main() |
Для создания прозрачного окна, мы получили изображения окна объекта и применяем его в нашем окне. В методе on_draw() мы рисуем поверх визуального объекта окна. Это создаст видимость частичной прозрачности.
1 |
self.set_app_paintable(True) |
Нам нужно задать приложение для рисования.
1 |
screen = self.get_screen() |
Метод get_screen() возвращает объект экрана.
1 |
visual = screen.get_rgba_visual() |
Мы получаем изображение из экрана окна. Визуал содержит в себе информацию о низкоуровневом дисплее.
1 2 |
if visual != None and screen.is_composited(): self.set_visual(visual) |
Не все дисплеи поддерживают эту операцию. Таким образом, мы проверяем, поддерживает ли наш экран композицию и возвращенный визуал. Мы указываем визуал экрана в качестве визуала для нашего окна.
1 2 3 4 5 |
def on_draw(self, wid, cr): cr.set_source_rgba(0.2, 0.2, 0.2, 0.4) cr.set_operator(cairo.OPERATOR_SOURCE) cr.paint() |
Мы используем исходник частичной прозрачности для рисования поверх окна экрана. Применив cairo.OPERATOR_SOURCE мы создаем операцию композиции, в которой мы можем рисовать поверх исходника, находящегося в окне экрана. Для получения полной прозрачности, мы указываема альфа-значение как 0, или используем операцию cairo.OPERATOR_CLEAR .
Делаем скриншот
Корневое окно имеет первостепенное значение при создании скриншота.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#!/usr/bin/python from gi.repository import Gdk import cairo def main(): root_win = Gdk.get_default_root_window() width = root_win.get_width() height = root_win.get_height() ims = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) pb = Gdk.pixbuf_get_from_window(root_win, 0, 0, width, height) cr = cairo.Context(ims) Gdk.cairo_set_source_pixbuf(cr, pb, 0, 0) cr.paint() ims.write_to_png("screenshot.png") if __name__ == "__main__": main() |
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
В данном примере мы делаем снимок всего экрана.
1 |
root_win = Gdk.get_default_root_window() |
Мы открываем корневое окно при помощи вызова метода Gdk.get_default_root_window() .
1 2 |
width = root_win.get_width() height = root_win.get_height() |
Определяем высоту и ширину корневого окна.
1 |
ims = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) |
Создаем пустую поверхность изображения, такого же размера, как и корневое окно.
1 |
pb = Gdk.pixbuf_get_from_window(root_win, 0, 0, width, height) |
Получаем pixbuf из корневого окна, вызвав метод Gdk.pixbuf_get_from_window(). Pixbuf – это используемый библиотекой GTK объект, описывающий изображение в памяти.
1 2 3 |
cr = cairo.Context(ims) Gdk.cairo_set_source_pixbuf(cr, pb, 0, 0) cr.paint() |
В вышеуказанном коде, мы создаем контекст рисования Cairo на поверхности изображения, которую мы создали ранее.
1 |
ims.write_to_png("screenshot.png") |
Поверхность изображения записана в изображении PNG при помощи метода write_to_png().
Демонстрация сообщений
В третьем примере мы покажем сообщение на рабочем столе.
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 |
#!/usr/bin/python from gi.repository import Gtk, Gdk, Pango import cairo class Example(Gtk.Window): def __init__(self): super(Example, self).__init__() self.setup() self.init_ui() def setup(self): self.set_app_paintable(True) self.set_type_hint(Gdk.WindowTypeHint.DOCK) self.set_keep_below(True) screen = self.get_screen() visual = screen.get_rgba_visual() if visual != None and screen.is_composited(): self.set_visual(visual) def init_ui(self): self.connect("draw", self.on_draw) lbl = Gtk.Label() text = "ZetCode, tutorials for programmers." lbl.set_text(text) fd = Pango.FontDescription("Serif 20") lbl.modify_font(fd) lbl.modify_fg(Gtk.StateFlags.NORMAL,Gdk.color_parse("white")) self.add(lbl) self.resize(300, 250) self.set_position(Gtk.WindowPosition.CENTER) self.connect("delete-event", Gtk.main_quit) self.show_all() def on_draw(self, wid, cr): cr.set_operator(cairo.OPERATOR_CLEAR) cr.paint() cr.set_operator(cairo.OPERATOR_OVER) def main(): app = Example() Gtk.main() if __name__ == "__main__": import signal signal.signal(signal.SIGINT, signal.SIG_DFL) main() |
Код показывает метку сообщения в корневом окне.
1 |
self.set_app_paintable(True) |
Мы будем работать с окном приложения, для этого нам нужно будет сделать так, чтобы в нем можно было рисовать.
1 |
self.set_type_hint(Gdk.WindowTypeHint.DOCK) |
Применив этот прием, мы убираем границы и оформление окна.
1 |
self.set_keep_below(True) |
Приложение должно находиться внизу, как раз над корневым окном.
1 2 3 4 |
screen = self.get_screen() visual = screen.get_rgba_visual() if visual != None and screen.is_composited(): self.set_visual(visual) |
Настраиваем визуал экрана таким образом, чтобы он стал визуалом нашего приложения.
1 2 3 |
lbl = Gtk.Label() text = "ZetCode, tutorials for programmers." lbl.set_text(text) |
Размещаем метку изображения в окне приложения.
1 2 3 |
fd = Pango.FontDescription("Serif 20") lbl.modify_font(fd) lbl.modify_fg(Gtk.StateFlags.NORMAL,Gdk.color_parse("white")) |
При помощи модуля Pango, мы меняем внешний вид нашего текста.
1 2 3 4 5 |
def on_draw(self, wid, cr): cr.set_operator(cairo.OPERATOR_CLEAR) cr.paint() cr.set_operator(cairo.OPERATOR_OVER) |
Используем оператор cairo.OPERATOR_CLEAR для очистки заднего фона окна. После этого мы используем оператор cairo.OPERATOR_CLEAR, чтобы нарисовать виджет метки.
1 2 3 4 |
if __name__ == "__main__": import signal signal.signal(signal.SIGINT, signal.SIG_DFL) main() |
Существует старый баг, который не позволяет нам завершить загрузку приложения из терминала при помощи команды Ctrl+C . Следует добавить две линии для того чтобы обойти эту ошибку.
Вот такая надпись на рабочем столе!
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»