× К оглавлению На главную Об авторе

Дата и время публикации   :

Назначение и использование


1. Назначение

1.1 GObject интроспекция

Для упрощения создания, развертывания и выполнения прикладных приложений в графическом окружении рабочего стола Gnome существует возможность написания скриптов на языке программирования Python с использованием языковых привязок, реализуемых с помощью интроспекции GObject

В свою очередь, интроспекцией GObject (GObject introspection, GI) является программная прослойка для связки языков более высокого уровня программирования с библиотеками GObject, написанными на языке программирования С и сканируемых во время компиляции, генерации файлов с метаданными в дополнении к фактически существующей библиотеки на С

Как показано на рисунке 1.1 привязывание языка высокого уровня производится автоматически обеспечивая вызов внутри библиотеки С

Рисунок 1.1

Таким образом, как следует из рисунка 1.1, проект GI состоит из :

1.2 Языковая связка PyGObject

Для реализации языка программирования Python используется пакет PyGObject, который обеспечивает связывание базовых библиотек GObject, таких как Gtk, Gstreamer, WebKitGTK, Glib, GIO и многих других.

Несомненно, пакет PyGObject является наиболее предпочтительным для разработки приложений на Python и реализует доступ к основной базовой функциональности графического окружения Gnome, как показано на рисунке 1.2

Рисунок 1.1

Из которого следует, что PyGObject использует библиотеки glib, gobject и уже ранее упоминавшиеся бибилиотеки girepository и libffi для обеспечения доступа к написанной на C библиотеки libgtk-x.x.so в комбинации с дополнительными метаданными из сопровождающего файла динамической типизации Gtk-x.x.typelib и предоставляющей её интерфейсам Python

Кроме того, PyGObject прекрасно взаимодействует со следующими программными компонентами Gnome :

Ниже перечисленные библиотек используют PyGObject для расширения функциональности в виде отдельных подключаемых плагинов или дополнительных бакендов:

2. Использование PyGObject

2.1 Установка программного обеспечения

В операционной системе Debian OC GNU/Linux необходимо установить базовые пакеты реализующие поддержку интроспекции GObgect, таких как python3-gi-cairo, python3-gi и python-gi-dev, предоставляемые пакетом исходного кода pygobject , как показано в дампе 2.1.1

Дамп 2.1.1

$ sudo apt install  python3-gi-cairo python3-gi python-gi-dev

При этом, скорее всего у Вас уже установлены первые два пакета, поэтому python-gi-dev рекомендую устанавливать по желанию.

2.2 Создание скелета программы

В листинге 2.2.1 приведен скелет программы gsshmgmt, которая выводит окно с названием "SSH Managment"

Листинг 2.2.1

  1 from gi.repository import Gtk
  2 import sys
...
 25 class TopLevelWindow(Gtk.ApplicationWindow):
 26
 27      # constructor for a Gtk.ApplicationWindow
 28      def __init__(self, app):
 29          Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL, modal=True, title="The title of my program", application=app)
...
 42
 43 class MyApplication(Gtk.Application):
 44
 45    def __init__(self):
 46        Gtk.Application.__init__(self)
 47
 48    def do_activate(self):
 49        top = TopLevelWindow(self)
 50        top.show_all()
 51
 52    def do_startup(self):
 53        Gtk.Application.do_startup(self)
 54
 55 app = MyApplication()
 56 exit_status = app.run(sys.argv)
 57 sys.exit(exit_status)
 58
...

В строке 1-2 листинга 2.2.1 производится установка импорта библиотек GNOME через интроспекцию GObject. В этих двух строках мы производим импорт языковых привязок и библиотеки Gtk, которая содержит графические виджеты, используемые для создания приложений GNOME . При этом, как показано в строке 1, 2 и 4 листинга 2.2.2, необходимо указать какая именно совместимая версия библиотеки Gtk для нашего приложения будет подключаться модулем gi, реализующий языковое связывание интроспекции gobgect и написанной на языке программирования С библиотеки Gtk

Листинг 2.2.1

  1 import gi
  2 gi.require_version("Gtk", "3.0")
  3
  4 from gi.repository import Gtk
...  
Примечание. В случае, если написанная программка на Python не запускается, а вместо нее на консоли выводится "import: command not found", одной из причиной может служить различие в кодировками – между той что ждет интерпретатор и той что есть на самом деле. Поэтому следует использовать шебанг, как показано ниже.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
...

Но, мало определить явно версию Gtk, в случае обращение к примитивам Gdk, ей нужно тоже определить требуему версию. Поэтому заголовок программы на Python будет иметь вид, как показано в дампе 2.2.3

Листинг 2.2.3

  1 #!/usr/bin/env python3
  2 # -*- coding: utf-8 -*-
  3 import os
  4 import gi
  5 gi.require_version("Gtk", "3.0")
  6 gi.require_version("Gdk", "3.0")
  7
  8 from gi.repository import Gtk,Gdk
...  

Как показано в строках 5 и 6 листинга 2.2.3, в первых строках кода необходимо указывать требуемые версии подключаемых библотек, которые будет использовать наша программа на Python, чтобы исключить неоднозначных ситуаций, наподобие той, что может сопровождаться диагностическими сообщениями, такими как "PyGIWarning: Gtk was imported without specifying a version first..." или "PyGIWarning: Gdk was imported without specifying a version first...".

В строках 25-41 листинга 2.2.1 декларируем класс TopLevelWindow, которое содержит основные элементы управления окна верхнего уровня на базе Gtk.ApplicationWindow, которое будет отображено и реализовать интерфейс пользователя в виде визуальных элеменов и форм управления.

