Está en la página 1de 10

William Viana y Andreu Belmonte 40

Para el caso anterior, con definir una función A la hora de la verdad no será necesario realizar este proceso manualmente. Por un lado, cuando queramos
con nombre on_Boton_Clicked() hubiera sido conectar unas señales con otras lo haremos en el propio designer-qt4 de forma gráfica. Y por otro lado, para
suficiente. conectar las señales con nuestras funciones, utilizaremos una nomenclatura determinada y el propio sistema nos
las conectará automáticamente.

7.3 Diseño del interfaz: Designer-qt


Para poder diseñar nuestro interfaz podríamos crear a mano definiendo en nuestro código los distintos elemen-
tos indicando sus propiedades y coordenadas. Pero será mucho más fácil si utilizamos la aplicación que nos
proporcionan las propias Qt, el QtDesigner.
William Viana y Andreu Belmonte 41

Las partes principales del interfaz que usaremos son:


Qt Desinger (ventana principal) ahí tenemos todos los elementos para poder arrastrarlos a nuestra aplicación
Property Editor editor de propiedades del elemento que tengamos seleccionado
Object Inspector lista jerárquica con las clases que estamos usando en nuestro interfaz
Signal/Slot Editor podremos editar las conexiones que tengamos y añadir nuevas manualmente
Inicialmente deberemos seleccionar que tipo de venta queremos crear, normalmente Main Window o Widget
A la hora de crear nuestras aplicaciones será interesantes que organicemos los elementos en layouts para que se
redimensionen automáticamente con la ventana.

En el propio desginer podremos definir que señales queremos conectar, como se ha visto antes se pueden relacionar
varios tipos de señales y eventos, pero en este caso, solo lo utilizaremos para relacionar elementos entre sí.
presionando F4 entraremos en modo Edit Singals/Slots, el funcionamiento es Drag&Drop1 , seleccionamos un
elemento de el que queremos capturar una señal y los soltamos en otro al que le queremos activar otra. Nos
aparecerá una ventana de dialogo donde deberemos seleccionar concretamente las señales que queremos conectar
(como se muestra en la figura).
1 arrastrar y soltar
William Viana y Andreu Belmonte 42

Generar el código

Es recomendable utilizar una nomenclatura Una vez creado el interfaz lo guardaremos como fichero .ui, esto es, un fichero en XML con la especificación de
más o menos formal para cada tipo de fichero. nuestra ventana. Tendremos que transformarlo en código para poderlo utilizar en nuestra aplicación. Y para
Por ejemplo: ello utilizaremos la herramienta rbuic que nos proporcionan los propios bindings de qt4-ruby. La forma de uso
• ui_nombreinterfaz.rb para la especifi- es muy simple:
cación del interfaz
$ r b u i c form . u i > ui_form . rb
• nombreinterfaz.rb para la parte de im-
$
plementación que veremos más adelante

Opcionalmente le podemos pasar el parámetro -x que nos generará el código necesario para poder cargar direc-
tamente la aplicación desde la linea de comandos y comprobar que está todo correcto.
Como ejemplo el código que correspondería a la siguiente ventana:
William Viana y Andreu Belmonte 43

ui_form.rb
1 c l a s s Ui_Form
2 attr_reader : l a be l
3 a t t r _ r e a d e r : pushButton
4
5 def s e t u p U i ( form )
6 form . setObjectName ( " form " )
7 @ l a b e l = Qt : : L a b e l . new ( form )
8 @ l a b e l . setObjectName ( " l a b e l " )
9 @ l a b e l . setGeometry ( Qt : : Rect . new ( 1 1 0 , 6 0 , 1 9 1 , 9 1 ) )
10 @ l a b e l . setFrameShape ( Qt : : Frame : : Box )
11 @pushButton = Qt : : PushButton . new ( form )
12 @pushButton . setObjectName ( " pushButton " )
13 @pushButton . setGeometry ( Qt : : Rect . new ( 1 7 0 , 2 1 0 , 8 0 , 2 7 ) )
14 r e t r a n s l a t e U i ( form ) ;
15 s i z e = Qt : : S i z e . new ( 4 4 5 , 2 9 6 )
16 s i z e = s i z e . expandedTo ( form . minimumSizeHint ( ) )
17 form . r e s i z e ( s i z e )
18
19 Qt : : MetaObject . connectSlotsByName ( form )
20 end # s e t u p U i
21
22 def r e t r a n s l a t e U i ( form )
23 form . setWindowTitle ( Qt : : A p p l i c a t i o n . t r a n s l a t e ( " Form " , " Form " , n i l , Qt : :
A p p l i c a t i o n : : UnicodeUTF8 ) )
24 @ l a b e l . s e t T e x t ( Qt : : A p p l i c a t i o n . t r a n s l a t e ( " Form " , " TextLabel " , n i l , Qt : :
A p p l i c a t i o n : : UnicodeUTF8 ) )
25 @pushButton . s e t T e x t ( Qt : : A p p l i c a t i o n . t r a n s l a t e ( " Form " , " PushButton " , n i l , Qt : :
A p p l i c a t i o n : : UnicodeUTF8 ) )
26 end # r e t r a n s l a t e U i
27
28 end
29 module Ui
30 c l a s s Form < Ui_Form
31 end
32 end # module Ui
William Viana y Andreu Belmonte 44

