2.2. Teoría de Señales y Retrollamadas

Nota

En la versión 2.0 de GTK+, el sistema de señales se ha movido de GTK+ a GLib. No entraremos en detalles sobre las extensiones que GLib 2.0 tiene en relación con el sistema de señales de GTK 1.2. Las diferecias no deberían notarse en el uso de PyGTK.

Antes de entrar en detalle en helloworld.py, discutiremos las señales y las retrollamadas. GTK+ es una biblioteca orientada a eventos, lo que significa que se dormirá en la función gtk.main() hasta que un evento ocurra y el control pase a la función apropiada.

Esta delegación del control se realiza usando la idea de "señales". (Nótese que estas señales no son las mismas que las señales de los sistemas Unix, y no se implementan usando éstas, aunque la terminología es casi idéntica) Cuando ocurre un evento, como cuando presionamos un botón del ratón, la señal apropiada se "emite" por el el control que fué presionado. Así es cómo GTK+ hace la mayoría de su trabajo útil. Hay señales que todos los controles heredan, como "destroy", y hay señales que son específicas de cada control, como "toggled" en el caso de un botón de activación.

Para hacer que un botón realice una acción, debemos configurar un manejador de señales que capture estas señales y llame a la función apropiada. Esto se hace usando un método de gtk.Widget (heredado de la clase GObject) como por ejemplo:

  handler_id = object.connect(name, func, func_data)

donde object es la instancia de gtk.Widget (un control) que estará emitiendo la señal, y el primer argumento name es una cadena que contiene el nombre de la señal que se desea capturar. El segundo argumento, func, es la función que se quiere llamar cuando se produce el evento. El tercer argumento, func_data, son los datos que se desean pasar a la función func. El método devuelve un handler_id que se puede usar para desconectar o bloquear el uso del manejador.

La función especificada en el tercer argumento se llama "función de retrollamada", y generalmente tiene la forma:

  def callback_func(widget, callback_data):

donde el primer argumento será una referencia al widget (control) que emitió la señal, y el segundo (callback_data) una referencia a los datos dados como último argumento en el método connect() mostrado antes.

Si la función de retrollamada es un método de un objeto entonces tendrá la forma general siguiente:

  def callback_meth(self, widget, callback_data):

donde self es la instancia del objeto que invoca este método. Esta es la forma usada en el programa de ejemplo helloworld.py.

Nota

La forma anterior de declaración de una función de retrollamada a señales es sólo una guía general, ya que las señales específicas de los distintos controles generan diferentes parámetros de llamada.

Otra llamada que se usa en el ejemplo helloworld.py es:

  handler_id = object.connect_object(name, func, slot_object)

connect_object() es idéntica a connect(), exceptuando que una función de retrollamada sólo usa un argumento, y un método de retrollamada, dos argumentos:

  def callback_func(object)
  def callback_meth(self, object)

donde object normalmente es un control. connect_object() permite usar los métodos de controles PyGTK qué solo admiten un argumento (self) como manejadores de señales.