Sie sind auf Seite 1von 64

Tutorial TKInter Python (GUI)

RESUMEN INTERFAZ GRFICA


PRIMERA PARTE
3 Noviembre del 2010

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

1. Introduccin:
Este tutorial no est hecho para seguirlo al pie de la letra solo son
algunas cosas bsicas que debemos entender para poder
trabajar con ventanas y para dar un pequeo salto desde la cnsola a la
interfaz. Recordemos que somos la primera
generacin en el TEC que recibe Python, por lo que el tutorial es
meramente experimental, y puede contener cosas que no
son del todo correctas. Se tratar de mostrar cmo se trabaja desde
ciertos puntos de vista, y el usuario se encargar de
desarrollar su propia forma de construir la interfaz.

2. El Mdulo que usaremos


Un mdulo se puede importar en Python. Existen diferentes formas de crear
mdulos, y de importarlos. Un mdulo puede ser un
archivo .py, o todo un conjunto de archivos que interactan con el
sistema operativo y la mquina en general.
Por ejemplo el mdulo time obtiene datos sobre la fecha, el mdulo os
obtiene datos sobre el sistema operativo.
Python ya viene con varios mdulos integrados, sin embargo nosotros
podemos buscar en internet y descargar otros ms.
Para construir interfaz grfica en Python se pueden utilizar varios
mdulos. Se pueden descargar mdulos para crear la
interfaz de la forma que ms nos guste.
Para este manual, usaremos el mdulo Tkinter, porque ya viene instalado
en Python y es con el que hemos trabajado, y
bastar para darse una idea de cmo se trabaja en Python con interfaz
grfica.
En algunas versiones de Linux no viene instalado el mdulo Tkinter,
entonces debemos escribir en la cnsola:
sudo apt-get install python-tk
Mientras que la versin que uno se descarga para Windows ya lo trae.

3. El IDE (El software que usaremos para


programar)
Bien, ahora necesitamos un IDE, que es donde programaremos. Yo
personalmente he utilizado Eclipse, Netbeans, el que trae
Python por defecto, uno que se llama Pycharm que es de pago (Lo cual en
cierto modo representa un problema) y al final he
dado con uno que en lo personal me agrada y se llama Pyscripter. La
verdad me parece la alternativa ms indicada para
programar en Python (Tomando en cuenta que no realizaremos un super
programa empresarial, si no simples prcticas)
En google pueden buscar y encontrarn versiones para varios sistemas
operativos.
Si no, pueden utilizar cualquiera que gusten.

4. Importando el mdulo
Para importar un mdulo en Python escribimos
import nombredelmodulo
Otra forma de hacerlo es
from nombredelmodulo import *
Esto no les va a devolver nada porque el modulo nombredelmodulo no
existe. Pero bsicamente estas son las formas que se
usan ms.

5. Ventanas
Las ventanas se pueden configurar de diferentes formas. Veamos un ejemplo
de una ventana.
Ejemplo 1:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.
Esto nos lanza una ventana normal.

Ejemplo 2:
Ahora para colocarle fondo a la ventana sera:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v0.config(bg="black") # Le da color al fondo
v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.

Ejemplo 3:
Una forma de controlar el tamao de la ventana sera el siguiente:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana


v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.
Ejemplo 4:
Bueno como habrn visto, declaramos una variable llamada v0, del tipo
Tk().
Adems de Tk(), podemos declarar ms variables
Toplevel: Crea una nueva ventana
Frame: Coloca los pneles para ordenar los elementos
Canvas: Para dibujar y graficar funciones etc..
Button: Para colocar un botn
Label: Coloca un texto
Message: Coloca un texto
Entry: Coloca una entrada de texto de una linea
Text: Coloca una entrada de texto de varias lineas
Listbox: Coloca una lista con elementos clickeables
Men: Coloca un men que puede contener cascadas y elementos clickeables
Existe toda una mecnica para agregar elementos a una ventana. Adems de
todo esto se pueden colocar imgenes y otras
cosas. Por el momento estos controles bsicos son los que aprenderemos a
utilizar:
Ejemplo 5:
Vamos a crear una ventana de tipo Toplevel. En Python ocurre algo
curioso, todas las ventanas creadas se abren al mismo
tiempo. Por eso cuando creamos una ventana del tipo Toplevel, debemos
ocultarla. Veamos un ejemplo:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
v1=Toplevel(v0) # Crea una ventana hija
v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.

Se abre al mismo tiempo las dos ventanas. Esto se evita de la siguiente


forma:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
v1=Toplevel(v0) # Crea una ventana hija
v1.withdraw() # oculta v1
v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.
Ah ya ocult la ventana. Pero cmo mostrarla otra vez?
Ejemplo 6:
Para importar un botn se hace de la siguiente forma:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
b1=Button(v0,text="ABRIR VENTANA V1") # Primer botn
b1.pack() # El botn es cargado
v1=Toplevel(v0) # Crea una ventana hija

v1.withdraw() # Oculta la ventana v1


v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.
Ese botn no tiene ningn evento, adems fue cargado con el mtodo .pack.
Lo podemos cargar con el mtodo .grid
Son dos formas distintas de cargar un botn. En vez de la primera forma:
b1=Button(v0,text="ABRIR VENTANA V1") # Primer botn
b1.pack() # El botn es cargado
Pudimos haberlo escrito de esta otra forma:
b1=Button(v0,text="ABRIR VENTANA V1").pack()
En una sola lnea. O de esta otra forma:
b1=Button(v0,text="ABRIR VENTANA V1") # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
Y esta otra forma:
b1=Button(v0,text="ABRIR VENTANA V1").grid(row=1,column=1) # El botn es
cargado
Hay diversas formas de cargar los botones y que se ajustan a nuestro
gusto y forma de hacer las cosas.
Ahora vamos a mostrar la otra ventana.
Primero creamos una funcin llamada mostrar
def mostrar(ventana):
ventana.deiconify()
El mtodo deiconify muestra la ventana que haba sido oculta por
withdraw(). Adems una funcin para ocultar podra ser
def ocultar(ventana):
ventana.withdraw()
Con solo estas dos funciones ya podemos mostrar y ocultar la ventana 1.
vamos a agregar otro botn ms y todo junto queda
de la siguiente forma:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v1=Toplevel(v0) # Crea una ventana hija
def mostrar(ventana): ventana.deiconify()
def ocultar(ventana):ventana.withdraw()
def ejecutar(f): v0.after(200,f)
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana

b1=Button(v0,text="ABRIR VENTANA V1",command=lambda:


ejecutar(mostrar(v1))) # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:
ejecutar(ocultar(v1))) # Segundo botn
b2.grid(row=1,column=2) # El botn es cargado
v1.withdraw() # Oculta la ventana v1
v0.mainloop() # Es el evento que llama al inicio de nuestro programa.
Siempre lo lleva la ventana principal.

El prximo archivo comentaremos algunos aspectos a tomar en cuenta a la


hora de mostrar y ocultar ventanas

RESUMEN INTERFAZ GRFICA


SEGUNDA PARTE
3 Noviembre del 2010

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

6. Irregularidades
Una de las cosas que dificulta a una persona nueva que quiere
aprender interfaz en Python, es el conjunto de dificultades
que aparecen conforme vas aprendiendo, sobre todo si no dominas
bien ms de un lenguaje o solo haz programado en Scheme
una interfaz grfica y piensas que todas se programan igual.
Pues presenta una dificultad.
En el ltimo cdigo que vimos:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v1=Toplevel(v0) # Crea una ventana hija
def mostrar(ventana): ventana.deiconify() # Muestra una ventana
def ocultar(ventana):ventana.withdraw() # Oculta una ventana

def ejecutar(f): v0.after(200,f) # Una forma alternativa de