7.4 Implementación de la funcionalidad del interfaz


Ya tenemos nuestro interfaz. Ahora deberemos de conectar los widgets con las funciones de nuestra aplicación.
Para poder acceder a las propiedades de En el fichero del interfaz tenemos implementado un modulo Ui que incluye la clase Form. Crearemos un nuevo
cualquiera de los elementos del interfaz, ten- fichero en el que tendremos que incluir la definición del interfaz, el método initialize (el constructor) deberá crear
dremos que hacerlo a través de dicha variable, un objeto de la clase que corresponderá a una instancia de Ui::Form.
por ejemplo @ui.pushButton corresponderá al
form.rb
objeto que contiene el botón.
1 r e q u i r e ’ ui_form . rb ’
2
3 c l a s s Form < Qt : : Widget
4 s l o t s ’ on_pushButton_released ( ) ’
5
6 def i n i t i a l i z e ( p a r e n t=n i l )
7 super ( p a r e n t )
8 @ui=Ui : : Form . new
9 @ui . s e t u p U i ( s e l f )
10 end
11
12 def on_pushButton_released ( )
13 @ui . l a b e l . s e t T e x t ( " h o l a " )
14 end
15 end

Tenemos definido un slot, que corresponde con la función on_pushButton_released():


nombre del widget
z }| {
on_ pushButton _ released
| {z }
evento capturado

Siguiendo este formato tendremos nuestras señales y slots conectados ya que en el constructor se ejecuta el
método connectSlotsByName.
Para consultar información referente a los Como vemos capturará el evento de pulsado del botón pushButton, y lo que hará es cambiar el texto del label
métodos y clases, disponemos del comando mediante el método setText propio de la clase Qt::Label.
rbqtapi equivalente al ri normal de ruby
En ocasiones no nos valdrá con la definición por defecto o querremos definir nuestras señales a mano, lo normal
será hacerlo en el constructor:
William Viana y Andreu Belmonte 45

Qt : : Obj ect . c o n n e c t ( @ui . l i s t a , SIGNAL( ’ i t e m C l i c k e d ( QListWidgetItem ∗ ) ’ ) , s e l f , SLOT( ’


o n _ l i s t a _ i t e m D o u b l e C l i c k e d ( QListWidgetItem ∗ ) ’ ) )

7.5 Aplicación principal


Por último crearemos un nuevo fichero en el que incluiremos nuestra nueva clase Form. De esta forma, podremos
añadir en nuestra aplicación todas los interfaces que sean necesarias. En este código simplemente crearemos una
instancia de aplicación (línea 4) y le incluiremos un nuevo objeto de nuestra ventana (línea 5):

main.rb
1 r e q u i r e ’ form . rb ’
2
3 i f $0 == __FILE__
4 a = Qt : : A p p l i c a t i o n . new (ARGV)
5 u = Form . new
6 u . show
7 a . exec
8 end
8 Dice la leyenda que se empieza por documentar y se acaba por
implementar

8.1 Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
8.2 SimpleMarkup o yo solo sé HTML, ¿como se juega a esto? . . . . . . . . . . . . . 47
8.3 ¿y ahora?. . . ejecución sobre nuestro código . . . . . . . . . . . . . . . . . . . . . . . 50

46
William Viana y Andreu Belmonte 47

8.1 Introducción
A la hora de documentar no hay que perder En ruby existen dos formas de generar documentación a partir del propio código: rdoc y RDtool (también
de vista, que lo que queremos hacer no es ex- disponible para otros lenguajes).
plicar que hace cada línea de nuestro código,
Mientras que rdoc es básicamente un documentador de código, RDtool es un lenguaje de marcado que no entiende
sino cual es el cometido de cada uno de sus
nada de código. Con RDtool necesitas introducir etiquetas del tipo =begin/=end. En cambio rdoc parsea los
partes: que hacen nuestros métodos, para que
ficheros de código fuente extrayendo las clases, módulos, atributos y definiciones de métodos automáticamente.
sirve nuestra nueva clase, . . . Cuando pasado
un tiempo queramos recuperar un proyecto, Osea que rdoc es el documuentador de código para los vagos ;), pero que eso no os confunda, también dispone
o cuando queramos pasárselo a otra persona de un lenguaje propio en caso de que queramos ser más descriptivos a la hora de trabajar
agradeceremos haber realizado algunas anota-
ciones. 8.2 SimpleMarkup o yo solo sé HTML, ¿como se juega a esto?
Básicamente rdoc irá pillando todos los comentarios justamente anteriores a vuestras clases/módulos/métodos y
lo añadirá a la documentación. si queremos que quede más bonito será interesante añadir ciertas etiquetas. Para
consultar el código y el resultado de los ejemplos que se irán mostrando se puede acceder a la siguiente dirección:
http://www.aditel.org/~andreu/ruby/rdoc_example/

