Tutorial TKInter Python (GUI) Parte 4

RESUMEN INTERFAZ GRÁFICA
CUARTA PARTE
4 Noviembre del 2010

Autor: Grupo 50, Segundo Semestre 2010 (Sede San Carlos)

14. GUARDANDO Y CARGANDO OBJETOS CON PICKLE

El módulo pickle del que hablábamos en la parte 3 del tutorial, no solo sirve para guardar listas, si no para cualquier
 tipo de dato en general. Hasta objetos.

Ejemplo 24:
A continuación se presenta una forma de cómo guardar objetos en Python:
import pickle

def guardar_lista(lista,ruta):
    fichero = file(ruta, "w")
    nl=lista
    pickle.dump(nl, fichero)

def cargar_lista(ruta):
    fichero = file(ruta)
    lista_recuperada = pickle.load(fichero)
    return lista_recuperada

class persona:
    def __init__(self,nombre):
        self.nombre=nombre
        print "Ha nacido",nombre

Roxana=persona("Roxana")

ListaPersonas=[Roxana]
print "Esta es ListaPersonas:",ListaPersonas

guardar_lista(ListaPersonas,"C:\salvaobjetos.txt")
ListaPersonas2 = cargar_lista("C:\salvaobjetos.txt")
print "Esta es ListaPersonas2",ListaPersonas2

print "Nombre de primer elemento en ListaPersonas:",ListaPersonas[0].nombre
print "Nombre de primer elemento en ListaPersonas2:",ListaPersonas2[0].nombre

En este ejemplo se utilizan las funciones para guardar listas. Se guarda directamente la lista con los objetos del tipo
 persona, clase que ha sido creada para este ejemplo y que únicamente contiene el atributo nombre.
En este ejemplo se realiza lo siguiente:

1. Se crea el objeto persona que contiene un atributo nombre
2. Se crea una variable Roxana de tipo persona, cuyo atributo es 'Roxana'
3. Se crea una lista llamada ListaPersonas, que contiene la variable Roxana
4. Se salva ListaPersonas en el archivo 'C:\salvaobjetos.txt'
5. Se crea una lista llamada ListaPersonas2, que contiene lo mismo que el archivo 'C:\salvaobjetos.txt'
6. Se imprime cuidadosamente cada paso en el código. Por lo que queda comprobado que se guardan también los objetos con el
 módulo pickle

15. COLOCANDO UNA IMÁGEN GIF ESTÁTICA CON UN LABEL

Las imágenes existen varios formatos, es algo muy básico que ya deberíamos saber. Existen formatos como JPG, PNG, BMP, GIF,
 entre otros.

Ejemplo 25:
Una forma de colocar una imágen GIF en una ventana sería la siguiente:

from Tkinter import *

v0=Tk()
imagen1=PhotoImage(file="C:\COUNTER.gif")
label1 = Label(v0, image=imagen1)
label1.grid(row=1,column=1)

v0.mainloop()
Antes de que comiencen a probar todos estos ejemplos, pueden bajarse la foto de Angelina de aquí:
Es una imágen que ya tiene el formato GIF correcto y no presentará problemas a la hora de cargarlo.

http://i.imgur.com/8CbfW.jpg 

Cabe señalar que para cambiarle el formato a una imágen basta con quitarle la extensión que tiene y ponerle otra. Debe ser
 previamente abierta con un programa que permita abrir el formato en el que está la imágen original, y guardarla en formato
 GIF.


16. CREANDO MENÚES EN LA PARTE SUPERIOR DE LA VENTANA

Ejemplo 26:

Vamos a agregarle a la hermosa Angelina Jolie unos cuántos menúes arriba. Supongamos que vamos a dividir cosas en submenúes
 según su color

from Tkinter import *

v0=Tk()
imagen1=PhotoImage(file="C:\COUNTER.gif")
label1 = Label(v0, image=imagen1)
label1.grid(row=1,column=1)

def imprimir(texto): print texto

menu1 = Menu(v0)
v0.config(menu=menu1)
menu1_1 = Menu(menu1, tearoff=0)
menu1.add_cascade(label="AMARILLO", menu=menu1_1)
menu1_1_1 = Menu(menu1_1, tearoff=0)
menu1_1.add_cascade(label="FRUTAS", menu=menu1_1_1)
menu1_1_1.add_command(label="BANANO",command=lambda: imprimir("BANANO"))
menu1_1_1.add_command(label="PIÑA",command=lambda: imprimir("PIÑA"))

