RESUMEN INTERFAZ GRÁFICA

55
RESUMEN INTERFAZ GRÁFICA PRIMERA PARTE 3 Noviembre del 2010 Autor: Grupo 50, Segundo Semestre 2010 (Sede San Carlos) 1. Introducción: Este tutorial no está hecho para seguirlo al pie de la letra solo son algunas cosas básicas que debemos entender para poder trabajar con ventanas y para dar un pequeño salto desde la cónsola a la interfaz. Recordemos que somos la primera generación 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 cómo se trabaja desde ciertos puntos de vista, y el usuario se encargará de desarrollar su propia forma de construir la interfaz. 2. El Módulo que usaremos Un módulo se puede importar en Python. Existen diferentes formas de crear módulos, y de importarlos. Un módulo puede ser un archivo .py, o todo un conjunto de archivos que interactúan con el sistema operativo y la máquina en general. Por ejemplo el módulo time obtiene datos sobre la fecha, el módulo os obtiene datos sobre el sistema operativo. Python ya viene con varios módulos integrados, sin embargo nosotros podemos buscar en internet y descargar otros más. Para construir interfaz gráfica en Python se pueden utilizar varios módulos. Se pueden descargar módulos para crear la interfaz de la forma que más nos guste. Para este manual, usaremos el módulo Tkinter, porque ya viene instalado en Python y es con el que hemos trabajado, y bastará para darse una idea de cómo se trabaja en Python con interfaz gráfica. En algunas versiones de Linux no viene instalado el módulo Tkinter, entonces debemos escribir en la cónsola: sudo apt-get install python-tk Mientras que la versión 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

description

interfas grafica python

Transcript of RESUMEN INTERFAZ GRÁFICA

Page 1: RESUMEN INTERFAZ GRÁFICA

RESUMEN INTERFAZ GRÁFICA

PRIMERA PARTE

3 Noviembre del 2010

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

1. Introducción:

Este tutorial no está hecho para seguirlo al pie de la letra solo son

algunas cosas básicas que debemos entender para poder trabajar con ventanas y para dar un pequeño salto desde la cónsola a

la interfaz. Recordemos que somos la primera generación 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 cómo se trabaja desde

ciertos puntos de vista, y el usuario se encargará de desarrollar su propia forma de construir la interfaz.

2. El Módulo que usaremos

Un módulo se puede importar en Python. Existen diferentes formas de

crear módulos, y de importarlos. Un módulo puede ser un archivo .py, o todo un conjunto de archivos que interactúan con el

sistema operativo y la máquina en general. Por ejemplo el módulo time obtiene datos sobre la fecha, el módulo os

obtiene datos sobre el sistema operativo.

Python ya viene con varios módulos integrados, sin embargo nosotros

podemos buscar en internet y descargar otros más.

Para construir interfaz gráfica en Python se pueden utilizar varios

módulos. Se pueden descargar módulos para crear la interfaz de la forma que más nos guste.

Para este manual, usaremos el módulo Tkinter, porque ya viene instalado

en Python y es con el que hemos trabajado, y bastará para darse una idea de cómo se trabaja en Python con interfaz

gráfica. En algunas versiones de Linux no viene instalado el módulo Tkinter,

entonces debemos escribir en la cónsola: sudo apt-get install python-tk

Mientras que la versión 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

Page 2: RESUMEN INTERFAZ GRÁFICA

dado con uno que en lo personal me agrada y se llama Pyscripter. La

verdad me parece la alternativa más indicada para programar en Python (Tomando en cuenta que no realizaremos un super

programa empresarial, si no simples prácticas) En google pueden buscar y encontrarán versiones para varios sistemas

operativos.

Si no, pueden utilizar cualquiera que gusten.

4. Importando el módulo

Para importar un módulo 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 básicamente estas son las formas que se usan más.

5. Ventanas

Las ventanas se pueden configurar de diferentes formas. Veamos un ejemplo

de una ventana. Ejemplo 1:

from Tkinter import * # Importa el módulo

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:

Page 3: RESUMEN INTERFAZ GRÁFICA

Ahora para colocarle fondo a la ventana sería:

from Tkinter import * # Importa el módulo 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 tamaño de la ventana sería el siguiente:

