Acerca de Ruby, Glade y Libglade
Ruby es un lenguaje de programación interpretado y totalmente orientado a objetos. Según su autor, el japonés Yukihiro Matsumoto (Matz), está parcialmente inspirado en Eiffel y Ada, y toma de Smalltalk la idea de que absolutamente todos los datos sean tratados como objetos (incluso los literales).
Este lenguaje ha gozado de muy buena reputación en Japón, pero en los últimos años la comunidad de usuarios se ha extendido por todo el mundo a un ritmo impresionante. En este tutorial utilizaremos la versión 1.8, aunque probablemente funcione también con versiones anteriores como la 1.6.
Por su parte, Glade es un constructor de interfaces gráficas de usuario para GTK+ y GNOME. Por sí sólo, Glade es capaz de generar código C. Sin embargo, utilizando libglade, es posible combinar las interfaces desarrolladas usando Glade con otros lenguajes como C++, Ada95, Python, Perl y, por supuesto, Ruby.
Presentación del ejemplo: una calculadora
Todo tutorial que se precie ha de girar en torno a uno o varios ejemplos (bueno, al menos esa es mi humilde opinión). En este caso, se va a fijar como objetivo la construcción de una más que sencilla calculadora capaz tan sólo de realizar las cuatro operaciones básicas que todos aprendimos en nuestros primeros años como "estudiantes": sumar, restar, multiplicar y dividir.
Esta calculadora dispondrá de una interfaz gráfica, mediante la cuál el usuario indicará la operación a realizar.
Una buena práctica de programación orientada a objetos es separar la calculadora de la interfaz, y modelarla, por ejemplo, como una clase (escrita en Ruby, por supuesto). Así que, en primer lugar, implementaremos esta clase, dejando para después la elaboración de la interfaz.
La clase Calculadora
La clase que representará a la calculadora es de lo más sencilla. Contará con dos atributos -cada uno de los cuales representa a uno de los operandos- y cuatro métodos, uno por cada operación matemática que implementaremos.
La siguientes líneas de código sirven para implementar esta idea:
class Calculadora
attr_writer :a, :b
def sumar
@a + @b
end
def restar
@a - @b
end
def multiplicar
@a * @b
end
def dividir
@a / @b
end
end
Construyendo la interfaz
Una vez que tenemos escrito el "motor" de la aplicación -la clase Calculadora- llega el momento de construir la interfaz. Para ello, vamos a utilizar la herramienta Glade.
Al ejecutar Glade sin ningún parámetro, el programa nos deja preparado un espacio para ponernos a trabajar directamente en nuestro nuevo proyecto. Vamos entonces a la paleta y escogemos el elemento Ventana. Si lo creemos oportuno, podemos hacer una primera modificación de sus propiedades cambiando, por ejemplo, la barra de título.
Sobre esta ventana que acabamos de crear, vamos a situar los botones -uno por cada operación y otro para salir- y las cajas correspondientes para la entrada de los operandos.
Pero antes de colocar estos elementos, hay que escoger de qué modo se distribuirán sobre la ventana. Para simplificar, escogeremos Posiciones estáticas: seleccionamos el elemento de la paleta y lo situamos en la ventana.
Ahora sí está todo listo para comenzar a colocar el resto de componentes de la interfaz. Comenzaremos con los recuadros de texto, a los que llamaremos cuadroA, cuadroB y cuadroResultado. El procedimiento es sencillo: para cada uno, se escoge un cuadro de texto de la paleta, se sitúa sobre la ventana y, finalmente, se modifican sus propiedades -como por ejemplo su nombre-.
Ya preparados los cuadros de texto, llega el turno de los botones. Se pondrá uno por cada una de las cuatro operaciones ariméticas y otro para salir de la aplicación. Al igual que en el caso de los cuadros de texto, los botones se sacan de la paleta y se sitúan sobre la ventana. Los nombres de los botones serán, por ejemplo: botonSumar, botonRestar, botonMultiplicar, botonDividir y botonSalir. En lo que a los botones se refiere, queda aún algo de trabajo por hacer, pero lo veremos más adelante. Para terminar, guardamos el proyecto donde nos apetezca.
Cargando la interfaz desde el código Ruby
Recapitulando: ya tenemos la clase Calculadora y un diseño de la interfaz de la aplicación. De momento, ambas son entidades separadas, así que a continuación vamos a combinarlas, usando libglade, para componer la aplicación final.
Empezaremos editando el código Ruby: aunque es una buena práctica que cada clase se encuentre en un fichero separado, no vamos a preocuparnos por eso, vamos a meter todo el código Ruby en el mismo archivo.Lo primero que debemos indicar al intérprete de Ruby, es que haga uso de libglade:
require 'libglade2'
A continuación, vamos a crear una clase CalculadoraSimplona que representará a la aplicación, siguiendo así uno de los principios de Ruby donde todo es un objeto.
class CalculadoraSimplona
TITLE = "Calculadora Simplona"
NAME = "CalculadoraSimplona"
VERSION = "1.0"
def initialize(path)
@glade = GladeXML.new(path) {|handler| method(handler)}
@cuadroA = @glade.get_widget("cuadroA")
@cuadroB = @glade.get_widget("cuadroB")
@cuadroResultado = @glade.get_widget("cuadroResultado")
@laCalculadora = Calculadora.new
end
end
Analicemos ahora los elementos más interesantes de este código:
- El constructor de la clase CalculadoraSimplona -initialize- se encarga de "cargar" la interfaz -gracias a libglade- haciendo uso de la clase GladeXML, a cuyo constructor se le pasa como parámetro el nombre del fichero .glade de la interfaz que construimos anteriormente con Glade.
@glade = GladeXML.new(path) {|handler| method(handler)}
- Estas tres líneas, crean tres objetos de la clase GTK::Entry que representan los diferentes cuadros de texto de la interfaz. Esta clase nos ofrece todos los métodos necesarios para manipular esos elementos de la interfaz.
@cuadroA = @glade.get_widget("cuadroA")
@cuadroB = @glade.get_widget("cuadroB")
@cuadroResultado = @glade.get_widget("cuadroResultado")
- Un apunte: el objeto no tiene por qué llamarse igual que el elemento de la interfaz. Es decir, esto es perfectamente válido:
@operandoA = @glade.get_widget("cuadroA");
- Para terminar con la inicialización de la aplicación, se crea una instancia de la clase Calculadora.
@laCalculadora = Calculadora.new
Inicialización de la biblioteca GTK+
Para que la biblioteca GTK+ comience a trabajar correctamente, es necesario inicializarla y lanzar su "bucle" principal. Para ello se añaden las tres líneas siguientes al final del fichero de código Ruby:
Gtk.init
CalculadoraSimplona.new("calculadora.glade")
Gtk.main
Con el fin de probar que todo esto funciona, vamos a ejecutar la aplicación: ruby calculadora.rb
En principio, como aún no hemos programado qué debería hacer ninguno de los botones, obtendremos una interfaz que no ofrece ninguna funcionalidad. De hecho, ni siquiera se puede salir de él de otra forma que no sea "matándolo".
La programación de las acciones a ejecutar al pulsar un botón, las dejaremos ya para el segundo artículo.