10.13. Elementos incrustables y puntos de conexión (Plugs y Sockets)

Los Plugs y los Sockets cooperan para embeber la interfaz de un proceso en otro proceso. Esto también se puede lograr con el uso de Bonobo.

10.13.1. Elementos incrustables (Plugs)

Un Plug encapsula una interfaz de usuario aportada por una aplicación de forma que se puede embeber en la interfaz de otra aplicación. La señal "embedded" alerta a la aplicación embebida que ha sido embebida en la interfaz de usuario de la otra aplicación.

Un Plug se crea con la siguiente función:

  plug = gtk.Plug(socket_id)

que crea un nuevo Plug y lo embebe en el Socket identificado por socket_id. Si socket_id es 0L, el elemento conectable queda "desconectado" y puede ser conectado más tarde a un Socket utilizando el método de Socket add_id().

El método de Plug:

  id = plug.get_id()

devuelve el identificador de ventana (window ID) de un Plug, que se puede usar para embeberlo en un Socket utilizando el método de Socket add_id().

El programa de ejemplo plug.py ilustra el uso de un elemento conectable Plug:

    1	#!/usr/bin/python
    2	
    3	import pygtk
    4	pygtk.require('2.0')
    5	import gtk,sys
    6	
    7	Wid = 0L
    8	if len(sys.argv) == 2:
    9	    Wid = long(sys.argv[1])
   10	
   11	plug = gtk.Plug(Wid)
   12	print "Plug ID=", plug.get_id()
   13	
   14	def embed_event(widget):
   15	    print "I (",widget,") have just been embedded!"
   16	
   17	plug.connect("embedded", embed_event)
   18	
   19	entry = gtk.Entry()
   20	entry.set_text("hello")
   21	def entry_point(widget):
   22	    print "You've changed my text to '%s'" % widget.get_text()
   23	
   24	entry.connect("changed", entry_point)
   25	plug.connect("destroy", gtk.mainquit)
   26	
   27	plug.add(entry)
   28	plug.show_all()
   29	
   30	
   31	gtk.mainloop()

El programa se invoca así:

  plug.py [windowID]

donde windowID es el ID (identificador) de un Socket al que conectar el Plug.

10.13.2. Puntos de Conexión (Sockets)

Un Socket proporciona el control que permite embeber un control incrustable Plug desde otra aplicación a la propia interfaz de forma transparente. Una aplicación crea un control Socket, pasa el ID de ventana de ese control a otra aplicación, que luego crea un Plug utilizando ese ID de ventana como parámetro. Cualquier control contenido en el elemento Plug aparece dentro de la ventana de la primera aplicación.

El identificador (ID) de ventana del Socket se obtiene utilizando el método de Socket get_id(). Antes de usar este método el Socket debe estar realizado y añadido a su control padre.

Nota

Si se le pasa el ID de ventana del Socket a otro proceso que va a crear un elemento Plug en el Socket, es preciso asegurarse de que el control Socket no se va a destruir hasta que se crea el elemento Plug.

Cuando se notifica a GTK+ que la ventana embebida ha sido destruída, entonces también se encarga de destruir el Socket. Por tanto, se debe prever la posibilidad de que los sockets se destruyan en cualquier momento mientras el bucle de eventos principal está en ejecución. La destrucción de un Socket provocará también la destrucción de un Plug embebido en él.

La comunicación entre un Socket y un Plug se hace según el protocolo XEmbed. Este protocolo también se ha implementado en otros toolkits como Qt, lo que permite el mismo nivel de integración al integrar un control de Qt en GTK+ o viceversa.

Creación de un nuevo Socket vacío:

  socket = gtk.Socket()

El Socket debe estar contenido en una ventana raíz antes de la invocación del método add_id():

  socket.add_id(window_id)

que añade un cliente XEMBED, tal como un Plug, al Socket. El cliente puede estar en el mismo proceso o en uno diferente.

Para embeber un Plug en un Socket se puede, bien crear el Plug con:

  plug = gtk.Plug(0L)

y luego pasar el número devuelto por el método de Plug get_id() al método de Socket add_id():

  socket.add_id(plug)

, o bien se puede invocar el método de Socket get_id():

    window_id = socket.get_id()

para obtener el identificador de ventana (ID) del socket, y luego crear el plug con:

  plug = gtk.Plug(window_id)

El Socket debe haber sido añadido ya a una ventana raíz antes de que se pueda hacer esta llamada.

El programa de ejemplo socket.py ilustra el uso de un Socket:

    1	#!/usr/bin/python
    2	
    3	import string
    4	
    5	import pygtk
    6	pygtk.require('2.0')
    7	import gtk,sys
    8	
    9	window = gtk.Window()
   10	window.show()
   11	
   12	socket = gtk.Socket()
   13	socket.show()
   14	window.add(socket)
   15	
   16	print "Socket ID=", socket.get_id()
   17	window.connect("destroy", gtk.mainquit)
   18	
   19	def plugged_event(widget):
   20	    print "I (",widget,") have just had a plug inserted!"
   21	
   22	socket.connect("plug-added", plugged_event)
   23	
   24	if len(sys.argv) == 2:
   25	    socket.add_id(long(sys.argv[1]))
   26	
   27	gtk.mainloop()

Para ejecutar el ejemplo se puede usar plug.py antes:

  $ python plug.py
  Plug ID= 20971522

y copiar el identificador ID al primer algumento de socket.py:

  $ python socket.py 20971522
  Socket ID= 48234523
  I ( <gtk.Plug object (GtkPlug) at 0x3008dd78> ) have just been embded!
  I ( <gtk.Socket object (GtkSocket) at 0x3008ddf0> ) have just had a plug inserted!

O se puede ejecutar socket.py:

  $ python socket.py
  Socket ID= 20971547

y después: plug.py, copiando el identificador ID de ventana:

  $ python plug.py
  20971547
  I ( <gtk.Socket object (GtkSocket) at 0x3008ddf0> ) have just had a plug inserted!
  Plug ID= 48234498