Bueno, Seguimos dandole continuacion adonde me he quedado
Vamos a conocer mas objetos 'widgets' de Tk dentro de Perl
Utilizo el ejemplo anteriormente ya dado :
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $ventana = MainWindow->new();
$ventana->minsize(qw(400 400));
$ventana->resizable('FALSE','FALSE');
$ventana->Label(-text => "Hola Mundo")->pack();
my $texto = $ventana->Text(-width => 20, -height => 15, -background => 'white')->pack();
my $entrada = $ventana->Entry(-width => 20, -background => 'white')->pack();
$ventana->Button(-text => "Copiar & Pegar", -command => \&copia)->pack();
$ventana->Button(-text => "Limpiar", -command => \&limpieza)->pack();
MainLoop();
sub copia
{
my $resultado = $entrada->get();
$texto->insert("end", "$resultado");
}
sub limpieza
{
$entrada->delete('0',"end");
$texto->delete('0.0', "end");
}
Aqui agregue otro boton nuevo y otra funcion.
* $ventana->Button(-text => "Limpiar", -command => \&limpieza)->pack();
Este es el boton nuevo, que llama a la funcion limpieza.
*sub limpieza
{
$entrada->delete('0',"end");
$texto->delete('0.0', "end");
}
- Aqui tenemos 2 lineas interesantes, llamamos a las variables ya declaradas $entrada y $texto y le pasamos una funcion de configuracion 'delete' dicha funcion de Tk soporta 2 parametros que son "end" que es hasta donde existan caracteres, y '0' quiere decir 1 linea, mas '0.0' hace referencia a varias. Recordemos que la variable $texto guarda un widget tipo Texto que ocupan varias filas y columnas, mas la variable $entrada solo ocupa 1 linea.
Ahora que ocurre si queremos poner en nuestra ventana principal que los botoncitos aparezcan alineados de forma horizontal o vertical exacta?? Creamos una ventana nueva
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $ventana = MainWindow->new();
$ventana->minsize(qw(250 200));
$ventana->maxsize(qw(250 200));
$ventana->Button(-text => "Pinchame", -width => 10, -relief => 'groove')->grid(-row => 1, -column => 1, -padx => 2);
$ventana->Button(-text => "Clickeame", -width => 10, -relief => 'sunken')->grid(-row => 1, -column => 2, -padx => 2);
$ventana->Button(-text => "Soy un Boton", -width => 10, -relief => 'raised')->grid(-row => 2, -column => 1, -pady => 2);
$ventana->Button(-text => "Pick Me", -width => 10, -relief => 'flat')->grid(-row => 2, -column => 2, -pady => 2);
MainLoop();
* $ventana->maxsize(qw(250 200));
Esta opcion de configuracion a nuestro objeto principal, especifica cual es el tamano maximo de largo y ancho que nuestra ventana soportara.. dependiendo el valor que indiquemos el usuario podra agrandar y disminuir la ventana agarrandola con el raton por los bordes. En caso que a la ventana le digamos que el tamano minimo y maximo son iguales, nadie podra agrandar o disminuir la ventana, (igual manera ocurre si hacemos $ventana->resizable('FALSE','FALSE')) En caso que indiquemos valores distintos podremos disminuir o agrandar la ventana hasta el tamano maximo y minimo indicado.
* $ventana->Button(-text => "Pinchame", -width => 10, -relief => 'groove')->grid(-row => 1, -column => 1, -padx => 2);
Volvemos con los botones, aqui utilizamos mas opciones disponibles al objeto Button aparte de la opcion text, le indico el tamano de largo (width) y el estilo (relief) que tendra el boton. Tk posee varios estilos que podemos aplicar a nuestros objetos 'widgets' entre estos tenemos (groove, flat, sunken, raised). Tambien podemos pasarle colores de fondo y de letra a los botones, basta con utilizar dentro de las opciones.. para colorear el fondo -background => 'color' y para las fuentes -foreground => 'color'.
Por Ejemplo :
$ventana->Button(-text => "Pinchame", -width => 10, -relief => 'groove', -background => 'black', -foreground => 'yellow')
Pero vemos que ya no uso pack() para encapsular los botones dentro del objeto padre ventana sino grid()??? que es grid()???
Tanto pack y grid, son 2 paquetes de geometria especificos de Tk. Ambos tienen opciones que podemos pasarle distintas, los dos encapsulan el objeto 'widget' dentro del objeto padre principal..
Entonces para que necesito grid si pack hace lo mismo o inversa?
Por las opciones que grid ofrece que pack no
grid nos permite alinear exactamente nuestro widget hijo en fila - columna (Con pack no podemos hacer esto
). Fijense que en grid utilizo 2 opciones llamada row y column (que es fila y columna) Asi puedo ir moldeando cada boton en este caso ordenadamente en la columna 1 fila 1, en la columna 1 fila 2, en la columna 2 fila 1, y asi sucesivamente
Ahi otra opcion que le estoy pasando a grid() se llama padx y pady, que hacen estas dos?
padx indica la cantidad de espacio a otorgar al widget para separarlo horizontalmente del otro widget.
pady indica la cantidad de espacio a otorgar al widget para separarlo verticalmente del otro widget.
Para probar pueden quitar a los botones las opciones padx y pady y ejecutar la aplicacion.. que ocurre?? Que salen los 4 botones pegados. Mas si aplican padx con una numeracion de espacio elegida por ustedes, podran ver como los botones se van espaciando horizontalmente.. y si le agregan pady con una enumeracion de espacio elegida por ustedes, podran ver como los botones se van separando entre ellos verticalmente...
padx y pady aplican en pack() tambien
No confundir padx y pady con ipadx y ipady, estos 2 ultimos ejercen la misma funciones que los 2 primeros solo que dentro del widget hijo (Boton en este caso) y no fuera de ellos. O sea dependiendo de la enumeraciones que pasemos a ipadx y ipady se aplicaran pero a modificar el tamano (ancho y largo) del boton en este caso.
my $ventana = MainWindow->new();
$ventana->minsize(qw(250 200));
$ventana->maxsize(qw(250 200));
my $frama = $ventana->Frame->pack();
$frama->Checkbutton(-text => "Pinchame", -borderwidth => 3, -relief => 'groove')->pack(-pady => 10);
$frama->Radiobutton(-text => "Clickeame", -borderwidth => 3, -relief => 'groove')->pack();
$frama->Label(-text => 'Soy una palabra')->pack();
Perl::Tk, Tambien soporta Frames
como muchos saben dentro de los Frames podemos encapsular varios hijitos 'widgets' en este caso encapsulo 2 un Checkbutton y un Radiobutton, estos ultimos 2 igual que los botones normales, acceptan como opcion la llamada a una funcion 'command' por ejemplo :
* $frama->Checkbutton(-text => "Pinchame", -borderwidth => 3, -relief => 'groove', -command => \&copia)->pack(-pady => 10);
Asi cada vez que el usuario clickee se llamara a la funcion copia.
my $ventana = MainWindow->new();
$ventana->minsize(qw(250 200));
$ventana->maxsize(qw(250 200));
$ventana->Scrolled('Text', -background => 'white')->pack(-fill => 'both', -expand => 'true');
* $ventana->Scrolled('Text', -background => 'white')->pack(-fill => 'both', -expand => 'true');
Aqui declaramos un objeto widget del tipo Text - texto. Con la unica variante que le agregamos una barra scroll, las barras scrolls nos sirven por si abrimos un documento un poco extenso poder leerlo hasta el final. Facilidad de las cuales carecemos sino usamos barra scrolls como el primer ejemplo hacia el widget Texto por Ejemplo ::
* $ventana->Text(-width => 20, -height => 10, -background => 'white')->pack();
Tanto al widget Texto con Barra Scroll como sin esta, le podemos indicar el tamano (ancho*alto) deseado o podemos cubrir la ventana completa pasandole ciertas opciones a pack por ejemplo -fill y -expand. Estas 2 particulares opciones hacen lo siguiente, la primera 'fill' indica que ese widget ocupara el mismo tamano total verticalmente que posee la ventana principal, siempre se lo indiquemos asi a fill con la opcion 'both' que quiere decir de lado a lado en el idioma Tk. y la opcion -expand = a verdadero indica que dicho widget hijo no solo ocupara verticalmente el tamano de la ventana sino que tambien ocupara horizontalmente el tamano total de esta...
Aqui posteo un ejemplo de un archivo un poco extenso abierto dentro del widget Texto con Barra Scroll.
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $ventana = MainWindow->new();
$ventana->minsize(qw(250 200));
$ventana->maxsize(qw(250 200));
my $entrada = $ventana->Scrolled('Text', -background => 'white')->pack(-fill => 'both', -expand => 'true');
open(AA,"/etc/profile");
my @todo = <AA>;
$entrada->insert("end", "@todo ");
close (AA);
MainLoop();
(Nota :: Solo funciona en Linux la ubicacion '/etc/profile' Si estas en otra plataforma, indicar otro directorio
y su respetivo archivo de texto
)