from Tkinter import * # Importa el módulo v0 = Tk() # Tk() Es la ventana principal v0.config(bg="black") # Le da color al fondo v0.geometry("500x500") # Cambia el tamaño 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 habrán visto, declaramos una variable llamada v0, del tipo

Tk(). Además de Tk(), podemos declarar más variables

Toplevel: Crea una nueva ventana Frame: Coloca los páneles para ordenar los elementos Canvas: Para dibujar y graficar funciones etc.. Button: Para colocar un botón 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

Page 4: RESUMEN INTERFAZ GRÁFICA

Existe toda una mecánica para agregar elementos a una ventana. Además

de todo esto se pueden colocar imágenes y otras cosas. Por el momento estos controles básicos 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 módulo v0 = Tk() # Tk() Es la ventana principal v0.config(bg="black") # Le da color al fondo v0.geometry("500x500") # Cambia el tamaño 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 módulo v0 = Tk() # Tk() Es la ventana principal v0.config(bg="black") # Le da color al fondo v0.geometry("500x500") # Cambia el tamaño de la ventana

v1=Toplevel(v0) # Crea una ventana hija v1.withdraw() # oculta v1

Page 5: RESUMEN INTERFAZ GRÁFICA

v0.mainloop() # Es el evento que llama al inicio de nuestro programa.

Siempre lo lleva la ventana principal. Ahí ya ocultó la ventana. Pero cómo mostrarla otra vez?

Ejemplo 6:

Para importar un botón se hace de la siguiente forma: from Tkinter import * # Importa el módulo

v0 = Tk() # Tk() Es la ventana principal v0.config(bg="black") # Le da color al fondo v0.geometry("500x500") # Cambia el tamaño de la ventana b1=Button(v0,text="ABRIR VENTANA V1") # Primer botón b1.pack() # El botón 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 botón no tiene ningún evento, además fue cargado con el método .pack.

Lo podemos cargar con el método .grid Son dos formas distintas de cargar un botón. En vez de la primera forma: b1=Button(v0,text="ABRIR VENTANA V1") # Primer botón b1.pack() # El botón es cargado Pudimos haberlo escrito de esta otra forma: b1=Button(v0,text="ABRIR VENTANA V1").pack() En una sola línea. O de esta otra forma: b1=Button(v0,text="ABRIR VENTANA V1") # Primer botón b1.grid(row=1,column=1) # El botón es cargado Y esta otra forma: b1=Button(v0,text="ABRIR VENTANA V1").grid(row=1,column=1) # El botón

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 función llamada mostrar def mostrar(ventana): ventana.deiconify()

El método deiconify muestra la ventana que había sido oculta por

withdraw(). Además una función para ocultar podría ser

def ocultar(ventana): ventana.withdraw()

Page 6: RESUMEN INTERFAZ GRÁFICA

Con solo estas dos funciones ya podemos mostrar y ocultar la ventana 1.

vamos a agregar otro botón más y todo junto queda de la siguiente forma:

from Tkinter import * # Importa el módulo 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 tamaño de la ventana

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

ejecutar(mostrar(v1))) # Primer botón b1.grid(row=1,column=1) # El botón es cargado b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:

ejecutar(ocultar(v1))) # Segundo botón b2.grid(row=1,column=2) # El botón 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 próximo archivo comentaremos algunos aspectos a tomar en cuenta a la

hora de mostrar y ocultar ventanas

RESUMEN INTERFAZ GRÁFICA

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

más de un lenguaje o solo haz programado en Scheme

una interfaz gráfica y piensas que todas se programan igual. Pues

presenta una dificultad.

En el último código que vimos:

Page 7: RESUMEN INTERFAZ GRÁFICA

from Tkinter import * # Importa el módulo

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

función

v0.config(bg="black") # Le da color al fondo

v0.geometry("500x500") # Cambia el tamaño de la ventana

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

ejecutar(mostrar(v1))) # Primer botón

b1.grid(row=1,column=1) # El botón es cargado

b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:

ejecutar(ocultar(v1))) # Segundo botón

b2.grid(row=1,column=2) # El botón 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 función llamada ejecutar

¿v0.after? ¡¿Qué es eso?!

¿Porqué el command de los botones tiene lambda dos puntos ejecutar y la

función 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 actúa 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 función:

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 tamaño