menu1_2 = Menu(menu1, tearoff=0)
menu1.add_cascade(label="ROJO", menu=menu1_2)
menu1_2.add_command(label="SANGRE",command=lambda: imprimir("SANGRE"))
menu1_2.add_separator()
menu1_2_1 = Menu(menu1_2, tearoff=0)
menu1_2.add_cascade(label="FRUTAS", menu=menu1_2_1)
menu1_2_1.add_command(label="FRESA",command=lambda: imprimir("FRESA"))
menu1_2_1.add_command(label="MANZANA",command=lambda: imprimir("MANZANA"))
v0.mainloop()

http://i.imgur.com/g5RLz.jpg 

Cada menú que contiene elementos se crea, y es a ese menú al que se introduce en un menú padre. Se le pueden agregar
 separadores, comandos clickeables, cascadas, entre otras cosas.

Además el menú padre hay que asociarlo a la ventana directamente con ventanaprincipal.config(menu=menupadre), tal como se
 muestra arriba

17. CREANDO NUESTRA SPLASH SCREEN

Una Splash Screen es una ventana que nos aparece cuando abrimos un programa. Por ejemplo lo siguiente es una splash screen:

http://i.imgur.com/XebQg.jpg 

Ejemplo 27:

Para crear nuestro Splash Screen, lo que debemos hacer es crear una pausa entre el Splash Screen, y la ventana principal,
 la cual debe estar oculta. Eso lo podemos realizar de la siguiente manera:

from Tkinter import *

v0=Tk()
imagen1=PhotoImage(file="C:\COUNTER.gif")
label1 = Label(v0, image=imagen1)
label1.grid(row=1,column=1)

def imprimir(texto): print texto
def mostrar(ventana): return ventana.deiconify # Muestra una ventana
def ocultar(ventana): return ventana.withdraw() # Oculta una ventana
def ejecutar(f): v0.after(100, f)

menu1 = Menu(v0)
v0.config(menu=menu1)
menu1_1 = Menu(menu1, tearoff=0)
menu1.add_cascade(label="AMARILLO", menu=menu1_1)
menu1_1_1 = Menu(menu1_1, tearoff=0)
menu1_1.add_cascade(label="FRUTAS", menu=menu1_1_1)
menu1_1_1.add_command(label="BANANO",command=lambda: imprimir("BANANO"))
menu1_1_1.add_command(label="PIÑA",command=lambda: imprimir("PIÑA"))

menu1_2 = Menu(menu1, tearoff=0)
menu1.add_cascade(label="ROJO", menu=menu1_2)
menu1_2.add_command(label="SANGRE",command=lambda: imprimir("SANGRE"))
menu1_2.add_separator()
menu1_2_1 = Menu(menu1_2, tearoff=0)
menu1_2.add_cascade(label="FRUTAS", menu=menu1_2_1)
menu1_2_1.add_command(label="FRESA",command=lambda: imprimir("FRESA"))
menu1_2_1.add_command(label="MANZANA",command=lambda: imprimir("MANZANA"))

v1=Toplevel(v0)
v1.geometry("400x200")
v1.config(bg="black")
v1.protocol("WM_DELETE_WINDOW", "onexit")
v1.resizable(0,0)

ocultar(v0)
def cerrar_splashscreen():
    ejecutar(ocultar(v1))
    ejecutar(mostrar(v0))
v1.after(4000,cerrar_splashscreen)
Label(v1,text="BIENVENIDO A NUESTRA APLICACIÓN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA APLICACIÓN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA APLICACIÓN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA APLICACIÓN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA APLICACIÓN",bg="black",fg="white",font=(15)).pack()

v0.mainloop()

Utiliza el método after para provocar un efecto de espera, y luego oculta una ventana y muestra la otra.

18. ACOMODANDO LOS ELEMENTOS: TOP, BOTTOM, LEFT, RIGHT

Una de las cosas que uno puede tardar más haciendo con Python, es acomodando los elementos. Si estuviésemos programando en
 Java con Netbeans, sería más cómodo pues disponemos de un panel como el siguiente:

http://i.imgur.com/8o3Ra.jpg 

