23
24 def to_s
25 Dias_semana [ @numdia ]
26 end
27 end
28
29 i f $0 == __FILE__
30 l a b o r a l = DiaSemana . new ( " l u n e s " ) . . DiaSemana . new ( " v i e r n e s " )
31 hoy = DiaSemana . new ( " domingo " )
32
33 i f l a b o r a l === hoy
34 p u t s "#{hoy } e s un d i a l a b o r a l "
35 else
36 p u t s "#{hoy } no e s un d i a l a b o r a l "
37 end
38
39 l a b o r a l . each { | d i a | p r i n t "#{d i a } " }
40 end
$ ruby diasemana . rb
domingo no e s un d i a l a b o r a l
l u n e s martes m i e r c o l e s j u e v e s v i e r n e s
$
El constructor lo primero que hace es comprobar si se le ha pasado un día de la semana válido: lo comprueba
mirando si está en el array Dias_semana con el método include?. Si está almacena la posición que ocupa el
día en el array (equivale a guardar el día en formato numérico empezando con lunes = 0). Si no está lanza
una excepción de tipo ArgumentError con el método raise. El método <=> (también conocido como nave
espacial) compara dos objetos y devuelve -1 si el primero es menor que el segundo, 0 si son iguales o 1 si el
segundo es menor que el primero. Eres bastante mayorcito para saber que hace el método succ El método to_s
sirve para poder imprimir nuestro objeto por pantalla. La línea 29 es un truco para saber si el programa ha sido
ejecutado directamente (útil si lo queremos probar). Cómo puedes ver en la línea 30 una instancia de nuestra
clase se crea con el nombre de la clase seguido de la palabra new y los argumentos que recibe el constructor
entre paréntesis.
Las clases pueden tener métodos de la clase. Un método de una clase no está asociado a un objeto de esa clase,
sino a la propia clase. Para llamarlo se hace con el nombre de la clase seguido de :: o . y el nombre del método.
William Viana y Andreu Belmonte 31
Definir métodos de una clase se hace de la misma forma: con el nombre de la clase seguido de :: o . y el nombre
del método.
5.1.1 Acceso
Al igual que otros lenguajes orientados a objeto como Java o C++ también se puede definir en Ruby el control
de acceso a una clase. Los modos de acceso son los usuales:
1 c l a s s Foo
2
3 def i n i t i a l i z e #por d e f e c t o e s p r i v a d o
4 ...
5 end
6
7 private #s o l o a c c e s i b l e d e s d e d e n t r o d e l o b j e t o
8 def bar
9 ...
10 end
11 p u b l i c #a c c e s i b l e d e s d e f u e r a d e l o b j e t o
12 def f o o
13 ...
14 end
15 p r o t e c t e d #p r i v a d o para e l e x t e r i o r p e r o a c c e s i b l e a l a s c l a s e s que heredan
16 def f o o b a r
17 ...
18 end
19
20 #Tambien s e puede d e f i n i r e l c o n t r o l de a c c e s o d e s p u e s de d e f i n i r l o s metodos
21 p r i v a t e : bar
22 p u b l i c : foo
23 p r o t e c t e d : f o o b a r
24
William Viana y Andreu Belmonte 32
25 end
5.1.2 Herencia
La clase Dvd es una clase hija de la clase Peli. Los métodos de la clase Dvd, al llamarse igual, sobreescriben los
métodos heredados pero con el método super dentro de un método se llama al método del mismo nombre de la
William Viana y Andreu Belmonte 33
clase padre.
Ruby no soporta herencia múltiple pero lo solventa con algo llamado Mixins, que veremos dentro de nada.
5.2 Módulos
Un módulo es algo parecido a una clase pero más sencillo. Se utiliza para agrupar cosas que tienen relación pero
que no forman una clase de manera natural. Dentro de un módulo puedes tener métodos, variables o clases. Para
acceder a algo de un método se utiliza el operador ::. De hecho has estado utilizando un módulo todo ese rato sin
darte cuenta. Los métodos print, puts y gets pertenecen al módulo Kernel y deberías estar llamándolos como
Kernel::print, Kernel::puts o Kernel::gets, pero como son métodos muy utilizados el intérprete de Ruby los
busca automáticamente en el módulo Kernel y por eso puedes omitirlo y simplemente poner puts.
5.3 Mixins
Un mixin, del inglés mezcla, no es más que una clase con un módulo dentro. Tienes una clase, le metes un módulo,
ya tienes un mixin. Dentro de una clase puedes meter cuantos módulos te apetezca y ésta “heredará” todo lo que
tenía el módulo. Los módulos dentro de una clase se comportan como si de una clase padre se trataran. Antes
hemos creado un mixin con el ejemplo de la clase DiaSemana. Incluimos el módulo Comparable y ganamos un
montón de métodos gratis, sólo había que cumplir una condición, tener definidos los métodos <=> y succ, ya
que Comparable asume que la clase que lo hereda los tiene definidos.
6 Si no lo apunto se me olvida
34
William Viana y Andreu Belmonte 35
Bueno, trabajar con ficheros en Ruby es muy sencillo, no quería incluir un capítulo entero para ello pero tenía que
contarlo en algún lado. Y cómo me quedará muy cortito también incluyo un poco de tratamiento de excepciones
y un último ejercicio cañero.
seguida del tipo de excepción. Si el bloque de código es susceptible de lanzar diferentes tipos de excepciones se
puede incluir un rescue para cada una. En el rescue es dónde tratas la excepción. Puede hacer que se vuelve
a ejecutar el código del begin con un retry o simplemente lanzar tu una excepción con raise.
1 begin
2 f i c h = F i l e . new ( " f i c h e r o " )
3 f i c h . each_line { | l i n e a | puts l i n e a }
4 fich . readline
5 rescue EOFError
6 r a i s e EOFError , " s e ha a l c a n z a d o e l f i n a l d e l f i c h e r o "
7 end
7.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
7.2 Estructura de un interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
7.2.1 Signal’n’Slots: Connecting Peoples’ objects . . . . . . . . . . . . . . . . . . . . . . . . . 39
7.3 Diseño del interfaz: Designer-qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
7.4 Implementación de la funcionalidad del interfaz . . . . . . . . . . . . . . . . . . . . 44
7.5 Aplicación principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
37
William Viana y Andreu Belmonte 38
7.1 Introducción
Qt es una biblioteca multiplataforma para desarrollar interfaces gráficas de usuario. Fue creada por la compañía
noruega Trolltech. Qt es utilizada en KDE, un entorno de escritorio para sistemas como linux o FreeBSD, entre
otros. Utiliza el lenguaje de programación C++ de forma nativa.
Qt4-ruby son los binding de Qt4 para ruby. Permite realizar aplicaciones gráficas utilizando dichas librerías pero
utilizando nuestro lenguaje de programación favorito ruby ;).
El proceso se dividirá básicamente en dos etapas. En la primera de ellas diseñaremos como será nuestra aplicación
visualmente: como le mostraremos por pantalla al usuario los datos y como podrá introducirlos él. En una segunda
fase definiremos como interactuar con cada uno de los elementos y como interactuarán los elementos entre sí.
«Programming isn’t about what you know; it’s El objetivo final de este documento no es enseñar como trabajar con las Qt, sino proporcionar los conocimientos
about what you can figure out. As long as you y las herramientas necesarias para poder utilizarlas con ruby y describir un breve ejemplo de como hacerlo.
know where to find out the things you forgot,
you’re doing just fine.» Chris Pine 7.2 Estructura de un interfaz
Qt está estructurado en clases. Hay clases que están en lo alto de la jerarquía y hay otras que heredan de estas.
No vamos a entrar a explicar demasiado detalladamente como se estructura, pero a grandes rasgos (y teniendo
en cuenta los cambios que ha habido con la nueva versión) las clases que más comúnmente usaremos las podemos
dividir en estos grandes grupos:
QWidget:: Clase base para crear varios tipos de ventana
• QMainWindow:: Ventana principal de aplicación, posiblemente con menús, barras de herramientas, barras
de estado,. . .
• QDialog:: Ventana de dialogo para tareas simples y a corto término: diálogos de error, abrir archivos,
seleccionar color,. . .
QLayout:: clase base para el manejo de geometrías, redimensionamiento automático para componer diálogos más
complejos:
• QBoxLayout:: de ésta clase heredan QHBoxLayout y QVBoxLayout para construir diseños en horizontal o
vertical.
• QGridLayout:: útil para construir diseños en forma de cuadrícula
• QStackedLayout:: para crear un conjunto de widgets de los que solo se muestra uno cada vez
William Viana y Andreu Belmonte 39
De QWidget también heredan las clases de de los elementos básicos de un interfaz como pueden ser:
• QComboBox:: Lista emergente de datos, que puede ser editable para introducir nuevos elementos
• QLabel:: para mostrar texto e imágenes
• QPushButton botón
• QTextBrowser:: Caja de edición de texto con tags HTML
Es posiblemente la mayor diferencia entre Qt y los otros toolkits de programación gráfica. Mientras la mayoría
Callback: es un puntero a una de otros entornos utilizan los callbacks en Qt usaremos los Signals y los Slotss.
función, que le pasas a una fun-
• Una Signal es emitida cuando un determinado evento ocurre, los objetos de Qt disponen de numerosos
ción de tratamiento de un deter-
eventos que generarán su correspondiente señal.
minado evento. Cuando ocurre un
evento en un objeto, la función de • Un Slot es una función que se llama como respuesta a una determinada señal (pero que también puede ser
tratamiento llama a nuestra fun- llamada directamente desde nuestro código).
ción callback.
Lo que tenemos que hacer es conectar cada señal que queremos tratar con un slot o incluso varios si fuera
También podemos conectar señales con necesario. .
señales: cuando se emite una señal, automáti-
Las Señales y los Slots no saben si están conectadas o si hay alguien conectado a ellas lo que garantiza que
camente ésta hace que se emita la segunda
estemos creando componentes independientes entre sí.
Tomemos como ejemplo un botón instanciado de la clase Qt::PushButton. Las acciones que podemos realizar con
un botón son:
Evento Señal emitida
Presionar el botón pressed
Dejar de presionarlo released
Pulsarlo: Presionar+Dejar clicked
Si queremos que nuestra aplicación trate el botón cuando sea pulsado, deberemos conectar su señal con un slot
que nosotros definamos:
\ t e x t i t {Qt } : : Obj ect . c o n n e c t ( @Boton , SIGNAL( ’ c l i c k e d ( b o o l ) ’ ) , s e l f , SLOT( ’ f u n c i o n ( ) ’ ) )