de la ventana.

En cuánto a las preguntas de más arriba. La función 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 función que

queremos ejecutar.

Por ejemplo abre una ventana, como se vió anteriormente.

Page 8: RESUMEN INTERFAZ GRÁFICA

Y para qué es el lambda? No estoy muy seguro pero es absolutamente

necesario usarlo, además lambda permite que un botón

ejecute dos eventos al mismo tiempo.

Ejemplo 7:

Por ejemplo si queremos mostrar una ventana y también imprimir hola,

sería de la siguiente forma:

from Tkinter import * # Importa el módulo

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 tamaño de la ventana

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

ejecutar(mostrar(v1)) or imprimir("hola")) # Primer botón

b1.grid(row=1,column=1) # El botón es cargado

b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:

ejecutar(ocultar(v1))) # Segundo botón

b2.grid(row=1,column=2) # El botón 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 botón ABRIR VENTANA V1, notarán que además de mostrar

la ventana, imprime el texto. Si quisieramos que el

botón hiciera tres cosas, sería de la siguiente forma:

from Tkinter import * # Importa el módulo

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 tamaño de la ventana

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

ejecutar(mostrar(v1)) or imprimir("hola") or imprimir("tercera

función")) # Primer botón

b1.grid(row=1,column=1) # El botón es cargado

b2=Button(v0,text="OCULTAR VENTANA V1",command=lambda:

ejecutar(ocultar(v1))) # Segundo botón

b2.grid(row=1,column=2) # El botón es cargado

Page 9: RESUMEN INTERFAZ GRÁFICA

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 función ejecutar, podemos

ejecutar varios eventos al mismo tiempo separados

por or.

Ejemplo 9:

Ahora, no sé si lo habrán notado, pero cuando cerramos la ventana, tira

error, pero cuando la ocultamos no nos da error. Yo

la solución que le encontré a esto, fue quitando la opción de cerrar

ventana, y colocando un botón salir en cada ventana.

Para realizar eso se hace lo siguiente:

from Tkinter import * # Importa el módulo

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

v1=Toplevel(v0) # Crea una ventana hija

v1.protocol("WM_DELETE_WINDOW", "onexit") # Elimina la opción 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 tamaño de la ventana

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

ejecutar(mostrar(v1)) or imprimir("hola") or imprimir("tercera

función")) # Primer botón

b1.grid(row=1,column=1) # El botón es cargado

b2=Button(v1,text="OCULTAR VENTANA V1",command=lambda:

ejecutar(ocultar(v1))) # Segundo botón

b2.grid(row=1,column=2) # El botón es cargado

b3=Button(v0,text="SALIR",command=lambda: ejecutar(ocultar(v1)))

b3.grid(row=1,column=2) # El botón 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 tamaño de una ventana). Con lo siguiente

se puede realizar:

from Tkinter import * # Importa el módulo

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

v1=Toplevel(v0) # Crea una ventana hija

v1.protocol("WM_DELETE_WINDOW", "onexit") # Elimina la opción de salir

para evitar el error

v0.resizable(0,0) # Evita que la ventana se pueda cambiar de tamaño

v1.resizable(0,0) # Evita que se le pueda cambiar de tamaño a la ventana

Page 10: RESUMEN INTERFAZ GRÁFICA

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 tamaño de la ventana

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

ejecutar(mostrar(v1)) or imprimir("hola") or imprimir("tercera

función")) # Primer botón

b1.grid(row=1,column=1) # El botón es cargado

b2=Button(v1,text="OCULTARME",command=lambda: ejecutar(ocultar(v1))) #

Segundo botón

b2.grid(row=1,column=2) # El botón es cargado

b3=Button(v0,text="OCULTAR VENTANA V1",command=lambda:

ejecutar(ocultar(v1)))

b3.grid(row=1,column=2) # El botón 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 deberían poder solucionar

algunas de estas irregularidades, entre otras más

Page 11: RESUMEN INTERFAZ GRÁFICA

que se podrían comentar más 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, cuál es el padre de un elemento, etcétera. Generalmente

cuando trabajamos con Tkinter, el elemento padre

es el primer argumento que recibe un objeto gráfico. El elemento Tk()

no tiene ningún padre. Si declaramos una variable

v0 = Tk()

Entonces v0 es un Tk(), que es la ventana principal, y entre paréntesis

no recibe ningún 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 botón en cada ventana. Lo que querría decir que uno de

los botones tiene como padre a la ventana Tk() y el

otro botón tiene como padre a la ventana del tipo Toplevel()

Ejemplo 11:

A continuación 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 APLICACIÓN",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 aplicación basta con

destruir el objeto de la ventana principal, llamado

Page 12: RESUMEN INTERFAZ GRÁFICA

v0. Así, cuando escribimos v0.destroy se destruye la ventana padre, y

entonces la aplicación termina.

Otras formas que podrían presentar conflictos, pero que también son

usadas, son v0.quit, y por supuesto, ocultar(v0) que

sería lo mismo que decir v0.withdraw(). Sin embargo con el withdraw()

solo la oculta no cerraría la aplicación.

También se puede usar en el command del botón lambda: exit()

Ahora introduzcamos más controles, como por ejemplo los Labels

8. QUE EL PROGRAMA TAMBIÉN 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 habíamos hablado de las ventanas Tk y Toplevel y de los controles

Label, Button, Listbox, Scrollbar Entry, Text, Frame,

Canvas, entre otros.

Pero, cómo se usan? Cómo se introduce un elemento en un Listbox? Cómo

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

Page 13: RESUMEN INTERFAZ GRÁFICA

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

Page 14: RESUMEN INTERFAZ GRÁFICA

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 algún texto"

b1=Button(v0,text="Insertar en

Listbox",command=insertar_en_listbox).pack()

v0.mainloop()

Si insertan muchos elementos se darán cuenta de que, en este tipo de

controles normalmente aparece una Scrollbar

automáticamente. 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() != "":

Page 15: RESUMEN INTERFAZ GRÁFICA

list1.insert(END,mivalor.get())

else: print "Por favor esciba algún texto"

b1=Button(v0,text="Insertar en

Listbox",command=insertar_en_listbox).pack()

v0.mainloop()

De esta forma al tener más elementos de los que permite visualizar,

coloca automáticamente un Scrollbar.

Cabe destacar que en Scheme, el control Listbox traía su propio

Scrollbar. Al menos eso recuerdo...

RESUMEN INTERFAZ GRÁFICA

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 estaríamos repitiendo mucho código y

saturando nuestro proyecto, mientras que una función resume muchas

instrucciones y lo hace más comprensible.

Esta es una solución 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)

Page 16: RESUMEN INTERFAZ GRÁFICA

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 cómo 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)

Page 17: RESUMEN INTERFAZ GRÁFICA

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

La función imprimir_en_label es la que llama la atención en este caso,

es una función que se llama así misma con el evento

objeto.after(tiempo(milisegundos),función).

Cada 100 milisegundos verifica cuál elemento está seleccionado.

Listbox.curselection() retorna la posición seleccionada, y

Listbox.get(posición) devuelve el texto seleccionado. Otra forma

de realizar esto es con una implementación de objeto.bind

Ejemplo 18:

Para este ejemplo lo que haremos es una función para limpiar un control

del tipo Listbox. La función elimina todos los

elementos del listbox cuando uno le da click al botón 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()

Page 18: RESUMEN INTERFAZ GRÁFICA

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','Marta','El

ias']

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 más que se pueden encontrar en documentación sobre

Tkinter por la web. Veamos el ejemplo de arriba

más personalizado

from Tkinter import *

Page 19: RESUMEN INTERFAZ GRÁFICA

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','Marta','El

ias']

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

Page 20: RESUMEN INTERFAZ GRÁFICA

Existen otros elementos personalizables como

width: El ancho

height: El alto

border: Tamaño de borde

En interfaces más avanzadas se puede configurar el nivel de opacidad,

logrando así el efecto de transparencia de las

ventanas más conocidas. Pero eso no es tan necesario mencionarlo

11. IMPRIMIENDO LA HORA CON TODO Y FECHA

Existe un módulo en Python llamado time. Utilizando la siguiente

implementación 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, podría conseguir imprimir más información, como los

nombres del mes, entre otras cosas.

En el siguiente ejemplo hay una implementación de cómo 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))

Page 21: RESUMEN INTERFAZ GRÁFICA

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

Además 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 modificándola directamente.

El ejemplo sirve incluso para crear efectos animaciones, y textos

cambiantes. Eso queda a imaginación del programador.

12. GUARDANDO Y ABRIENDO UN ARCHIVO CON TEXTO

Ahora vamos a hacer uso de varios módulos. Esta aplicación abre una

ventana con un control Text y un control Button.

Ejemplo 22:

El siguiente código guarda un archivo de texto en una ruta específicada.

Y luego, si cerramos el programa, cuando lo

volvemos a abrir, nos devuelve el texto que guardamos anteriormente

(Puedes cambiar el enlace si estás 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):

Page 22: RESUMEN INTERFAZ GRÁFICA

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 información en archivos de texto, siempre

y cuando sea string, lo guardará adecuadamente.

Cabe destacar que este pequeño programa tiene un código un tanto simple,

pero tiene algunos detalles interesantes. Por

ejemplo, no es igual utilizar controles Entry (una sola línea) que

controles Text (Varias líneas de texto)

Su información es diferente, sus métodos, y algunas cosas para leer y

escribir información en un control de tipo Text, es

diferente a la manipulación del objeto Entry. Además en este ejemplo

ni siquiera podemos ver toda la capacidad que tiene

el objeto Text. Es uno de los objetos más potentes que tiene la interfaz

Tkinter.

Page 23: RESUMEN INTERFAZ GRÁFICA

El segundo detalle a tomar en cuenta, es que, aunque parezca fácil, no

es para nosotros obvio a simple vista que hay algo

en este documento, lo que e conoce como codificación.

La codificación es para que no se nos caiga nuestra aplicación cuando

intentemos guardar en un archivo, caracteres tales

como tildes, eñes, y otros caracteres que se necesitan. Para ello

incluso se importa un módulo llamado codecs, y se

utiliza utf-8, que les recomiendo realicen una búsqueda en google y

revisen la información sobre la diferente codificación

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 módulo 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 módulo Pickle permite guardar las listas como estructuras de datos y

luego recuperarlas desde el archivo. Esto nos

permitiría guardar toda la información de una lista y recuperarla tal

cual.

Ejemplo 23:

En este ejemplo importamos el módulo 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 números del 1 al 7 en el

archivo datos.txt que se creará en la misma carpeta

donde está guardado el archivo.py donde se encuentra el código de

arriba, pero nosotros podemos cambiar la ruta, por

ejemplo 'C:\datos.txt'

RESUMEN INTERFAZ GRÁFICA

CUARTA PARTE

4 Noviembre del 2010

Page 24: RESUMEN INTERFAZ GRÁFICA

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

Page 25: RESUMEN INTERFAZ GRÁFICA

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í: http://i.imgur.com/qTKZv.gif Es una imágen que ya tiene el formato GIF correcto y no presentará

problemas a la hora de cargarlo.

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.

Page 26: RESUMEN INTERFAZ GRÁFICA

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

Page 27: RESUMEN INTERFAZ GRÁFICA

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:

Page 28: RESUMEN INTERFAZ GRÁFICA

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

Page 29: RESUMEN INTERFAZ GRÁFICA

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:

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:

Page 30: RESUMEN INTERFAZ GRÁFICA

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

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.

Page 31: RESUMEN INTERFAZ GRÁFICA

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

Page 32: RESUMEN INTERFAZ GRÁFICA

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

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

Page 33: RESUMEN INTERFAZ GRÁFICA

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

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

Page 34: RESUMEN INTERFAZ GRÁFICA
Page 35: RESUMEN INTERFAZ GRÁFICA

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)