Por lo que para nosotros que debemos hacerlo a pura línea de código, puede ser un poco más complicado. Sin embargo, como es
 para propósito meramente de aprendizaje, es indispensable haber hecho aunque sea una vez en toda tu carrera (Que habrá
 más)  el trabajo de Interfaz Gráfica solo utilizando código, sin herramientas externas.

Para acomodar los elementos en Python, al igual que en Scheme, y me imagino que en la mayoría de lenguajes de programación
 que posean un módulo de Interfaz Gráfica     que se haga llamar standard, se utilizan paneles, y dos propiedades de los
 objetos gráficos, llamados .pack() y .grid()

Ejemplo 28:

Las ventanas tienen arriba, abajo, izquierda y derecha. En inglés se llaman TOP, BOTTOM, LEFT, RIGHT. Podemos hacer uso de
 esto para acomodar los elmentos a un lado o al otro de la ventana, de la siguiente forma:
from Tkinter import *

v0=Tk()
v0.geometry("200x200")

b1=Button(v0,text="ARRIBA").pack(side=TOP)
b3=Button(v0,text="ABAJO").pack(side=BOTTOM)
b2=Button(v0,text="IZQUIERDO").pack(side=LEFT)
b4=Button(v0,text="DERECHO").pack(side=RIGHT)

v0.mainloop()
http://i.imgur.com/To1rj.jpg 

Ejemplo 29:

Y el orden de colocación en el código sí importa. Nóte que primero está TOP, luego BOTTOM, luego LEFT, y luego RIGHT. Pero
 si por ejemplo colocamos este orden

from Tkinter import *

v0=Tk()
v0.geometry("200x200")

b1=Button(v0,text="ARRIBA").pack(side=TOP)
b2=Button(v0,text="IZQUIERDO").pack(side=LEFT)
b3=Button(v0,text="ABAJO").pack(side=BOTTOM)
b4=Button(v0,text="DERECHO").pack(side=RIGHT)

v0.mainloop()

Tendremos que los botones no se alinean de manera correcta.

http://i.imgur.com/cITGJ.jpg 

Ejemplo 30:

Es importante recordar que también podemos colocar el código de la siguiente forma:

from Tkinter import *

v0=Tk()
v0.geometry("200x200")

b1=Button(v0,text="ARRIBA")
b1.pack(side=TOP)
b3=Button(v0,text="ABAJO")
b3.pack(side=BOTTOM)
b2=Button(v0,text="IZQUIERDO")
b2.pack(side=LEFT)
b4=Button(v0,text="DERECHO")
b4.pack(side=RIGHT)

v0.mainloop()



19. ACOMODANDO LOS ELEMENTOS: FRAMES

Una de las cosas a las que lleva tiempo acostumbrarse es a los Frames. Si no se tiene cuidado o se usan con exceso, un
 proyecto puede contener más frames que cualquier otro tipo de elemento gráfico.

Ejemplo 31:
Un frame es un panel que sirve como padre para otros elementos en una ventana. Casi siempre que uno va a trabajar con
 frames en un proyecto, es recomendable primero realizar un dibujo en papel o con algún editor gráfico, y pensar en cómo
 quedará al final. Acá tenemos un ejemplo de cómo se pueden acomodar los elementos con Frame

http://i.imgur.com/z0Msm.jpg 

from Tkinter import *

v0=Tk()
v0.geometry("200x200")

l1=Label(v0,text="BIENVENIDO AL PROYECTO")
l1.pack()

frame0=Frame(v0)
frame0.pack(side=TOP)

frame1=Frame(frame0)
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
frame1.pack(side=LEFT)

frame2=Frame(frame0)
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
frame2.pack(side=RIGHT)

v0.mainloop()
http://i.imgur.com/p2VKE.jpg 

Ejemplo 32

También tenemos propiedades para algunos objetos gráficos, que sirven para acomodamiento en las ventanas. Se llaman expand
 y fill. Veamos un ejemplo de cómo funciona fill
from Tkinter import *

v0=Tk()
v0.geometry("200x200")

l1=Label(v0,text="BIENVENIDO AL PROYECTO")
l1.pack()

frame0=Frame(v0)
frame0.pack(side=TOP,fill=BOTH)

frame1=Frame(frame0)
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
Label(frame1,text="T e x t o").pack()
frame1.pack(side=LEFT)

frame2=Frame(frame0)
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
Label(frame2,text="o t x e T").pack()
frame2.pack(side=RIGHT)