verbatim

Todas las lineas que comiencen a la misma distancia del margen serán tratadas como párrafos, pero si le añadimos
un nivel de identación nos lo meterá como verbatim, es decir, no procesará las directivas que encuentre dentro.
1 #Esto e s una l i n e a de c o m e n t a r i o
2# p e r o a q u i no t r a t a r e m o s l o s t a g s que
3# veremos mas a d e l a n t e , como puede s e r :
4# ∗ negrita ∗
5 c l a s s Verbatim
6 end

Formateo del texto

Tenemos tres tipos de letra: negrita, cursiva y máquina de escribir. Tenemos dos formas de etiquetar el texto:
rodeando la palabra con símbolos espaciales (*,+,_) o utilizando tags del tipo HTML:
William Viana y Andreu Belmonte 48

1 #∗ <b>n e g r i t a </b >:


2 # − \<b>n e g r i t a </b>
3 # − \∗ n e g r i t a ∗
4 #∗ <em>c u r s i v a </em>
5 # − \<em>c u r s i v a </em>
6 # − \ _cursiva_
7 #∗ <t t >maquina de e s c r i b i r </ t t >
8 # − \< t t >maquina de e s c r i b i r </ t t >
9 # − \+maquina de e s c r i b i r+
10 c l a s s Formateo_del_texto
11 end

Listas y descripciones

Las listas ya aparecían en el apartado anterior, podemos utilizar varios tipos:


1 #∗ un ’ ∗ ’ o ’ − ’ para l i s t a s i m p l e
2 #∗ un numero s e g u i d o de un punto
3 # para una l i s t a numerada
4 # 1 . uno
5 # 2 . dos
6 # 3. tres
7 #∗ una l e t r a s e g u i d a de un punto
8 # para numerar con l e t r a s
9# a. a
10 # b . be
11 # c . ce
12 c l a s s L i s t a s _ y _ d e s c r i p c i o n e s
13 end

Comentarios comentados (?¿?¿?)

Si en ocasiones añadimos anotaciones con comentarios internos para uno mismo (tu ya me entiendes), es intere-
sante que luego no aparezca en la documentación final. . . no queda bonito. Lo delimitaremos con #– y #++:
1 #Esta c l a s e e s muy i m p o r t a n t e
William Viana y Andreu Belmonte 49

2 #−−
3 #j a j a j a p e r o s i no v a l e pa na
4 #p e r o bueno
5 #++
6 #no hay que d e j a r de u s a r l a
7 c l a s s Comentarios
8 end

Titulos

En este ejemplo podemos ver como hacer titulo con fuentes de tamaño más grande. Fijaros en el resultado final,
observad que los datos que devuelve la función con el yield, nos aparecen como datos de entrada de la función
en formato de bloque.
1 #=T i t u l o 1
2 #Esto e s t e x t o de e s t e p a r r a f o
3#
4 #==T i t u l o 2
5 #Texto d e l o t r o
6#
7#
8 class Titulos
9 def each
10 @datos . each do | dato |
11 yield dato
12 end
13 end
14
15 def [ ] ( i n d i c e )
16 return @datos [ i n d i c e ]
17 end
18 end