Page 36: RESUMEN INTERFAZ GRÁFICA

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

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,

Page 37: RESUMEN INTERFAZ GRÁFICA

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

RESUMEN INTERFAZ GRÁFICA

V PARTE

5 Noviembre del 2010

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

21. EJEMPLO DE INTERFAZ GRÁFICA 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 líneas seguidas gana el juego. Se utilizan algunos de los elementos explicados en los tutoriales

anteriores:

- Uso del IDE PyScripter - Módulo Tkinter - Evento objetografico.after(milisegundos,función) - Método objetografico.grid(row=i,column=j) - Método lambda para asignar más de un evento a un botón - Control de Flujo - Uso de ventana.withdraw() para ocultar ventanas - Uso de ventana.deiconify() para mostrar ventanas - Uso de listas para almacenar información de manera temporal - Abastracción y aprovechamiento del lenguaje para declarar variables

por medio de tuplas () - Uso de la codificación utf-8 para evitar problemas con caracteres

tales como tildes, eñes, entre otros - Propiedades y atributos de las ventanas como resizable para evitar que

se pueda redimencionar, o title para colocar título a esta - Uso de font para cambiar el tamaño de la letra de un control de tipo

Label

Ejemplo 33

Page 38: RESUMEN INTERFAZ GRÁFICA