v0.mainloop()

http://i.imgur.com/vCDKK.jpg 

En la documentación viene más información sobre expand y fill. Son conceptos sobre el ordenamiento de los objetos a los que
 hemos de acostumbrarnos para que al final le demos un acabado a la interfaz que se adapte a nuestras necesidades. Aquí hay
 unas ventanas acomodadas utilizando el método de Frames

http://i.imgur.com/5Ie6S.jpg http://i.imgur.com/3CvJg.jpg 

20. ACOMODANDO LOS ELEMENTOS: GRID

Otra forma de acomodar los elementos en una ventana es con el método grid. Anteriormente vimos que el método .pack tenía
 atributos como side, fill y expand.
El método grid tiene como atributos row y column. En una matriz, row (en español fila) son las líneas horizontales
 (conocidas también como vectores), y column (columnas..), son las líneas verticales.
















Esta es la forma de comprender el método grid, utiliza la ventana como si fuera una matriz, y ordena los elementos como
 entradas de esa matriz. Veamos el ejemplo con botones:

from Tkinter import *

v0=Tk()
v0.geometry("200x200")

Button(v0,text="A").grid(row=1,column=1)
Button(v0,text="B").grid(row=1,column=2)
Button(v0,text="C").grid(row=1,column=3)
Button(v0,text="D").grid(row=1,column=4)
Button(v0,text="E").grid(row=2,column=1)
Button(v0,text="F").grid(row=2,column=2)
Button(v0,text="G").grid(row=2,column=3)
Button(v0,text="H").grid(row=2,column=4)
Button(v0,text="I").grid(row=3,column=1)
Button(v0,text="J").grid(row=3,column=2)
Button(v0,text="K").grid(row=3,column=3)
Button(v0,text="L").grid(row=3,column=4)
Button(v0,text="M").grid(row=4,column=1)
Button(v0,text="N").grid(row=4,column=2)
Button(v0,text="Ñ").grid(row=4,column=3)
Button(v0,text="O").grid(row=4,column=4)

v0.mainloop()

Y el ejemplo de más arriba pero con grid, sería de la siguiente forma:

from Tkinter import *

v0=Tk()
v0.geometry("242x100")

Label(v0,text="").grid(row=1,column=1)
Label(v0,text="BIENVENIDO AL PROYECTO").grid(row=1,column=2)
Label(v0,text="").grid(row=1,column=3)
Label(v0,text="T E X T O").grid(row=2,column=1)
Label(v0,text="T E X T O").grid(row=2,column=3)
Label(v0,text="T E X T O").grid(row=3,column=1)
Label(v0,text="T E X T O").grid(row=3,column=3)
Label(v0,text="T E X T O").grid(row=4,column=1)
Label(v0,text="T E X T O").grid(row=4,column=3)
Label(v0,text="T E X T O").grid(row=5,column=1)
Label(v0,text="T E X T O").grid(row=5,column=3)
Label(v0,text="T E X T O").grid(row=6,column=1)
Label(v0,text="T E X T O").grid(row=6,column=3)

v0.mainloop()

http://i.imgur.com/dSyRv.jpg 

Dos observaciones importantes. La primera, no mezcles ObjetoBoton.pack() y ObjetoBoton.grid() en una misma ventana. Y la
 segunda, Es que podrías introducir los elementos en frames, y luego utilizar el grid para acomodar los Frames. Se debe
 planear la manera en cómo irán acomodados los elementos.

Además una de las cosas que debemos tomar en cuenta cuando programamos una interfaz, es que si va a cambiar el tamaño de la
 ventana, debemos configurarla adecuadamente para que se mantenga la proporción del aspecto. Por que si maximiza la
 ventana, los elementos se van a ver mal. Una solución para esto es prohibir que se pueda cambiar el tamaño de la ventana,
 o buscar maneras para que los elementos 'se mantengan en su sitio' aún cuando la ventana cambie de tamaño

Finalmente, el grid puede ser a veces engorroso y dar resultados no deseados, si no sabemos bien como configurar bien su
 aspecto. Por eso lo mejor es mezclarlo con Frames y darle el acabado deseado.

Para una mejor documentación de grid y demás elementos de la interfaz Tkinter en general, diríjase al siguiente link:
http://effbot.org/tkinterbook/grid.htm

No hay comentarios:

Publicar un comentario

gmendezm
Portada
Lista Principal