Consejos para trabajar con Python + GTK2

Introducción

Hoy en día es cada vez más común que deseemos dotar a nuestros programas de alguna interfaz gráfica vistosa, sobre todo para hacerlos más fáciles de usar. En Python existen varias alternativas, aunque la gran mayoría implican diseñar la interfaz únicamente a base de escribir código. Esto tiende a volverse engorroso, y no es recomendable para programadores impacientes.

Después de probar diversas alternativas, creo haber encontrado la que más me convence. Python (por supuesto) combinado con Glade-2, y algunas librerías que ahora comentaré. Glade es un programa orientado al diseño de interfaces gráficas utilizando la librería GTK; viene preparado incluso para autogenerar código para lenguajes como C, C++ o Perl, pero es una opción poco recomendable debido a la ofuscación que termina teniendo el código autogenerado.

En mi opinión, la forma más cómoda de trabajar es la siguiente:

A continuación daré unas breves directivas acerca de cómo manejar todo esto con soltura y comodidad.

Programas y librerías necesarios

Todos los programas y librerías que voy a utilizar están disponibles en la red de diversas formas, ya que se trata de programas de código libre. Yo utilizo la distribución Debian de GNU/Linux (en su versión testing), por lo que daré el nombre de los paquetes necesarios en esta distro por si a alguien le sirve de ayuda. Supongo que encontrar los paquetes para otras distribuciones (o incluso para Windows, quien sabe) no debería ser demasiado difícil.

Pues bien, lo que necesitamos es:

Teniendo todo esto instalado, ya podemos ponernos a diseñar nuestra interfaz, y guardarla como archivo .glade. Además, podemos leer este archivo .glade desde Python, con lo que separamos el diseño de la implementación, pero sin perder la "conexión" entre ambos.

No me voy a extender explicando como diseñar interfaces con Glade que para eso ya hay tutoriales y además es bastante intuitivo si se le ponen ganas. Lo que sí que voy a hacer es contar un par de truquillos que se pueden usar en un programa Python para manejar la interfaz creada con Glade con más comodidad.

Consejos útiles - un poco de código

Supongamos que ya tenemos nuestra flamante interfaz gráfica generada por Glade, y guardada en el fichero interfaz.glade. Pues bien, ahora queremos poder trabajar con esa interfaz desde un programa Python de la forma más cómoda posible. A mí, para conseguirlo me gusta utilizar el siguiente código:

import pygtk
pygtk.require('2.0')
import gtk
import gtk.glade

class Widgets:
    def __init__(self,file):
        self.widgets = gtk.glade.XML(file)
    def __getitem__(self,key):
        return self.widgets.get_widget(key)

widgets = Widgets('interfaz.glade')

El hecho de hacer pygtk.require('2.0') es importante porque nos asegura que se va a importar la versión 2 de las GTK cuando hagamos import gtk, y que gtk.glade leerá correctamente el fichero .glade generado por la versión 2 de Glade.

La clase Widgets simplemente nos forma un wrapper muy cómodo para trabajar con los widgets que tengamos definidos en nuestra interfaz. Una vez hemos inicializado una instancia de la clase (proporcionándole el nombre del fichero a cargar), podemos acceder a cada widget simplemente usando la sintaxis widgets['nombre_del_widget'].

Otra característica deseable que podemos tener es una forma lo más sencilla posible de definir los handlers para las señales que reciban los widgets. Para mí el mejor método es el siguiente:

connections = {
        'mainWindow/destroy'  : terminar,
        'Boton1/clicked'      : on_Boton1_clicked,
        'Boton2/clicked'      : on_Boton2_clicked
        }
for wid_con, func in connections.iteritems():
        wid,con = wid_con.split('/')
        widgets[wid].connect(con,func)

En el diccionario connections pongo como claves las cadenas nombrewidget/nombreseñal, y para cada widget y señal indico el handler que voy a utilizar (esto es, el nombre de la función). Después recorro el diccionario, divido cada clave en el nombre del widget y de la señal, y los "conecto" con el handler. Es interesante destacar que puesto que en el diccionario lo que se guarda en los valores son objetos con la propiedad callable, podemos introducir funciones lambda o cualquier tipo de filigrana que se nos ocurra.

Más documentación

Puesto que aquí solo he explicado algunos truquillos, si no se está familiarizado con el funcionamiento de las GTK, sería interesante visitar los siguientes enlaces:
Volver a la página principal