Para la elaboración de este proyecto se

tomaron en cuenta aspectos de movimientos.

Si un espacio del gato ya fue usado no se puede

volver a usar. Si todos los espacios del gato están llenos

y nadie hizo un tres en linea se termina el

juego.

Si hay un tres en línea se avisa cuál

jugador en específico ganó la partida y se

reinician las casillas, así como la lista donde se guarda

la información. La lista contiene 9 ceros

que corresponden a cada casilla. Si juega el

jugador 1, el espacio en la lista donde jugó

se transforma en un 1 o en un 2, dependiendo

del turno del jugador. La primera vez el jugador que inicia es el

azul. La segunda vez, inicia el jugador que

haya ganado la partida anterior, si ninguno

ganó, entonces el turno es para el jugador

que hizo la penúltima jugada en el juego anterior.

Los jugadores hacen click en cada casilla,

transformando el color de esta para

identificarle.

# -*- 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))

Page 39: RESUMEN INTERFAZ GRÁFICA

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)

Page 40: RESUMEN INTERFAZ GRÁFICA

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 posición" 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 GRÁFICA

VI PARTE

5 Noviembre del 2010

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

22. HACER QUE DOS LISTAS INTERACTÚEN

Supongamos que necesitamos que dos listas interactúen 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.

Además 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]