ejecutar una funcin
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
b1=Button(v0,text="ABRIR VENTANA V1",command=lambda:
ejecutar(mostrar(v1))) # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:
ejecutar(ocultar(v1))) # Segundo botn
b2.grid(row=1,column=2) # El botn es cargado
v1.withdraw() # Oculta la ventana v1
v0.mainloop() # Es el evento que llama al inicio de nuestro
programa. Siempre lo lleva la ventana principal.
Vemos que apareci:
Una nueva funcin llamada ejecutar
v0.after? Qu es eso?!
Porqu el command de los botones tiene lambda dos puntos
ejecutar y la funcin dentro de mostrar?
Esto fue as, porque hice varias pruebas y esta fu la mejor
forma que encontr para que todo funcionara bien (Se teste la
interfaz en Windows XP).
Otra cosa que not es que la interfaz de vez en cuando no acta
de la misma forma en Windows que en las distros de Linux
(Por ejemplo Ubuntu o Kubuntu).
Ya por ejemplo si yo quiero centrar una ventana de Python en
windows, utilizo esta funcin:
def centrar(ventana):
ventana.update_idletasks()
w=ventana.winfo_width()
h=ventana.winfo_height()
extraW=ventana.winfo_screenwidth()-w
extraH=ventana.winfo_screenheight()-h
ventana.geometry("%dx%d%+d%+d" % (w,h,extraW/2,extraH/2))
Si escribimos el nombre de la ventana, entonces la centrar,
pero en Windows, porque en Ubuntu desconfigura todo el tamao
de la ventana.
En cunto a las preguntas de ms arriba. La funcin llamada
ejecutar, y lo de v0.after, es acerca de lo mismo. Qu es lo
que hace la ventana ejecutar?

Lo que hace es que pasados dos milisegundos en un momento dado


del tiempo, ejecuta f. f es el nombre de una funcin que
queremos ejecutar.
Por ejemplo abre una ventana, como se vi anteriormente.
Y para qu es el lambda? No estoy muy seguro pero es
absolutamente necesario usarlo, adems lambda permite que un
botn
ejecute dos eventos al mismo tiempo.
Ejemplo 7:
Por ejemplo si queremos mostrar una ventana y tambin imprimir
hola, sera de la siguiente forma:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v1=Toplevel(v0) # Crea una ventana hija
def mostrar(ventana): ventana.deiconify() # Muestra una ventana
def ocultar(ventana):ventana.withdraw() # Oculta una ventana
def ejecutar(f): v0.after(200,f) # Una forma de ejecutar las
funciones
def imprimir(texto): print texto # Imprime un texto
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
b1=Button(v0,text="ABRIR VENTANA V1",command=lambda:
ejecutar(mostrar(v1)) or imprimir("hola")) # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:
ejecutar(ocultar(v1))) # Segundo botn
b2.grid(row=1,column=2) # El botn es cargado
v1.withdraw() # Oculta la ventana v1
v0.mainloop() # Es el evento que llama al inicio de nuestro
programa. Siempre lo lleva la ventana principal.
Ejemplo 8:
Si dan click al botn ABRIR VENTANA V1, notarn que adems de
mostrar la ventana, imprime el texto. Si quisieramos que el
botn hiciera tres cosas, sera de la siguiente forma:
from Tkinter import * # Importa el mdulo

v0 = Tk() # Tk() Es la ventana principal


