Introducción a Gtk#: Desarrollando aplicaciones gráficas con el entorno MONO. | ||
---|---|---|
Anterior | Introducción a Gtk# | Siguiente |
Hasta el momento parece que todo es perfecto, ¿no es así?, pues no del todo, ya que si quisieramos avanzar más, y sobre todo, desarrollar aplicaciones más complejas ( o menos sencillas ) tendríamos el porblema de que cada contenedor ( una ventana, o un botón por ejemplo, sólo pueden contener un elemento. Alguien podríua decir, ¿qué tal si anidamos elementos? simplemente el resultado sería terrible, ya que perderíamos control sobre algunos elementos, sin mencionar el pésimo aspecto gráfico.
Por esa razón, se pensó en las Boxes, que son elementos gráficos no visibles, que nos van a permitir organizar y empaquetar nuestros widgets. Pero, ¿cómo luce una Box ? una box lucería como :
De esa forma, podemos ir colocando dentro de sí elementos ( incluso otras boxes, sin perder calidad ), teniendo el control gráfico de nuestra aplicación ( ¡al fín! ).
Antes que nada, aprenderemos a declarar las boxes, en sus dos sabores, vertical y horizontal, aunque se declaran exactamente igual. Nos ayuderemos de imágenes que nos hagan ver más claro el panorama del uso de las boxes.
Los constructores de las boxes están definidos como:
public Hbox ( bool homegeneous, int spacing ) // Box horizontal public VBox ( bool homogeneous, int spacing ) // Box vertical |
Comprobamos que se declaran igual las verticales y las horizontales. Reciben como primer parámetro un valor booleano, que les indicará si deben ser o no homogéneos en su repartición de espacio en pantalla. En tanto tenemos que con el segundo, especificamos la cantidad de pixeles que habrá entre ellos de separación.
Y antes de pasar a la siguiente parte, que es el escribir una aplicación, sería bueno explicar como funciona el posicionamiento en las boxes. En ellas, los nuevos elementos van siendo posicionados o bien al principio o al final ( de izquierda a derecha en las verticales, y arriba a bajo en las horizontales ).
Para colocar elementos en las boxes, usamos los métodos:
public void PackStart(Gtk.Widget child, bool expand, bool fill, uint padding) // Al principio public void PackEnd(Gtk.Widget child, bool expand, bool fill, uint padding) // Al final |
Con ellos ponemos un elemento en el principio y fin, respectivamente. Su primer parámetro es el widget o elemento gráfico a colocar ( como un botón, un label, etc ). El segundo, bool expand, se encarga de definir si queremos que el elemento a colocar sea puesto de tal forma de quede en medio del total del área restante ( esto también s elogra con la propiedad Homogeneous de nuestra box ). En tanto, bool fill decide si, después de que hayamos especificado a expand como true, el widget debe se ocupar todo área desocupada. Finalmente, uint padding controla el espacio que deberá de haber de "margen" de tal elemento.
![]() | Recomiendo enormemente que Ud. sea tan amable de ponersea jugar un poco con las propiedades expand y fill para compredner un poco mejor su funcionamiento. |
Para usar las boxes, tenemos que definirlas, y posteriormente colocar elementos en su interior. Como ya vimos, para definir usamos el constructor arriba especificado. Para colocar los elementos, usamos dos métodos de las boxes en cuestión: PackStart() y PackEnd(), que se encargan de poner en una box un elemento al final y al fin, respectivamente.
Así las cosas, es hora de "codear" y poner en práctica nuestros conocimientos:
using System; using Gtk; using GtkSharp; public class Tester { static void BotonPresionado ( object obj, EventArgs args ) { // Definimos nuestro boton en funcion de object Button boton = (Button) obj; Console.WriteLine("{0} fue presionado.", boton.Label ); } static void DetenerAplicacion ( object obj, DeleteEventArgs args ) { Application.Quit(); } public static void Main ( string[] args ) { // Esta linea es indispensable en todas nuestras aplicaciones Application.Init(); Window win = new Window(" Botones "); HBox hbox = new HBox(false, 0); // Definimos nuestra HBox (Horizontal) Button boton = new Button(" Boton 1 "); win.DeleteEvent += new DeleteEventHandler(DetenerAplicacion); win.BorderWidth = 10; win.Add(hbox); // Definimos un EventHandler para Clicked de boton boton.Clicked += new EventHandler(BotonPresionado); hbox.PackStart(boton, true, false, 5 ); //Colocamos el boton al principio boton = new Button(" Boton 2 "); boton.Clicked += new EventHandler(BotonPresionado); hbox.PackStart(boton, true, false, 5); // Colocamos el otro boton win.ShowAll(); Application.Run(); } } |
Wow! todo va bien, ¿no es así?, ahora simplemente, como ejercicio adicional, implementemos otro botón, que sirva para cerrar nuestra aplicación:
using System; using Gtk; using GtkSharp; public class Tester { static void BotonPresionado ( object obj, EventArgs args ) { // Definimos nuestro boton en funcion de object Button boton = (Button) obj; Console.WriteLine("{0} fue presionado.", boton.Label ); } static void DetenerAplicacion ( object obj, DeleteEventArgs args ) { Application.Quit(); } // Definimos un nuevo método para el botón Cerrar static void BotonCerrar ( object obj, EventArgs args ) { Application.Quit(); } public static void Main ( string[] args ) { // Esta linea es indispensable en todas nuestras aplicaciones Application.Init(); Window win = new Window(" Botones "); HBox hbox = new HBox(false, 0); // Definimos nuestra HBox (Horizontal) Button boton = new Button(" Boton 1 "); win.DeleteEvent += new DeleteEventHandler(DetenerAplicacion); win.BorderWidth = 10; win.Add(hbox); // Definimos un EventHandler para Clicked de boton boton.Clicked += new EventHandler(BotonPresionado); hbox.PackStart(boton, true, false, 5 ); //Colocamos el boton al principio boton = new Button(" Boton 2 "); boton.Clicked += new EventHandler(BotonPresionado); hbox.PackStart(boton, true, false, 5); // Colocamos el otro boton // Implementamos el boton para cerrar la aplicación boton = new Button(" Cerrar "); boton.Clicked += new EventHandler (BotonCerrar); hbox.PackStart(boton, true, false, 5); win.ShowAll(); Application.Run(); } } |
¡Sensacional! ahora nuestra ventanita ya puede cerrarse con un botón. Nótese que tuvimos que crear otro método, BotonCerrar(), ya que la especificación del evento Clicked no converge con el argumento DeleteEventArgs, así que implementamos una que sí.
Ahora implementaremos otra forma de usar las boxes. Recordando que las boxes pueden ser incluidas en un contenedor ( Container ) o dentro de otra box, procederemos a incluir una HBox dentro de un botón ... sí, así es, no lo dije mal, pues al ser un boton ( Button ) un contenedor, puede a su vez tener dentro de sí una serie de elementos, y por supuesto, una HBox en este caso.
Para "ahorrarnos" un poco de trabajo, crearemos un método privado, static Button CrearBoton (), que devolvera un objeto tipo Button, tomando como argumento simplemente el PATH a una imagen en formato XPM ( el formato soportado por Gtk+/Gtk# ), y una cadena ( String ), que será la etiqueta que lleve.
Si se ha dado cuenta de que no tiene imágenes en formato XPM, quizás sería bueno que se pusiera a husmear en /usr/share, pues seguramente allí habrán varias en este formato; de otra forma, puede proceder a crear una personalizada en Gimp, cuidando simplemente la extensión y que el tamaño no sea muy grande.
using System; using Gtk; using GtkSharp; public class Tester { static int clicks = 0; static void BotonPresionado ( object obj, EventArgs args ) { clicks++; Console.WriteLine("Boton Personalizado activado {0} veces.", clicks); } static void DetenerAplicacion ( object obj, DeleteEventArgs args ) { Application.Quit(); } public static void Main ( string[] args ) { Application.Init(); Window win = new Window(" Packing "); HBox hbox = new HBox(false, 2); Button boton = new Button(); Label label = new Label("Presioname!"); win.DeleteEvent += new DeleteEventHandler(DetenerAplicacion); win.BorderWidth = 10; win.Add(boton); // Definimos un EventHandler para Clicked de boton boton.Clicked += new EventHandler(BotonPresionado); boton.Add(hbox); // Cargamos una imagen XPM Image imagen = new Image("imagen.xpm"); hbox.PackStart(imagen, true, false, 0); hbox.PackStart(label, true, true, 0); win.ShowAll(); Application.Run(); } } |
¡Bien! con esto comprobamos que existen muchas formas de utilizar las boxes, incluso dentro de un botón.