Page 41: RESUMEN INTERFAZ GRÁFICA

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 María"]

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 posición en la que se encuentra el

elemento dentro del listbox. La posición inicial es

cero.

Page 42: RESUMEN INTERFAZ GRÁFICA

controlistbox.get(número) : Recibe un número y devuelve un string con

el elemento que se encuentra en esa posición.

Y por lo tanto, controlistbox.curselection(controlistbox.get(número))

retorna el elemento que estamos clickeando en ese

momento. Si llamamos con ventana.after(tiempo,función) 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,FUNCIÓN)

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 imprimirán.

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 más rápido. Cuando llega al punto máximo

de velocidad, entonces comienza a retroceder hasta

llegar al 0 Km/h.

¿Con qué propósito? Para comprender de mejor manera como funciona el

evento ventana.after().

Para este ejemplo imprimiremos en cónsola y además 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

Page 43: RESUMEN INTERFAZ GRÁFICA

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,función) ha sido utilizada a lo largo de

este tutorial y sirve para multitud de eventos

aunque no es el más 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 estén acomodados de acuerdo a la

manera en la que nosotros queremos que estén. 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 módulo de

la interfaz que nos permita acomodar las cosas con algo más que paneles.

En Python por suerte tenemos el método grid, y

este nos permite acomodar las cosas a nuestro antojo.

Ejemplo 36

Si dibujamos una interfaz, por ejemplo:

Page 44: RESUMEN INTERFAZ GRÁFICA

Queremos esta estructura, donde cada cajita es un botón. 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:

Page 45: RESUMEN INTERFAZ GRÁFICA

Se puede hacer fácilmente 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)

Page 46: RESUMEN INTERFAZ GRÁFICA

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="Teléfono: ").grid(row=3,column=0,sticky=W)

Entry(v0).grid(row=3,column=2)

Label(v0,text="Profesión: ").grid(row=4,column=0,sticky=W)

Entry(v0).grid(row=4,column=2)

Label(v0,text="Cédula: ").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,columnspan=4

)

v0.mainloop()

25. COMPRENDIENDO LOS CONTROLES COMO OBJETOS

Aún 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.

Page 47: RESUMEN INTERFAZ GRÁFICA

Ejemplo 39