В строках 43-53 листинга 2.2.1 декларируем класс MyApplication, который инициализирует и отображает окно верхнего уровня путем вызова метода:

Кроме того, могут быть дополниетльно определены следующие методы:

Порядок обращения к выше перечисленным методам будет следующим:

При этом, нужно учитывать, что приложение Gnome запускается в качестве первичного (single-instance) или вторичного экземпляра (second-instance). При этом по умолчанию, запущенный экземпляр приложения в Gnome будет первичным по умолчанию. Если пользователь попытается запустить второй экземпляр приложения Gnome, для первого экземпляра будут выполнены методы do_activate() и do_open()

Также, чтобы приложение не зависало на методе do_shutdown() следует использовать quit() после Gtk.Application.do_shutdown() , как показано в листинге 2.2.4

Листинг 2.2.4

...
 78 class MyApplication(Gtk.Application):
 79
 80 stage = 0
 81
 82 def __init__(self):
 83     self.stage += 1
 84     print("%2d. Gtk.Application __init__ !!!" % self.stage )
 85     Gtk.Application.__init__(self)
 86
 87 def do_activate(self):
 88     self.stage += 1
 89     print("%2d. MyApplication :: do_activate !!!" % self.stage )
 90     top = TopLevelWindow(self)
 91     top.show_all()
 92
 93 def do_open(self):
 94     self.stage += 1
 95     print("%2d. MyApplication :: do_open !!!" % self.stage )
 96
 97 def do_startup(self):
 98     self.stage += 1
 99     print("%2d. MyApplication :: do_startup !!!" % self.stage )
100     Gtk.Application.do_startup(self)
101
102 def do_shutdown(self):
103     self.stage += 1
104     print("%2d. MyApplication :: do_shutdown !!!" % self.stage )
105     Gtk.Application.do_shutdown(self)
106    self.quit()
...

Реальный порядок запуска методов, определенных в строках 78-106 листинга 2.2.4, показан в дампе 2.2.5

Дамп 2.2.5

$ ./gsshmgmt.py
 1. Gtk.Application __init__ !!!
 2. TopLevelWindow :: do_startup !!!
 3. TopLevelWindow :: do_activate !!!
 4. TopLevelWindow :: do_shutdown !!!

В котором показан, вышеописанный порядок запуска конструктора __init__ методов TopLevelWindow :: do_startup(), TopLevelWindow :: do_activate() и TopLevelWindow :: do_shutdown(). При этом, чтобы избежать зависание на последнем в строку 84 листинга 2.2.6 добавлен self.quit()

2.3 Создание главного окна

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

Листинг 2.3.1

...
.53 class TopLevelWindow(Gtk.ApplicationWindow):
.54
 55      # constructor for a Gtk.ApplicationWindow
.56      def __init__(self, app):
.57          Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL, modal=True, title="The title of my program", application=app)
...

Создание главного (type=Gtk.WindowType.TOPLEVEL) и модального (modal=True) окна верхнего уровня создоваемого приложения (application=app) производится с помощью конструктора __init__ базового класса Gtk.Window для класса Gtk.ApplicationWindow, как показано в строке 29 листинга 2.3.1

При этом, разработчику нужно учитывать, что Gtk.Window в GTK3 может иметь только один дочерний виджет. Поэтому самым простым решением было бы использовать ящик вертикального размещения виджетов на базе Gtk.Container

Но, так так как, на выданье версия Gtk4, определяем класс-обертку, чтобы абстрагировать TopLevelWindow от грядущих изменений при переходе с GTK3, как показано в листинге 2.3.2

Листинг 2.3.2

...
.25 #BoxWrapper()
.26 #
.27 # will pack a child widget into the window as it can have one child only.   
.28 #
.29 class BoxWrapper(Gtk.VBox):
.30
.31      # method assigns a parent window to the widget by default.
.32      def __init__(self, top):
.33          Gtk.VBox.__init__(self,homogeneous=False,spacing=0)   
.34
.35      # metod adds a child to end of the box       
.36      def add(self,child):
.37          self.pack_start(child,False, False, 0)    4
...
.53 class TopLevelWindow(Gtk.ApplicationWindow):
.54
.55      # constructor for a Gtk.ApplicationWindow
.56      def __init__(self, app):
.57
...
.58          box = BoxWrapper(self)
.59          self.add(box)
.60                    
.61          # create a label
.62          label = Gtk.Label()
.63          # set the text of the label
.64          label.set_text("Child widgets of the Vbox container")
.65          # add the label to the window
.67          box.add(label)
...

В результате выше описанных действий по реализации главного окна, на выходе должна получится картинка, как показано на рисунке 2.3.3

Рисунок 2.3.3

3. Библиография

3.1 Gnome Develeper.How to build, install and create a tar.xz of a Hello World program

3.2 GObject Introspection

3.3 Debian.org: Пакет исходного кода: pygobject

3.4 AskUbuntu. How to detect a computers physical screen size in gtk

3.5 StackOverflow.Com. Select certain monitor for going fullscreen with gtk

3.6 StackOverflow.Com. Show terminal output in a gui window using python gtk

3.7 StackOverflow.Com. How to make buttons different colours in python gtk3 using gi

3.8 Program Talk. gi.repository.Gtk.WindowType.TOPLEVEL

3.9 Python Code Examples for do startup

3.10 WiKi.Gnome. Using GtkApplication

3.11 Gnome Develeper. Class GtkApplication

3.12 StackOverflow.Com. Behaviour of increment and decrement operators in python