10.13. Виджеты Plug и Socket

Виджеты Plug и Socket используются для встраивания пользовательского интерфейса одного процесса в другой процесс. Также это может быть выполнено с помощью Bonobo.

10.13.1. Plug

Plug инкапсулирует пользовательский интерфейс, предоставляемый приложением так, что он может быть встроен в GUI другого приложения. Сигнал"embedded" предупреждает приложение использующее Plug, что Plug был встроен в пользовательский интерфейс другого приложения.

Plug создаётся с помощью функции:

  plug = gtk.Plug(socket_id)

которая создаёт новый Plug, и встраивает его в Socket, определяемый socket_id. Если socket_id равен 0L, то Plug остаётся "неподключенным", и позже его можно будет подключить к Socket'у используя метод Socket'а add_id().

Метод виджета Plug:

  id = plug.get_id()

возвращает ID окна с Plug, который может быть использован для встраивания в Socket методом add_id().

Пример plug.py показывает использование Plug:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import pygtk
  5. pygtk.require('2.0')
  6. import gtk,sys
  7.  
  8. Wid = 0L
  9. if len(sys.argv) == 2:
  10. Wid = long(sys.argv[1])
  11.  
  12. plug = gtk.Plug(Wid)
  13. print "Plug ID=", plug.get_id()
  14.  
  15. def embed_event(widget):
  16. print "Я (", widget, ") только что был встроен!"
  17.  
  18. plug.connect("embedded", embed_event)
  19.  
  20. entry = gtk.Entry()
  21. entry.set_text("привет")
  22. def entry_point(widget):
  23. print "Вы изменили мой текст на '%s'" % widget.get_text()
  24.  
  25. entry.connect("changed", entry_point)
  26. plug.connect("destroy", lambda w: gtk.main_quit())
  27.  
  28. plug.add(entry)
  29. plug.show_all()
  30.  
  31.  
  32. gtk.main()
  33.  

Программа запускается так:

  plug.py [windowID]

где windowID это ID виджета Socket для подключения Plug.

10.13.2. Socket

Socket предоставляет виджет для встраивания виджета Plug из другого приложения в ваш GUI. Приложение создаёт виджет Socket и передаёт ID другому приложению, которое создаёт Plug используя переданный ID как параметр. Любой виджет содержащийся в Plug появится внутри окна первого приложения.

Socket ID получают использованием метода get_id(). До использования этого метода Socket должен быть реализован и прикреплён к родителю.

Примечание

Если вы передаёте ID другому процессу который создаст Plug, вам нужно удостовериться что виджет Socket не будет уничтожен до создания Plug.

Когда GTK+ получает уведомление о том, что встроенное окно было закрыто, он также удаляет и Socket. По этой причине вы должны всегда быть готовы к тому, что ваши Socket могут быть уничтожены в любое время основного цикла. Уничтожение Socket также уничтожит и Plug.

Соединение между Socket и Plug происходит по протоколу XEmbed. Этот протокол также включен в другие тулкиты, например Qt, позволяя некоторый уровень интеграции виджета Qt в GTK или наоборот.

Создаём новый пустой Socket:

  socket = gtk.Socket()

Socket должен находиться в  окне до того, как вы  вызовете метод add_id():

  socket.add_id(window_id)

который подключает XEmbed-клиент, например Plug, к Socket. Клиент может быть из этого-же процесса, или из другого.

Для встраивания Plug в Socket, вы можете создать Plug с:

  plug = gtk.Plug(0L)

и передать номер возвращаемый методом get_id() в метод Socket'a add_id():

  socket.add_id(plug)

Или вы можете вызвать метод get_id() виджета Socket:

    window_id = socket.get_id()

чтобы получить ID для Socket'a, и затем подключить Plug с:

  plug = gtk.Plug(window_id)

Socket уже должен быть добавлен на окно до этого вызова.

Пример socket.py показывает использование Socket:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import string
  5.  
  6. import pygtk
  7. pygtk.require('2.0')
  8. import gtk,sys
  9.  
  10. window = gtk.Window()
  11. window.show()
  12.  
  13. socket = gtk.Socket()
  14. socket.show()
  15. window.add(socket)
  16.  
  17. print "Socket ID=", socket.get_id()
  18. window.connect("destroy", lambda w: gtk.main_quit())
  19.  
  20. def plugged_event(widget):
  21. print "Я (", widget, ") только что подключил штепсель!"
  22.  
  23. socket.connect("plug-added", plugged_event)
  24.  
  25. if len(sys.argv) == 2:
  26. socket.add_id(long(sys.argv[1]))
  27.  
  28. gtk.main()
  29.  

Для запуска примера вы можете сначала запустить plug.py в одном терминале:

  djbaldey@rosix examples $ python plug.py 
Plug ID= 88080387

и использовать полученный ID как первый аргумент для socket.py в другом терминале:

  djbaldey@rosix examples $ python socket.py 88080387
Socket ID= 90177583

Вывод Терминала1:
Я ( <gtk.Plug object at 0x901d414 (GtkPlug at 0x90f9018)> ) только что был встроен!

Вывод Терминала2:
Я ( <gtk.Socket object at 0x86bd4dc (GtkSocket at 0x879a670)> ) только что подключил штепсель!

Или вы можете запустить socket.py:

  djbaldey@rosix examples $ python socket.py
Socket ID= 88080431

и затем запустить plug.py, используя ID:

  djbaldey@rosix examples $ python plug.py 88080431
Plug ID= 90177539

Вывод с терминала socket'а:
Я ( <gtk.Socket object at 0xb61854dc (GtkSocket at 0x903e670)> ) только что подключил штепсель!