Por ejemplo podemos crear una función, que al introducirle un número,

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 función (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

Page 48: RESUMEN INTERFAZ GRÁFICA

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 GRÁFICA

VII PARTE

5 Noviembre del 2010

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

Page 49: RESUMEN INTERFAZ GRÁFICA

30. wxPython, Otro módulo para interfaces

gráficas con Python

Bueno, parece que han habido muchas cosas qué aprender sobre Tkinter.

Suponiendo que Tkinter tiene algún rival podría decirse que sería

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 cuántos ejemplos más para Tkinter.

Saltamos entonces al apartado 30 de este tutorial de

interfaces. Para los que están muy dispuestos a sacarle el máximo

provecho a este curso, no solo vamos a ver un módulo de

interfaces gráficas, si no que vamos a entrar ahora con otro, el

wxPython.

WxPython NO VIENE CON EL PYTHON, hay que bajárselo. Hay que instalarlo.

Por eso preferí realizar la interfaz con Tkinter y

toda la documentación posible.

Y muchos se preguntarán ¿Para qué bajarse otro módulo si ya Python tiene

el Tkinter? Bueno, pues, primero porque es

interesante comparar ambos, y segundo, porque las ventajas que tiene

wxPython sobre Tkinter, podrían ser interesantes y

nos podrían 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

página:

http://wxpython.org/

¿Que vamos a aprender? Vamos a aprender que se puede programar una

interfaz gráfica de dos maneras distintas, también,

vamos a saber cómo se programa una interfaz con wxPython.

Una vez que encuentren la forma de instalarlo, entonces podemos comenzar.

31. Una ventana en wxPython

Cómo se abre una ventana en wxPython ejemplo sencillo:

from wx import *

v0 = PySimpleApp() # Elemento de aplicación

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:

Page 50: RESUMEN INTERFAZ GRÁFICA

- 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 título 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 mayúsculas (Debe ser en mayúsculas)

Sería 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 cómo hacemos para:

- Evitar que se redimencione la ventana

- Quitar bordes y botones de cerrar, minimizar, maximizar, barra de

títulos, a la ventana

- Crear menúes 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 tamaño se hace de la siguiente forma

from wx import *

v0 = PySimpleApp() # Elemento de aplicación

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 fácilmente,

además usamos size para darle el tamaño 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 aplicación

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 tamaño

from wx import *

Page 51: RESUMEN INTERFAZ GRÁFICA

v0 = PySimpleApp() # Elemento de aplicación

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

Además le hemos cambiado el color de fondo. Se empieza a notar que

algunas cosas son más sencillas y manejables desde wxPython que desde

Tkinter. A estas alturas debería 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 opción interesantísima de

Python. Con esta opción podemos mostrar imágenes online e incluso páginas

web completas, en una ventana de Python. Por ejemplo, si quisiéramos

Page 52: RESUMEN INTERFAZ GRÁFICA

mostar en la ventana que creamos arriba, una imágen que está en internet,

una opción para realizarlo sería la siguiente:

from wx import *

v0 = PySimpleApp() # Elemento de aplicación

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

Page 53: RESUMEN INTERFAZ GRÁFICA

La imágen es de un gato al que le brillan los ojos. Dicha imágen tiene

una secuencia que se reproduce una y otra vez, lo que se conoce como una

imágen de un GIF ANIMADO.

Otra forma de lograrlo sería la siguiente:

from wx import *

v0 = PySimpleApp() # Elemento de aplicación

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 página web entonces el código sería el

siguiente:

from wx import *

v0 = PySimpleApp() # Elemento de aplicación

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

Page 54: RESUMEN INTERFAZ GRÁFICA

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

muchas páginas 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 imágenes animadas y otras cosas más. Así que si se tiene

un poco de creatividad, se sabe HTML, y Python, se tiene asegurado algo

bastante llamativo.

Además, 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

métodos para ordenar los elementos tales como:

- Frames

- objeto.pack

- objeto.grid

En wxPython, podemos darle la posición 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 característica, se logra un acabado exacto. En muchos de los casos

resulta mejor poder dar la posición a los elementos.

Esto no quiere decir que en wxPython no exista grid ni frames. Al

contrario, sería muy engorroso ordenar elementos del tipo matriz, con

coordena

Page 55: RESUMEN INTERFAZ GRÁFICA