v1=Toplevel(v0) # Crea una ventana hija
def mostrar(ventana): ventana.deiconify() # Muestra una ventana
def ocultar(ventana):ventana.withdraw() # Oculta una ventana
def ejecutar(f): v0.after(200,f) # Una forma de ejecutar las
funciones
def imprimir(texto): print texto # Imprime un texto
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
b1=Button(v0,text="ABRIR VENTANA V1",command=lambda:
ejecutar(mostrar(v1)) or imprimir("hola") or imprimir("tercera
funcin")) # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:
ejecutar(ocultar(v1))) # Segundo botn
b2.grid(row=1,column=2) # El botn es cargado
v1.withdraw() # Oculta la ventana v1
v0.mainloop() # Es el evento que llama al inicio de nuestro
programa. Siempre lo lleva la ventana principal.
Con el lambda y los dos puntos, mezclado con la funcin
ejecutar, podemos ejecutar varios eventos al mismo tiempo
separados
por or.
Ejemplo 9:
Ahora, no s si lo habrn notado, pero cuando cerramos la
ventana, tira error, pero cuando la ocultamos no nos da error.
Yo
la solucin que le encontr a esto, fue quitando la opcin de
cerrar ventana, y colocando un botn salir en cada ventana.
Para realizar eso se hace lo siguiente:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v1=Toplevel(v0) # Crea una ventana hija
v1.protocol("WM_DELETE_WINDOW", "onexit") # Elimina la opcin de
salir para evitar el error
def mostrar(ventana): ventana.deiconify() # Muestra una ventana
def ocultar(ventana):ventana.withdraw() # Oculta una ventana
def ejecutar(f): v0.after(200,f) # Una forma de ejecutar las
funciones

def imprimir(texto): print texto # Imprime un texto


v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana
b1=Button(v0,text="ABRIR VENTANA V1",command=lambda:
ejecutar(mostrar(v1)) or imprimir("hola") or imprimir("tercera
funcin")) # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
b2=Button(v1,text="OCULTAR VENTANA V1",command=lambda:
ejecutar(ocultar(v1))) # Segundo botn
b2.grid(row=1,column=2) # El botn es cargado
b3=Button(v0,text="SALIR",command=lambda: ejecutar(ocultar(v1)))
b3.grid(row=1,column=2) # El botn es cargado
v1.withdraw() # Oculta la ventana v1
v0.mainloop() # Es el evento que llama al inicio de nuestro
programa. Siempre lo lleva la ventana principal.
Ejemplo 10:
Otro truco interesante es evitar que una ventana pueda
redimencionarse (Cambiar el tamao de una ventana). Con lo
siguiente
se puede realizar:
from Tkinter import * # Importa el mdulo
v0 = Tk() # Tk() Es la ventana principal
v1=Toplevel(v0) # Crea una ventana hija
v1.protocol("WM_DELETE_WINDOW", "onexit") # Elimina la opcin de
salir para evitar el error
v0.resizable(0,0) # Evita que la ventana se pueda cambiar de
tamao
v1.resizable(0,0) # Evita que se le pueda cambiar de tamao a la
ventana
def mostrar(ventana): ventana.deiconify() # Muestra una ventana
def ocultar(ventana):ventana.withdraw() # Oculta una ventana
def ejecutar(f): v0.after(200,f) # Una forma de ejecutar las
funciones
def imprimir(texto): print texto # Imprime un texto
v0.config(bg="black") # Le da color al fondo
v0.geometry("500x500") # Cambia el tamao de la ventana

b1=Button(v0,text="ABRIR VENTANA V1",command=lambda:


ejecutar(mostrar(v1)) or imprimir("hola") or imprimir("tercera
funcin")) # Primer botn
b1.grid(row=1,column=1) # El botn es cargado
b2=Button(v1,text="OCULTARME",command=lambda:
ejecutar(ocultar(v1))) # Segundo botn
b2.grid(row=1,column=2) # El botn es cargado
b3=Button(v0,text="OCULTAR VENTANA V1",command=lambda:
ejecutar(ocultar(v1)))
b3.grid(row=1,column=2) # El botn es cargado
v1.withdraw() # Oculta la ventana v1
v0.mainloop() # Es el evento que llama al inicio de nuestro
programa. Siempre lo lleva la ventana principal.

Con una lectura de los manuales de Tkinter se deberan poder


solucionar algunas de estas irregularidades, entre otras ms
que se podran comentar ms adelante.

7. ELEMENTOS PADRES Y ELEMENTOS HIJOS


Tomando en cuenta todos los primeros 6 puntos, ahora vamos a
analizar la interfaz por el lado de lo que son los elementos
hijos de otros, cul es el padre de un elemento, etctera.
Generalmente cuando trabajamos con Tkinter, el elemento padre
es el primer argumento que recibe un objeto grfico. El
elemento Tk() no tiene ningn padre. Si declaramos una variable
v0 = Tk()
Entonces v0 es un Tk(), que es la ventana principal, y entre
parntesis no recibe ningn argumento. Pero si queremos
introducir un elemento dentro de v0, dicho elemento debe saber
que su padre es v0.
En el siguiente ejemplo se crean dos ventanas, la ventana
principal del tipo Tk() y una ventana hija del tipo Toplevel().
La ventana Toplevel() es hija de la ventana Tk()
Luego creamos un botn en cada ventana. Lo que querra decir que
uno de los botones tiene como padre a la ventana Tk() y el
otro botn tiene como padre a la ventana del tipo Toplevel()
Ejemplo 11:
A continuacin se presenta el ejemplo
from Tkinter import *
v0=Tk()
v1=Toplevel(v0)
def mostrar(ventana): ventana.deiconify()
def ocultar(ventana):ventana.withdraw()
def ejecutar(f): v0.after(200,f)
b1=Button(v0,text="TERMINAR
APLICACIN",command=v0.destroy).pack()
b2=Button(v1,text="OCULTAR VENTANA",command=lambda:
ejecutar(ocultar(v1))).pack()
v0.mainloop()

En este ejemplo se puede ver que para salir de la aplicacin


basta con destruir el objeto de la ventana principal, llamado
v0. As, cuando escribimos v0.destroy se destruye la ventana
padre, y entonces la aplicacin termina.
Otras formas que podran presentar conflictos, pero que tambin
son usadas, son v0.quit, y por supuesto, ocultar(v0) que
sera lo mismo que decir v0.withdraw(). Sin embargo con el
withdraw() solo la oculta no cerrara la aplicacin.
Tambin se puede usar en el command del botn lambda: exit()
Ahora introduzcamos ms controles, como por ejemplo los Labels

8. QUE EL PROGRAMA TAMBIN SEA UN OBJETO


Ejemplo 12:
Creamos un programa que funcione con el paradigma de objetos y
se puede implementar de la siguiente forma
from Tkinter import *
class programa:
def __init__(self):
self.v0 = Tk()
def run(self):
self.v0.mainloop()
test1=programa()
test1.run()
Se implementa todo lo visto anteriormente pero a manera de
objetos.

9. PROPIEDADES DE LOS CONTROLES (Parte 1)


Ya habamos hablado de las ventanas Tk y Toplevel y de los
controles Label, Button, Listbox, Scrollbar Entry, Text, Frame,

Canvas, entre otros.


Pero, cmo se usan? Cmo se introduce un elemento en un Listbox?
Cmo se le cambia el color de fondo y de letra a las
cosas?
Label
Para el label se puede declarar una variable de tipo StringVar()
Ejemplo 13:
En este ejemplo, nos abre con raw_input un espacio para que
escribamos algo. Luego simplemente imprimimos eso en un control
de tipo Label, todo lo que tenemos que hacer es setear la
variable de tipo StringVar(). De la siguiente manera:
from Tkinter import *
v0=Tk()
mitexto=StringVar()
label1=Label(v0,textvar=mitexto).pack()
escribir=raw_input("")
mitexto.set(escribir)
v0.mainloop()

Como se puede ver en el ejemplo anterior, para darle valor a una


variable del tipo StringVar() se escriba
variable.set(texto).
Ejemplo 14:
En el siguiente ejemplo veremos como se puede obtener valor de
una variable de tipo StringVar(), utilizando variable.get()
from Tkinter import *
v0=Tk()
v0.geometry("200x60")

def cambiar_stringvar(nuevotexto,stringvar):
stringvar.set(nuevotexto)
mitexto=StringVar()
textoentry=StringVar()
entry1=Entry(v0,textvar=textoentry).pack()
label1=Label(v0,textvar=mitexto).pack()
b1=Button(v0,text="Escribir",command=lambda:
cambiar_stringvar(textoentry.get(),mitexto)).pack()
v0.mainloop()

Ejemplo 15:
Ahora veamos el objeto Listbox. Supongamos que queremos
introducir una palabra en un control de tipo Listbox. Una forma
de
implementarlo seria:
from Tkinter import *
v0=Tk()
list1=Listbox(v0)
list1.pack()
mivalor=StringVar()
e1=Entry(v0,textvar=mivalor).pack()
def insertar_en_listbox():
if mivalor.get() != "":
list1.insert(END,mivalor.get())
else: print "Por favor esciba algn texto"
b1=Button(v0,text="Insertar en
Listbox",command=insertar_en_listbox).pack()
v0.mainloop()

Si insertan muchos elementos se darn cuenta de que, en este


tipo de controles normalmente aparece una Scrollbar
automticamente. El Scrollbar es otro tipo de control, y en
Python, curiosamente, para que un Listbox tenga Scrollbar,
deben unirse mediante un truco, por decirlo de alguna forma.
Ejemplo 16:
Para que el Listbox del ejemplo de arriba tenga un scrollbar, se
debe hacer lo siguiente:
from Tkinter import *
v0=Tk()
def colocar_scrollbar(listbox,scrollbar):
scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(side=LEFT, fill=Y)
frame1=Frame(v0)
frame1.pack()
scroll1=Scrollbar(frame1)
list1=Listbox(frame1)
list1.pack()
colocar_scrollbar(list1,scroll1)
mivalor=StringVar()
e1=Entry(v0,textvar=mivalor).pack()
def insertar_en_listbox():
if mivalor.get() != "":
list1.insert(END,mivalor.get())
else: print "Por favor esciba algn texto"

b1=Button(v0,text="Insertar en
Listbox",command=insertar_en_listbox).pack()
v0.mainloop()

De esta forma al tener ms elementos de los que permite


visualizar, coloca automticamente un Scrollbar.
Cabe destacar que en Scheme, el control Listbox traa su propio
Scrollbar. Al menos eso recuerdo...

RESUMEN INTERFAZ GRFICA


TERCERA PARTE
3 Noviembre del 2010
Autor: Grupo 50, Segundo Semestre 2010 (Sede San Carlos)

10. PROPIEDADES DE LOS CONTROLES (Parte 2)


Ejemplo 17:
Ahora, suponiendo que tenemos una lista de cosas, y queremos que
esa lista de cosas se inserten, una a una, en un listbox.
Para cosas como estas debemos implementar funciones , ya que de
otra manera estaramos repitiendo mucho cdigo y
saturando nuestro proyecto, mientras que una funcin resume
muchas instrucciones y lo hace ms comprensible.
Esta es una solucin para realizarlo:
from Tkinter import *

v0=Tk()
def colocar_scrollbar(listbox,scrollbar):
scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(side=LEFT, fill=Y)
frame1=Frame(v0)
frame1.pack()
scroll1=Scrollbar(frame1)
list1=Listbox(frame1)
list1.pack()
colocar_scrollbar(list1,scroll1)
def cargarlistbox(lista,listbox):
ind,largo=0,len(lista)
while ind < largo:
listbox.insert(END,lista[ind])
ind+=1
ListaNombres=['Laura','Roger','Fabiola']
cargarlistbox(ListaNombres,list1)
v0.mainloop()

Ejemplo 18:
Este es un ejemplo de cmo imprimir el texto del elemento
seleccionado en un Listbox, en un control del tipo Label. Esta
es
una de las formas con las que se puede implementar esto:
from Tkinter import *
v0=Tk()
def colocar_scrollbar(listbox,scrollbar):

scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(side=LEFT, fill=Y)
frame1=Frame(v0)
frame1.pack()
scroll1=Scrollbar(frame1)
list1=Listbox(frame1)
list1.pack()
colocar_scrollbar(list1,scroll1)
mitexto=StringVar()
label1=Label(v0,textvar=mitexto)
label1.pack()
def cargarlistbox(lista,listbox):
ind,largo=0,len(lista)
while ind < largo:
listbox.insert(END,lista[ind])
ind+=1
ListaNombres=['Laura','Roger','Fabiola']
def imprimir_en_label():
label1.after(100, imprimir_en_label) # Llamada recursiva con
.after
ind = list1.curselection()
if list1.curselection() != ():
sel = list1.get(ind)
mitexto.set(sel)
cargarlistbox(ListaNombres,list1)
imprimir_en_label()
v0.mainloop()

Producido
La funcin imprimir_en_label es la que llama la atencin en este
caso, es una funcin que se llama as misma con el evento
objeto.after(tiempo(milisegundos),funcin).
Cada 100 milisegundos verifica cul elemento est seleccionado.
Listbox.curselection() retorna la posicin seleccionada, y
Listbox.get(posicin) devuelve el texto seleccionado. Otra forma
de realizar esto es con una implementacin de objeto.bind
Ejemplo 18:
Para este ejemplo lo que haremos es una funcin para limpiar un
control del tipo Listbox. La funcin elimina todos los
elementos del listbox cuando uno le da click al botn ELIMINAR
TODOS
from Tkinter import *
v0=Tk()
def colocar_scrollbar(listbox,scrollbar):
scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(side=LEFT, fill=Y)
frame1=Frame(v0)
frame1.pack()
scroll1=Scrollbar(frame1)
list1=Listbox(frame1)
list1.pack()
colocar_scrollbar(list1,scroll1)
mitexto=StringVar()
label1=Label(v0,textvar=mitexto)
label1.pack()
b1=Button(v0,text="ELIMINAR TODOS",command=lambda:
limpiar_listbox(list1))
b1.pack()
def cargarlistbox(lista,listbox):
ind,largo=0,len(lista)
while ind < largo:
listbox.insert(END,lista[ind])
ind+=1
ListaNombres=['Laura','Roger','Fabiola','Yendry','Esteban','Mart
a','Elias']

def imprimir_en_label():
label1.after(100, imprimir_en_label) # Llamada recursiva con
.after
ind = list1.curselection()
if list1.curselection() != ():
sel = list1.get(ind)
mitexto.set(sel)
def limpiar_listbox(listbox):
while listbox.size() > 0:
listbox.delete(0)
cargarlistbox(ListaNombres,list1)
imprimir_en_label()
v0.mainloop()

Ejemplo 19:
Para personalizar los colores de los objetos se utilizan:
bg: Se encarga del color de fondo
fg: Se encarga del color del texto
Hay otras propiedades ms que se pueden encontrar en
documentacin sobre Tkinter por la web. Veamos el ejemplo de
arriba
ms personalizado
from Tkinter import *
v0=Tk()
v0.config(bg="black")
v0.title("Ejemplo personalizado")
v0.geometry("210x190")

def colocar_scrollbar(listbox,scrollbar):
scrollbar.config(command=listbox.yview)
listbox.config(yscrollcommand=scrollbar.set)
scrollbar.pack(side=RIGHT, fill=Y)
listbox.pack(side=LEFT, fill=Y)
frame1=Frame(v0,bg="black")
frame1.pack()
scroll1=Scrollbar(frame1)
list1=Listbox(frame1,bg="black",fg="white")
list1.pack()
colocar_scrollbar(list1,scroll1)
mitexto=StringVar()
label1=Label(v0,textvar=mitexto,bg="black",fg="white")
label1.pack()
b1=Button(v0,text="ELIMINAR TODOS",command=lambda:
limpiar_listbox(list1),bg="black",fg="white")
b1.pack()
def cargarlistbox(lista,listbox):
ind,largo=0,len(lista)
while ind < largo:
listbox.insert(END,lista[ind])
ind+=1
ListaNombres=['Laura','Roger','Fabiola','Yendry','Esteban','Mart
a','Elias']
def imprimir_en_label():
label1.after(100, imprimir_en_label) # Llamada recursiva con
.after
ind = list1.curselection()
if list1.curselection() != ():
sel = list1.get(ind)
mitexto.set(sel)
def limpiar_listbox(listbox):
while listbox.size() > 0:
listbox.delete(0)
cargarlistbox(ListaNombres,list1)
imprimir_en_label()
v0.mainloop()

Existen otros elementos personalizables como


width: El ancho
height: El alto
border: Tamao de borde
En interfaces ms avanzadas se puede configurar el nivel de
opacidad, logrando as el efecto de transparencia de las
ventanas ms conocidas. Pero eso no es tan necesario
mencionarlo

11. IMPRIMIENDO LA HORA CON TODO Y FECHA


Existe un mdulo en Python llamado time. Utilizando la siguiente
implementacin se puede conseguir la hora:
Ejemplo 20:
import time
def imprimir_fecha():
return str(time.localtime()[2]) + "/" + str(time.localtime()
[1]) + "/" + str(time.localtime()[0]) + ", " +
str(time.localtime()[3]) + ":" + str(time.localtime()[4]) + ":"
+ str(time.localtime()[5])
print imprimir_fecha()
Ejemplo 21:
Si uno deseara, podra conseguir imprimir ms informacin, como
los nombres del mes, entre otras cosas.
En el siguiente ejemplo hay una implementacin de cmo se
consigue imprimir la hora actual en un label.
import Tkinter

from Tkinter import *


import time
def imprimir_fecha():
return str(time.localtime()[2]) + "/" + str(time.localtime()
[1]) + "/" + str(time.localtime()[0]) + ", " +
str(time.localtime()[3]) + ":" + str(time.localtime()[4]) + ":"
+ str(time.localtime()[5])
v0=Tk()
v0.title("Hora")
mifecha=StringVar()
l1=Label(v0,textvar=mifecha,font=(16))
l1.pack()
l2=Label(v0,text="",font=(16))
l2.pack()
def refresh_fecha():
v0.after(1000,refresh_fecha)
mifecha.set(imprimir_fecha())
l2.config(text=imprimir_fecha())
refresh_fecha()
v0.mainloop()

Adems en este ejemplo podemos ver que existen dos formas de


cambiar el texto de un control Label, utilizando
objeto.config(text='loquesea') o creando una variable de tipo
StringVar() y modificndola directamente.
El ejemplo sirve incluso para crear efectos animaciones, y
textos cambiantes. Eso queda a imaginacin del programador.

12. GUARDANDO Y ABRIENDO UN ARCHIVO CON TEXTO


Ahora vamos a hacer uso de varios mdulos. Esta aplicacin abre
una ventana con un control Text y un control Button.
Ejemplo 22:
El siguiente cdigo guarda un archivo de texto en una ruta
especficada. Y luego, si cerramos el programa, cuando lo

volvemos a abrir, nos devuelve el texto que guardamos


anteriormente (Puedes cambiar el enlace si ests trabajando en
Ubuntu u otro Sistema Operativo que no lee disco C como en
Windows)
# -*- coding: utf-8 -*import Tkinter
from Tkinter import *
import codecs
import os
v0 = Tkinter.Tk()
v0.config(bg="black")
v0.resizable(0,0)
def doit(f): v0.after(100, f)
def imprimir(textcontrol): print textcontrol.get('1.0', END+'1c')
def escribir_en_archivo(enlace):
f = codecs.open(enlace,"w","utf-8")
texto = t1.get('1.0', END+'-1c')
f.write(texto)
f.close()
def abrir_archivo(enlace):
if os.path.exists(enlace):
f = open(enlace,"r")
h= f.read()
t1.insert(END,h)
f.close()
t1=Text(v0)
t1.config(bg="black",fg="white")
t1.pack()
b1 = Button(v0,text="<< SAVE >>",command=lambda:
doit(escribir_en_archivo('C:\hola.txt')))
b1.config(bg="black",fg="white")
b1.pack()
abrir_archivo('C:\hola.txt')
v0.mainloop()

Este permite guardar y cargar informacin en archivos de texto,


siempre y cuando sea string, lo guardar adecuadamente.
Cabe destacar que este pequeo programa tiene un cdigo un tanto
simple, pero tiene algunos detalles interesantes. Por
ejemplo, no es igual utilizar controles Entry (una sola lnea)
que controles Text (Varias lneas de texto)
Su informacin es diferente, sus mtodos, y algunas cosas para
leer y escribir informacin en un control de tipo Text, es
diferente a la manipulacin del objeto Entry. Adems en este
ejemplo ni siquiera podemos ver toda la capacidad que tiene
el objeto Text. Es uno de los objetos ms potentes que tiene la
interfaz Tkinter.
El segundo detalle a tomar en cuenta, es que, aunque parezca
fcil, no es para nosotros obvio a simple vista que hay algo
en este documento, lo que e conoce como codificacin.
La codificacin es para que no se nos caiga nuestra aplicacin
cuando intentemos guardar en un archivo, caracteres tales
como tildes, ees, y otros caracteres que se necesitan. Para
ello incluso se importa un mdulo llamado codecs, y se

utiliza utf-8, que les recomiendo realicen una bsqueda en


google y revisen la informacin sobre la diferente codificacin
de caracteres.
Otro detalle raro es la forma en la que se consigue el texto de
un control del tipo Text
'1.0', END+'-1c'
Cuando en los controles Entry basta con
Entry.get(mi_variable_entry)
Finalmente, para cargar el archivo primero se verifica si el
archivo existe, esto lo podemos realizar con el mdulo os, con
el que podemos verificar si un archivo existe en el sistema, si
existe entonces lo abrir.

13. GUARDANDO Y ABRIENDO LISTAS CON PICKLE


El mdulo Pickle permite guardar las listas como estructuras de
datos y luego recuperarlas desde el archivo. Esto nos
permitira guardar toda la informacin de una lista y
recuperarla tal cual.
Ejemplo 23:
En este ejemplo importamos el mdulo pickle y creamos unas
funciones para guardar y abrir listas.
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
guardar_lista([1,2,3,4,5,6,7],"datos.txt")
print cargar_lista("datos.txt")
En este ejemplo guardamos una lista con los
en el archivo datos.txt que se crear en la
donde est guardado el archivo.py donde se
de arriba, pero nosotros podemos cambiar la
ejemplo 'C:\datos.txt'

nmeros del 1 al 7
misma carpeta
encuentra el cdigo
ruta, por

RESUMEN INTERFAZ GRFICA


CUARTA PARTE
4 Noviembre del 2010
Autor: Grupo 50, Segundo Semestre 2010 (Sede San Carlos)

14. GUARDANDO Y CARGANDO OBJETOS CON PICKLE


El mdulo pickle del que hablbamos 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 continuacin se presenta una forma de cmo 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 cdigo. Por lo que queda
comprobado que se guardan tambin los objetos con el
mdulo pickle

15. COLOCANDO UNA IMGEN GIF ESTTICA CON UN


LABEL
Las imgenes existen varios formatos, es algo muy bsico que ya
deberamos saber. Existen formatos como JPG, PNG, BMP, GIF,
entre otros.
Ejemplo 25:
Una forma de colocar una imgen GIF en una ventana sera 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:

http://i.imgur.com/qTKZv.gif

Es una imgen que ya tiene el formato GIF correcto y no presentar


problemas a la hora de cargarlo.

Cabe sealar que para cambiarle el formato a una imgen basta con
quitarle la extensin que tiene y ponerle otra. Debe ser
previamente abierta con un programa que permita abrir el formato en el
que est la imgen original, y guardarla en formato
GIF.

16. CREANDO MENES EN LA PARTE SUPERIOR DE LA


VENTANA
Ejemplo 26:
Vamos a agregarle a la hermosa Angelina Jolie unos cuntos menes arriba.
Supongamos que vamos a dividir cosas en submenes
segn 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="PIA",command=lambda: imprimir("PIA"))
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()

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.
Adems 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:

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
def
def
def

imprimir(texto): print texto


mostrar(ventana): return ventana.deiconify # Muestra una ventana
ocultar(ventana): return ventana.withdraw() # Oculta una ventana
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="PIA",command=lambda: imprimir("PIA"))

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
APLICACIN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA
APLICACIN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA
APLICACIN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA
APLICACIN",bg="black",fg="white",font=(15)).pack()
Label(v1,text="BIENVENIDO A NUESTRA
APLICACIN",bg="black",fg="white",font=(15)).pack()
v0.mainloop()
Utiliza el mtodo 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 ms haciendo con Python, es
acomodando los elementos. Si estuvisemos programando en
Java con Netbeans, sera ms cmodo pues disponemos de un panel como el
siguiente:

Por lo que para nosotros que debemos hacerlo a pura lnea de cdigo,
puede ser un poco ms complicado. Sin embargo, como es

para propsito meramente de aprendizaje, es indispensable haber hecho


aunque sea una vez en toda tu carrera (Que habr
ms) el trabajo de Interfaz Grfica solo utilizando cdigo, sin
herramientas externas.
Para acomodar los elementos en Python, al igual que en Scheme, y me
imagino que en la mayora de lenguajes de programacin
que posean un mdulo de Interfaz Grfica
que se haga llamar
standard, se utilizan paneles, y dos propiedades de los
objetos grficos, llamados .pack() y .grid()
Ejemplo 28:
Las ventanas tienen
llaman TOP, BOTTOM,
esto para acomodar
siguiente forma:
from Tkinter import

arriba, abajo, izquierda y derecha. En ingls se


LEFT, RIGHT. Podemos hacer uso de
los elmentos a un lado o al otro de la ventana, de la
*

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()

Ejemplo 29:
Y el orden de colocacin en el cdigo s importa. Nte 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.

Ejemplo 30:
Es importante recordar que tambin podemos colocar el cdigo 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 ms frames que cualquier otro tipo de elemento


grfico.
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 algn editor grfico, y pensar en cmo
quedar al final. Ac tenemos un ejemplo de cmo se pueden acomodar los
elementos con Frame

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
Label(frame1,text="T e
Label(frame1,text="T e
Label(frame1,text="T e
Label(frame1,text="T e
frame1.pack(side=LEFT)

x
x
x
x
x

t
t
t
t
t

o").pack()
o").pack()
o").pack()
o").pack()
o").pack()

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

e
e
e
e
e

T").pack()
T").pack()
T").pack()
T").pack()
T").pack()

v0.mainloop()

Ejemplo 32
Tambin tenemos propiedades para algunos objetos grficos, que sirven
para acomodamiento en las ventanas. Se llaman expand
y fill. Veamos un ejemplo de cmo 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
Label(frame1,text="T e
Label(frame1,text="T e
Label(frame1,text="T e
Label(frame1,text="T e
frame1.pack(side=LEFT)

x
x
x
x
x

t
t
t
t
t

o").pack()
o").pack()
o").pack()
o").pack()
o").pack()

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

e
e
e
e
e

T").pack()
T").pack()
T").pack()
T").pack()
T").pack()

v0.mainloop()

En la documentacin viene ms informacin 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 mtodo de Frames

20. ACOMODANDO LOS ELEMENTOS: GRID


Otra forma de acomodar los elementos en una ventana es con el mtodo
grid. Anteriormente vimos que el mtodo .pack tena
atributos como side, fill y expand.
El mtodo grid tiene como atributos row y column. En una matriz, row (en
espaol fila) son las lneas horizontales
(conocidas tambin como vectores), y column (columnas..), son las lneas
verticales.

Esta es la forma de comprender el mtodo 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 ms arriba pero con grid, sera 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()

Dos observaciones importantes. La primera, no mezcles ObjetoBoton.pack()


y ObjetoBoton.grid() en una misma ventana. Y la
segunda, Es que podras introducir los elementos en frames, y luego
utilizar el grid para acomodar los Frames. Se debe
planear la manera en cmo irn acomodados los elementos.
Adems una de las cosas que debemos tomar en cuenta cuando programamos
una interfaz, es que si va a cambiar el tamao de la
ventana, debemos configurarla adecuadamente para que se mantenga la
proporcin del aspecto. Por que si maximiza la
ventana, los elementos se van a ver mal. Una solucin para esto es
prohibir que se pueda cambiar el tamao de la ventana,
o buscar maneras para que los elementos 'se mantengan en su sitio' an
cuando la ventana cambie de tamao
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 documentacin de grid y dems elementos de la interfaz
Tkinter en general, dirjase al siguiente link:

http://effbot.org/tkinterbook/grid.htm

RESUMEN INTERFAZ GRFICA


V PARTE
5 Noviembre del 2010

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

21. EJEMPLO DE INTERFAZ GRFICA CON UN JUEGO GATO


(TRES EN LINEA)
Para este ejemplo se cre un gato, en el que juegan dos jugadores. Cuando
un jugador hace 3 lneas seguidas gana el juego.
Se utilizan algunos de los elementos explicados en los tutoriales
anteriores:
- Uso del IDE PyScripter
- Mdulo Tkinter
- Evento objetografico.after(milisegundos,funcin)
- Mtodo objetografico.grid(row=i,column=j)
- Mtodo lambda para asignar ms de un evento a un botn
- Control de Flujo
- Uso de ventana.withdraw() para ocultar ventanas
- Uso de ventana.deiconify() para mostrar ventanas
- Uso de listas para almacenar informacin de manera temporal
- Abastraccin y aprovechamiento del lenguaje para declarar variables por
medio de tuplas ()
- Uso de la codificacin utf-8 para evitar problemas con caracteres tales
como tildes, ees, entre otros
- Propiedades y atributos de las ventanas como resizable para evitar que
se pueda redimencionar, o title para colocar
ttulo a esta
- Uso de font para cambiar el tamao de la letra de un control de tipo
Label
Ejemplo 33

# -*- coding: utf-8 -*from Tkinter import *


v0=Tk()
v0.title("Gato")
v0.resizable(0,0)
color,nl,matriz,ganador=["red"],[],[0,0,0,0,0,0,0,0,0],[0]

def imprimir(t): print t


def doit(f): v0.after(100,f) # Evento por tiempo
# Crea un gato
def gato():
ind=0
c1,c2=0,0
while ind < 9:
nl.append(Button(v0,text="",width=10,height=5,bg="white"))
nl[ind].grid(row=c2,column=c1)
ind+=1
if c1==2: c1,c2=0,c2+1
else: c1+=1
nl[0].config(command=lambda: jugar(0)), nl[1].config(command=lambda:
jugar(1))
nl[2].config(command=lambda: jugar(2)), nl[3].config(command=lambda:
jugar(3))
nl[4].config(command=lambda: jugar(4)), nl[5].config(command=lambda:
jugar(5))
nl[6].config(command=lambda: jugar(6)), nl[7].config(command=lambda:
jugar(7))
nl[8].config(command=lambda: jugar(8))
def juego_finalizado(): # Revisa si el gato est lleno. Si lo est
devuelve True
ind,largo=0,len(matriz)
while ind < largo:
if matriz[ind] == 0:
return False
break
ind+=1
return True
def tres_linea(lista):
if matriz[lista[0]] != 0 and matriz[lista[1]] != 0 and
matriz[lista[2]] != 0:
if matriz[lista[0]] == matriz[lista[1]] == matriz[lista[2]]:
ganador[0]=matriz[lista[0]]
return True
return False
def gana():
if tres_linea([0,1,2]) or tres_linea([3,4,5]) or tres_linea([6,7,8])
or tres_linea([0,3,6]) or tres_linea([1,4,7]) or tres_linea([2,5,8]) or
tres_linea([0,4,8]) or tres_linea([2,4,6]):
return True
def limpiar_botones():
color="white"
ind,largo=0,len(nl)
while ind < largo:
nl[ind].config(bg=color)
ind+=1

matriz[0],matriz[1],matriz[2],matriz[3],matriz[4],matriz[5],matriz[6]
,matriz[7],matriz[8]=0,0,0,0,0,0,0,0,0
def declarar_ganador():
v0.after(200,declarar_ganador)
if gana():
limpiar_botones()
v0.withdraw()
v1=Toplevel(v0)
if ganador[0] == 1:
l1=Label(v1,text="Ganador: Jugador 1 (Azul)",font=(16))
color[0]="red"
if ganador[0] == 2:
l1=Label(v1,text="Ganador: Jugador 2 (Rojo)",font=(16))
color[0]="blue"
l1.pack()
b1=Button(v1,text="OK",command=lambda: v1.withdraw() or
v0.deiconify(),font=(16))
b1.pack()
v1.focus_force()
def reiniciar_juego():
v0.after(200,reiniciar_juego)
if juego_finalizado():
v0.withdraw()
v1=Toplevel(v0)
v1.title("Finalizado")
v1.resizable(0,0)
l1=Label(v1,text="Nadie Gan.",font=(16))
l1.pack()
b1=Button(v1,text="OK",command=lambda: v1.withdraw() or
v0.deiconify(),font=(16))
b1.pack()
doit(limpiar_botones())
def jugar(posicion):
if matriz[posicion] != 0:
print "Ya se jug en esta posicin"
else:
if color[0]=="red":
matriz[posicion]=1
color[0]="blue"
nl[posicion].config(bg=color)
elif color[0]=="blue":
matriz[posicion]=2
color[0]="red"
nl[posicion].config(bg=color)
print "ESTADO DE LA MATRIZ:",matriz
gato()
declarar_ganador()
reiniciar_juego()
v0.mainloop()

RESUMEN INTERFAZ GRFICA


VI PARTE
5 Noviembre del 2010
Autor: Grupo 50, Segundo Semestre 2010 (Sede San Carlos)

22. HACER QUE DOS LISTAS INTERACTEN


Supongamos que necesitamos que dos listas interacten entre s.
Una lista contiene grupos, y otra lista contiene personas.
Cuando yo hago click en uno de los grupos de la lista, entonces
la otra lista se llena con todas las personas que
pertenezcan a ese grupo.
Para este ejemplo utilizaremos las carreras que se imparten en
la Sede de San Carlos, con algunos nombres de personas.
Adems cuando le damos click al nombre de una persona, en la
consola se imprime dicho nombre.
Ejemplo 34
# -*- coding: utf-8 -*from Tkinter import *
v0=Tk()
v0.resizable(0,0)
v0.title("Dos Listbox")
gsel=StringVar()
switch=[0]
def llenar_listbox(lista,listbox):
ind,largo=0,len(lista)
while listbox.size() > 0: # Un while para limpiar el listbox
listbox.delete(0)
while ind < largo: # Un while que inserta todos los
elementos en una lista
listbox.insert(END,lista[ind])
ind+=1
def vargrupo():
v0.after(200,vargrupo)
if l2.curselection() != ():
print l2.get(l2.curselection())
if l1.curselection() != ():
gsel.set(l1.get(l1.curselection()))
if gsel.get() == "Computacion":
llenar_listbox(Compu,l2)
if gsel.get() == "Agronomia":
llenar_listbox(Agro,l2)
if gsel.get() == "Administracion":

llenar_listbox(Turistas,l2)
if gsel.get() == "Turismo":
llenar_listbox(Admin,l2)
ListaCarreras=["Computacion","Agronomia",
"Administracion","Turismo"]
Compu=["Ana","Alejandra","Ronald","Andrey"]
Agro=["Jefry"]
Turistas=["Laura","Jose Mara"]
Admin=["Andrea","Roberta"]
l1=Listbox(v0)
l1.grid(row=1,column=0)
l2=Listbox(v0)
l2.grid(row=1,column=1)
b1=Button(v0,text="SALIR",width=40,command=v0.destroy)
b1.grid(row=2,column=0,columnspan=2)
vargrupo()
llenar_listbox(ListaCarreras,l1)
v0.mainloop()

Para este ejemplo utilizamos:


controlistbox.curselection(): Es la posicin en la que se
encuentra el elemento dentro del listbox. La posicin inicial es
cero.
controlistbox.get(nmero) : Recibe un nmero y devuelve un
string con el elemento que se encuentra en esa posicin.
Y por lo tanto,
controlistbox.curselection(controlistbox.get(nmero)) retorna el
elemento que estamos clickeando en ese
momento. Si llamamos con ventana.after(tiempo,funcin) podemos
lograr que nos retorne el elemento clickeado. Eso es
precisamente lo que ocurre en este ejemplo.

23. UN ACELERADOR, EL EVENTO


VENTANA.AFTER(TIEMPO,FUNCIN)
Cuando hacemos un while o un for, y queremos que se nos impriman
datos en la pantalla, nosotros no podemos controlar la
velocidad en la que esos datos se imprimirn.
Ejemplo 35
El ejemplo siguiente muestra como crear un acelerador, donde nos
vaya imprimiendo algo como lo siguiente:
1 Km/h
2 Km/h
3 Km/h
...
100 Km/h
101 Km/h
Y cada vez lo vaya imprimiendo ms rpido. Cuando llega al punto
mximo de velocidad, entonces comienza a retroceder hasta
llegar al 0 Km/h.
Con qu propsito? Para comprender de mejor manera como
funciona el evento ventana.after().
Para este ejemplo imprimiremos en cnsola y adems cambiaremos
el valor de una StrinVar() que controla el texto de un
control de tipo Label
# -*- coding: utf-8 -*from Tkinter import *
v0=Tk()
v0.resizable(0,0)
v0.title("ACELERADOR")
speed=StringVar()
label1=Label(v0,textvar=speed,font=(20)).grid()
b1=Button(v0,text="TERMINAR
KILOMETRAJE",command=v0.destroy,font=(16)).grid()
gas=[180]
limite=[1]
velocidad=[1]
switch=[1]
def acelerador():
v0.after(gas[0],acelerador)
if gas[0] > limite[0] and switch[0]==1:
gas[0]-=1
print "Vamos a",velocidad[0],"Km/h"

speed.set("Vamos a " + str(velocidad[0]) + " Km/h")


velocidad[0]+=1
else:
switch[0] = 0
limite[0]= 180
if gas[0] < limite[0] and switch[0]==0:
gas[0]+=1
print "Vamos a",velocidad[0],"Km/h"
speed.set("Vamos a " + str(velocidad[0]) + " Km/h")
velocidad[0]-=1
else:
if switch[0]==0:
switch[0]=1
gas[0]=180
velocidad[0]=1
limite[0]= 1
acelerador()
v0.mainloop()

El evento ventana.after(tiempo,funcin) ha sido utilizada a lo


largo de este tutorial y sirve para multitud de eventos
aunque no es el ms adecuado a la hora de realizar algunas
tareas.

24. UTILIZANDO GRID, PARA ACOMODAR EXACTAMENTE A


NUESTRO ANTOJO
Supongamos que queremos tener una ventana con varios elementos
pero que esos elementos estn acomodados de acuerdo a la
manera en la que nosotros queremos que estn. Muchas veces
tenemos una idea y a la hora de llevarla a la interfaz no se ve
como nosotros queremos. Y muchas de esas veces esto sucede
porque no tenemos una herramienta eficaz dentro del mdulo de
la interfaz que nos permita acomodar las cosas con algo ms que
paneles. En Python por suerte tenemos el mtodo grid, y
este nos permite acomodar las cosas a nuestro antojo.
Ejemplo 36
Si dibujamos una interfaz, por ejemplo:

Queremos esta estructura, donde cada cajita es un botn. Esto lo


podemos hacer con grid. Solo debemos pensar en cada
elemento como si este fuera parte de una matriz.
# -*- coding: utf-8 -*from Tkinter import *
v0=Tk()
v0.resizable(0,0)
v0.title("GRID")
Button(v0,width=25,height=7).grid(row=0,column=0,rowspan=2)
Button(v0,width=25,height=7).grid(row=1,column=0,rowspan=2)
Button(v0,width=25,height=7).grid(row=0,column=1)
Button(v0,width=25,height=7).grid(row=1,column=1)
Button(v0,width=25,height=7).grid(row=2,column=1)
Button(v0,width=25,height=7).grid(row=0,column=2,rowspan=2)
Button(v0,width=25,height=7).grid(row=1,column=2,rowspan=2)
v0.mainloop()
Ejemplo 37
Otra forma como la siguiente:

Se puede hacer fcilmente con


# -*- coding: utf-8 -*from Tkinter import *
v0=Tk()
v0.resizable(0,0)
v0.title("GRID")
Button(v0,width=6,height=3).grid(row=0,column=0)
Button(v0,width=6,height=3).grid(row=0,column=2)
Button(v0,width=6,height=3).grid(row=0,column=3)
Button(v0,width=6,height=3).grid(row=0,column=4)
Button(v0,width=6,height=3).grid(row=0,column=5)
Button(v0,width=6,height=3).grid(row=0,column=6)
Button(v0,width=6,height=3).grid(row=0,column=7)
Button(v0,width=6,height=3).grid(row=0,column=8)
Button(v0,width=6,height=3).grid(row=0,column=9)
Button(v0,width=6,height=3).grid(row=0,column=10)
Button(v0,width=6,height=3).grid(row=0,column=11)
Button(v0,width=6,height=3).grid(row=1,column=0)
Button(v0,width=6,height=3).grid(row=2,column=0)

Button(v0,width=6,height=3).grid(row=3,column=0)
Button(v0,width=6,height=3).grid(row=4,column=0)
Button(v0,width=6,height=3).grid(row=5,column=0)
Button(v0,width=6,height=3).grid(row=6,column=0)
Button(v0,width=6,height=3).grid(row=7,column=0)
Button(v0,width=6,height=3).grid(row=8,column=0)
Button(v0,width=6,height=3).grid(row=1,column=11)
Button(v0,width=6,height=3).grid(row=2,column=11)
Button(v0,width=6,height=3).grid(row=3,column=11)
Button(v0,width=6,height=3).grid(row=4,column=11)
Button(v0,width=6,height=3).grid(row=5,column=11)
Button(v0,width=6,height=3).grid(row=6,column=11)
Button(v0,width=6,height=3).grid(row=7,column=11)
Button(v0,width=6,height=3).grid(row=8,column=11)
Button(v0,width=6,height=3).grid(row=8,column=2)
Button(v0,width=6,height=3).grid(row=8,column=3)
Button(v0,width=6,height=3).grid(row=8,column=4)
Button(v0,width=6,height=3).grid(row=8,column=5)
Button(v0,width=6,height=3).grid(row=8,column=6)
Button(v0,width=6,height=3).grid(row=8,column=7)
Button(v0,width=6,height=3).grid(row=8,column=8)
Button(v0,width=6,height=3).grid(row=8,column=9)
Button(v0,width=6,height=3).grid(row=8,column=10)
Button(v0,width=66,height=25,text="UN GRAN
CLICK").grid(row=1,column=1,rowspan=7,columnspan=10)
v0.mainloop()
Ejemplo 38
Y un formulario de contacto:
# -*- coding: utf-8 -*from Tkinter import *
v0=Tk()
v0.resizable(0,0)
v0.title("FORMULARIO")
Label(v0,text="Formulario de
Contacto",width=50).grid(row=0,column=0,columnspan=4)
Label(v0,text="Nombre: ").grid(row=1,column=0,sticky=W)
Entry(v0).grid(row=1,column=2)
Label(v0,text="Email: ").grid(row=2,column=0,sticky=W)
Entry(v0).grid(row=2,column=2)
Label(v0,text="Telfono: ").grid(row=3,column=0,sticky=W)
Entry(v0).grid(row=3,column=2)
Label(v0,text="Profesin: ").grid(row=4,column=0,sticky=W)
Entry(v0).grid(row=4,column=2)
Label(v0,text="Cdula: ").grid(row=5,column=0,sticky=W)
Entry(v0).grid(row=5,column=2)

l1=Listbox(v0,height=6)
l1.grid(row=0,column=3,rowspan=20)
l1.insert(END,"Costa
Rica"),l1.insert(END,"Croacia"),l1.insert(END,"Estados Unidos")
Button(v0,text="Registrar",width=50).grid(row=10,column=0,column
span=4)
v0.mainloop()

25. COMPRENDIENDO LOS CONTROLES COMO OBJETOS


An nos falta mucho para comprender del todo los objetos. Sin
embargo en Python, est claro que cada control de la interfaz
Tkinter es un objeto. Por lo tanto, podemos hacer todo lo que
hacemos con nuestros objetos, pero utilizando controles de
interfaz.
Ejemplo 39
Por ejemplo podemos crear una funcin, que al introducirle un
nmero, nos cree una cantidad de botones en la ventana.
# -*- coding: utf-8 -*from Tkinter import *
v0=Tk()
v0.resizable(0,0)
v0.title("OBJETOS")
def crear_botones(n):
ind,acumulador,fila,columna=1,0,0,0
while ind <= n:
Button(v0,text=" " + str(ind) + "
",width=2).grid(row=fila,column=columna)
if acumulador==39: fila,columna,acumulador=fila+1,0,0
else: acumulador,columna=acumulador+1,columna+1
ind+=1
crear_botones(600)
v0.mainloop()

26. BINARIUM

Finalmente para acabar con la parte de animaciones y


ventana.after, en este ejemplo se presentan varias funciones. La
idea
es que podamos analizarla y saber que hace cada funcin (Por lo
que los nombres de todos los elementos son representados por
letras)
Ejemplo 40
# -*- coding: utf-8 -*from Tkinter import *
a=Tk()
a.resizable(0,0)
a.geometry("550x400")
a.title("BINARIUM")
b=StringVar()
b.set("""
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
""")
c="""
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010

1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
1001010101010010010101010010110010101010100100101010100101
0100101010101001001010101001001001010101010010010101010010
"""
def ds(h):
f,g=0,len(h)
while f < g:
if h[f] != " ":
return False
break
f+=1
return True
def s(h):
taud=h
if not ds(h):
h = " " + h[0:-1]
return h
else: return c
def j(t): print t
def i():
a.after(1,i)
b.set(s(b.get()))
label1=Label(a,textvar=b,font=(16)).pack(side=TOP)
i()
a.mainloop()

RESUMEN INTERFAZ GRFICA


VII PARTE
5 Noviembre del 2010

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

30. wxPython, Otro mdulo para interfaces


grficas con Python
Bueno, parece que han habido muchas cosas qu aprender sobre
Tkinter.
Suponiendo que Tkinter tiene algn rival podra decirse que
sera wxPython. As que me pareci interesante conocer a este
rival de Tkinter, y debo decir que me he llevado muy buenas
sorpresas.
Aunque siento que se ha quedado corto el manual del Tkinter. Por
ejemplo, nunca tocamos el tema de objeto.bind, todo lo
hicimos con afters.. Y sin embargo, el objeto.bind es una de
las cosas indispensables a la hora de usar Tkinter. Pero
bueno, ya fue. Ya agregar unos cuntos ejemplos ms para
Tkinter. Saltamos entonces al apartado 30 de este tutorial de
interfaces. Para los que estn muy dispuestos a sacarle el
mximo provecho a este curso, no solo vamos a ver un mdulo de
interfaces grficas, si no que vamos a entrar ahora con otro,
el wxPython.
WxPython NO VIENE CON EL PYTHON, hay que bajrselo. Hay que
instalarlo. Por eso prefer realizar la interfaz con Tkinter y
toda la documentacin posible.
Y muchos se preguntarn Para qu bajarse otro mdulo si ya
Python tiene el Tkinter? Bueno, pues, primero porque es
interesante comparar ambos, y segundo, porque las ventajas que
tiene wxPython sobre Tkinter, podran ser interesantes y
nos podran ayudar talvez no ahora, pero en un futuro, cuando
ya tengamos trabajo y necesitemos realizar este tipo de
comparaciones.
As que si quieres comenzar a trabajar y probar los ejemplos con
este tutorial, ya seas usuario de alguna de las distros de
Linux (como Ubuntu o Kubuntu), usuario de Windows, o usuario de
otras cosas como Mac entre otras, lo primero que debes
hacer es bajarte el wxPython e instalartelo. Para eso vaya a
esta pgina:
http://wxpython.org/
Que vamos a aprender? Vamos a aprender que se puede programar
una interfaz grfica de dos maneras distintas, tambin,
vamos a saber cmo se programa una interfaz con wxPython.
Una vez que encuentren la forma de instalarlo, entonces podemos
comenzar.

31. Una ventana en wxPython


Cmo se abre una ventana en wxPython ejemplo sencillo:
from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON") # Ventana padre
v1.Show() # Muestra la ventana
v0.MainLoop() # Ejecuta el programa
Es diferente con Tkinter en algunas cosas. Como por ejemplo:
- En vez de from import Tkinter * tenemos from wx import *
- En vez de v0=Tk() tenemos v0 = PySimpleApp()
- En lugar de tener v1 a v0 como elemento padre, colocamos none
- Un Frame en wxPython no es un panel si no una ventana
- El ttulo se puede introducir entre las opciones del Frame
- Para mostrar una ventana basta con decir ventana.Show() y de
hecho para ocultarla se utiliza ventana.Hide()
- El mainloop es igual al del Tkinter pero este se escribe
MainLoop(), con maysculas (Debe ser en maysculas)
Sera bueno tener claro como poder hacer todas las cosas que
hacemos en Tkinter, pero con wxPython, a la hora de trabajar con
ventanas. Por ejemplo cmo hacemos para:
- Evitar que se redimencione la ventana
- Quitar bordes y botones de cerrar, minimizar, maximizar, barra
de ttulos, a la ventana
- Crear menes en las ventanas
- Poner la ventana siempre visible
- Y se ver igual en Ubuntu que en Windows?

32. Modificando las ventanas en wxPython


Vamos a ver un ejemplo de algunas propiedades que podemos darle
a nuestar ventana. Para cambiar el tamao se hace de la
siguiente forma
from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON",size=(640,480)) #
Ventana padre
v1.CentreOnScreen() # Centra la ventana
v1.Show() # Muestra la ventana

v0.MainLoop() # Ejecuta el programa


Aqu vemos que con wxPython si que podemos centrar la ventana
fcilmente, adems usamos size para darle el tamao que
queremos.

Incluso podemos indicar que queremos que nuestro programa ocupe


toda la pantalla (Modo Full Screen) de la siguiente forma:

from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON") # Ventana padre
v1.CentreOnScreen() # Centra la ventana
v1.ShowFullScreen(1) # Hace que el programa ocupe toda la
pantalla
v1.Show() # Muestra la ventana
v0.MainLoop() # Ejecuta el programa
Y para que no pueda cambiarse el tamao
from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON",size=(640,480)) #
Ventana padre
v1.Show() # Muestra la ventana
b1=Button(v1,label="Aceptar",pos=(240, 420), size=(80, 25))
b2=Button(v1,label="Salir",pos=(330, 420), size=(80, 25))
v1.SetBackgroundColour("white") # Cambia el color de fondo
v1.SetSizeHints(640,480,640,480) # Minimo Ancho, Minimo Alto,
Maximo Ancho, Maximo Alto
v1.CentreOnScreen() # Centra la ventana
v0.MainLoop() # Ejecuta el programa
Adems le hemos cambiado el color de fondo. Se empieza a notar
que algunas cosas son ms sencillas y manejables desde wxPython
que desde Tkinter. A estas alturas debera irnos quedando de la
siguiente forma:

33. Mostrando HTML directamente desde una ventana


con wxPython
Dependiendo del conocimiento que tengamos sobre algunos
lenguajes web, esta definitivamente va a sonarte como una opcin
interesantsima de Python. Con esta opcin podemos mostrar
imgenes online e incluso pginas web completas, en una ventana
de Python. Por ejemplo, si quisiramos mostar en la ventana que
creamos arriba, una imgen que est en internet, una opcin para
realizarlo sera la siguiente:
from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON",size=(640,480)) #
Ventana padre
v1.Show() # Muestra la ventana

v1.SetBackgroundColour("white") # Cambia el color de fondo


v1.SetSizeHints(640,480,640,480) # Minimo Ancho, Minimo Alto,
Maximo Ancho, Maximo Alto
v1.CentreOnScreen() # Centra la ventana
l1=StaticText(v1,label="EJEMPLO DE UN CONTROL TEXTO",pos=(240,
400))
l1.SetForegroundColour("blue")
b1=Button(v1,label="Aceptar",pos=(240, 420), size=(80, 25))
b2=Button(v1,label="Salir",pos=(330, 420), size=(80, 25))
SeccionHtml = html.HtmlWindow(v1,-1,size=(350,381),pos=(160, 1))
SeccionHtml.SetPage('''<img
src="http://i.imgur.com/UbhPr.gif"/>''')
v0.MainLoop() # Ejecuta el programa

La imgen es de un gato al que le brillan los ojos. Dicha imgen


tiene una secuencia que se reproduce una y otra vez, lo que se
conoce como una imgen de un GIF ANIMADO.

Otra forma de lograrlo sera la siguiente:


from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON",size=(640,480)) #
Ventana padre
v1.Show() # Muestra la ventana
v1.SetBackgroundColour("white") # Cambia el color de fondo
v1.SetSizeHints(640,480,640,480) # Minimo Ancho, Minimo Alto,
Maximo Ancho, Maximo Alto
v1.CentreOnScreen() # Centra la ventana
l1=StaticText(v1,label="EJEMPLO DE UN CONTROL TEXTO",pos=(240,
400))
l1.SetForegroundColour("blue")
b1=Button(v1,label="Aceptar",pos=(240, 420), size=(80, 25))
b2=Button(v1,label="Salir",pos=(330, 420), size=(80, 25))
SeccionHtml = html.HtmlWindow(v1,-1,size=(350,381),pos=(160, 1))
SeccionHtml.LoadPage('http://i.imgur.com/UbhPr.gif')
v0.MainLoop() # Ejecuta el programa
Si lo que se quiere es abrir una pgina web entonces el cdigo
sera el siguiente:
from wx import *
v0 = PySimpleApp() # Elemento de aplicacin
v1=Frame(None,title="BIENVENIDO A WXPYTHON",size=(640,480)) #
Ventana padre
v1.Show() # Muestra la ventana
v1.SetBackgroundColour("white") # Cambia el color de fondo
v1.SetSizeHints(640,480,640,480) # Minimo Ancho, Minimo Alto,
Maximo Ancho, Maximo Alto
v1.CentreOnScreen() # Centra la ventana

l1=StaticText(v1,label="EJEMPLO DE UN CONTROL TEXTO",pos=(240,


400))
l1.SetForegroundColour("blue")
b1=Button(v1,label="Aceptar",pos=(240, 420), size=(80, 25))
b2=Button(v1,label="Salir",pos=(330, 420), size=(80, 25))
SeccionHtml = html.HtmlWindow(v1,-1,size=(350,381),pos=(160, 1))
SeccionHtml.LoadPage('http://www.google.com/imghp?hl=es&tab=wi')
v0.MainLoop() # Ejecuta el programa

Sin embargo no tiene mucha utilidad desde mi punto de vista, ya


que muchas pginas no se ven bien, debido a que utilizan
JavaScript y Flash, entre otros elementos. Creo que este control
es espectacular por si se desean agregar imgenes animadas y
otras cosas ms. As que si se tiene un poco de creatividad, se
sabe HTML, y Python, se tiene asegurado algo bastante llamativo.

Adems, podemos introducir el control HTML en una ventana, junto


con otros controles como botones y labels, como se puede ver
arriba.

34. Posicionando elementos en wxPython


Bueno, como vimos en el tutorial de Tkinter, se pueden utilizar
varios mtodos para ordenar los elementos tales como:
- Frames
- objeto.pack
- objeto.grid
En wxPython, podemos darle la posicin que queramos a los
elementos mediante las coordenadas (x,y), por lo que se puede
colocar EXACTAMENTE DONDE SE QUIERE. Por una parte es un poco
complicado saber las coordenadas donde queremos que est un
objeto, pero al poder acceder a dicha caracterstica, se logra
un acabado exacto. En muchos de los casos resulta mejor poder
dar la posicin a los elementos.
Esto no quiere decir que en wxPython no exista grid ni frames.
Al contrario, sera muy engorroso ordenar elementos del tipo
matriz, con coordenadas. Solo que al poder posicionar los
elementos, resulta mucho ms fcil ordenar algunos elementos sin
tener que adaptarse estricamente a columnas y filas. Se es ms
libre de colocar los elementos donde se requiera.

Das könnte Ihnen auch gefallen