Beruflich Dokumente
Kultur Dokumente
1
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
1. Definición
Una Interfaz Gráfica de Usuario (Graphical User Interface, GUI) es un programa que permite a los
usuarios interactuar de forma sencilla mediante un entorno visual conformado de imágenes y objetos
gráficos, haciendo que el uso del programa sea amigable. A lo largo del documento se le llamará
interfaz gráfica.
2. Metodología de diseño
El diseño de interfaces gráficas se encuentra alineado al diseño de software en general. La siguiente
metodología puede ser aplicada para el diseño de interfaces gráficas.
Ejemplo:
El usuario requiere un programa que permita convertir grados Celsius (°C) a grados Fahrenheit (°F) y
viceversa. El usuario solamente desea ingresar la temperatura en la escala original, presionar un botón
para aplicar el cambio y obtener la temperatura en la escala opuesta. Las temperaturas resultado solo
requieren a lo mucho un decimal de precisión.
Ejemplo:
De la definición de requisitos, se pueden plantear los puntos requeridos en esta etapa. Enfocándonos
particularmente en el bosquejo de la GUI, se presentan tres opciones que no son las únicas posibles.
2
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
Se recomienda definir al menos dos opciones de interfaz para dar al usuario libertad en a elección, y a
lo mucho tres opciones para evitar perder el foco del resultado deseado.
Ejemplo:
En base a los bosquejos planteados, se realiza un prototipo que será usado en las pruebas. Entre las
pruebas de funcionamiento, se tendrá que validar que los valores convertidos coincidan con valores de
referencia precalculados. En las pruebas de usuario, se debe ver que el llenado de datos no sea claro y
proponer mejoras en la interfaz en caso queden ambigüedades, como agregar mensajes adicionales en
pantalla o un botón de instrucciones; el hecho de tener más de una opción permite que los usuarios
escojan cual es la que más se adecua a su trabajo.
Ejemplo:
Es posible que el programa planteado sea un componente de un programa más amplio, por lo que se
podría requerir que, una vez aplicada la conversión, el resultado de ésta sea copiado directamente al
portapapeles o escrito en un cuadro de texto de otra ventana; dependerá bastante del resto de
componentes involucrados en la solución completa.
Ejemplo:
Considerando que se quiera que el programa también permita trabajar con conversiones a Kelvin (K),
se tendría que agregar botones o replantear la interfaz presentada de forma que cumpla con las
nuevas especificaciones. Normalmente se plantearía este punto como un nuevo desarrollo
3
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
independiente, pero podría existir un contrato de mejora continua que incluya las modificaciones al
programa actual.
Para el desarrollo de GUIs utilizaremos la librería tkinter ya viene integrada con Python en las versiones
actuales; todos los conceptos aplicados con esta librería son compatibles con el resto de librerías.
4. Librería tkinter
En una librería que permite trabajar de forma orientada a objetos sobre Tcl/Tk con soporte
multiplataforma (Windows, Linux, MacOSX).
4
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
5. Componentes
Se muestra los componentes más comunes de la librería tkinter; sin embargo, componentes con
funcionalidades similares pueden ser encontrados en otras librerías. Además, se presenta las clases
que administran el comportamiento de estos.
Para crear una ventana, utilizamos el constructor de la clase Tk de la librería. Una vez creada y
habiendo terminado la definición de todos sus componentes, el programa debe entrar a un bucle
propio donde se toman todas las interacciones que se tiene con la ventana, esto se realiza con la
función mainloop.
# -*- coding: utf-8 -*-
import tkinter as tk
import tkinter.ttk as ttk
ventana = tk.Tk()
# Aquí se agrega el resto
# de definiciones de widgets
ventana.mainloop()
ventana = tk.Tk()
ventana.geometry("300x200")
ventana.title("Ventana raíz")
# Aquí se agrega el resto
# de definiciones de widgets
ventana.mainloop()
5
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
ventana = tk.Tk()
ventana.geometry("300x200")
ventana.title("Ventana raiz")
# Aquí se agrega el resto
# de definiciones de widgets
ventanaAdicional = tk.Toplevel()
ventanaAdicional.geometry("300x100")
ventanaAdicional.title("Ventana adicional")
# Aquí se agrega el resto
# de definiciones de widgets
# de la ventana adicional
ventana.mainloop()
5.3.1. Información
messagebox.showinfo(
message="Se termino de cargar datos.",
title="Informacion")
5.3.2. Advertencia
6
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
messagebox.showwarning(
message="Tiene 5 días para cambiar su contraseña.",
title="Advertencia")
5.3.3. Error
messagebox.showerror(
message="No se pudo exportar datos.",
title="Error")
5.3.4. Si o no
print(messagebox.askyesno(
message="¿Desea continuar?",
title="Título"))
print(messagebox.askokcancel(
message="¿Desea continuar?",
title="Título"))
print(messagebox.askretrycancel(
message="¿Desea reintentar?",
title="Título"))
print(messagebox.askyesnocancel(
message="¿Desea continuar?",
title="Título"))
7
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
5.4. Widgets
Un widget es cada uno de los componentes visuales que conforman la interfaz gráfica; estos permiten
interactuar de diferentes formas con el programa.
Los widgets mostrados a continuación son algunos de los más comunes y suelen estar implementados
en la mayoría de librerías para desarrollo de interfaces gráficas.
5.4.1. Marco – Frame
Es un widget que se presenta como un rectángulo y que suele usarse para agrupar widgets.
ventana = tk.Tk()
ventana.geometry("180x180")
frame = tk.Frame(ventana, bd=1,
relief=tk.SUNKEN, width=160,
height = 130, padx = 10, pady = 10)
frame.pack(anchor = "center")
ventana.mainloop()
def aceptar():
print("Aceptar")
ventana = tk.Tk()
ventana.geometry("180x100")
button = ttk.Button(ventana, text = "Aceptar", command = aceptar)
button.pack(anchor = "center")
ventana.mainloop()
5.4.3. Etiqueta de texto – Label
Widget que permite mostrar texto no modificable por el usuario. Suele utilizarse para describir otros
widgets.
8
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
ventana = tk.Tk()
ventana.geometry("180x100")
label = ttk.Label(ventana, text = "Hola mundo")
label.pack(anchor = "center")
ventana.mainloop()
El valor de una etiqueta puede variar si se le vincula con una variable de la librería tkinter de tipo
StringVar.
def cambiarLabel():
vValor.set("Hasta luego")
ventana = tk.Tk()
ventana.geometry("180x100")
vValor = tk.StringVar()
vValor.set("Hola mundo")
label = ttk.Label(ventana, textvariable=vValor)
label.pack(anchor = "center")
button = ttk.Button(
ventana, text="Cambiar Label",
command=cambiarLabel)
button.pack(anchor = "center")
ventana.mainloop()
def verEstado():
print(vValor.get())
9
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
ventana = tk.Tk()
ventana.geometry("180x100")
vValor = tk.IntVar()
checkbutton = ttk.Checkbutton(
ventana,
text = "Habilitar envio de datos",
variable = vValor)
checkbutton.pack(anchor = "center")
button = ttk.Button(
ventana, text="Ver estado",
command=verEstado)
button.pack(anchor = "center")
ventana.mainloop()
def mostrarEleccion():
print(vRadiobutton.get())
ventana = tk.Tk()
ventana.geometry("180x150")
label = ttk.Label(ventana, text = "Escoja tipo de carne:")
opciones = ["Pollo", "Pescado",
"Res", "Sin carne"]
vRadiobutton = tk.StringVar()
radiobuttons = []
for i in range(len(opciones)):
radiobuttons.append(
ttk.Radiobutton(
ventana, text = opciones[i],
variable = vRadiobutton, value = i)
)
button = ttk.Button(
ventana, text = "Mostrar Elección",
command = mostrarEleccion)
label.grid()
for radiobutton in radiobuttons:
radiobutton.grid(sticky=tk.NW)
button.grid()
ventana.mainloop()
10
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
def mostrarTexto():
print(vEntry.get())
ventana = tk.Tk()
ventana.geometry("180x100")
vEntry = tk.StringVar()
entry = ttk.Entry(ventana, textvariable = vEntry)
button = ttk.Button(
ventana, text = "Mostrar Texto",
command = mostrarTexto)
entry.pack(anchor = "center")
button.pack(anchor = "center")
ventana.mainloop()
def mostrarEleccion():
print(vCombobox.get())
ventana = tk.Tk()
ventana.geometry("180x100")
vCombobox = tk.StringVar()
combobox = ttk.Combobox(
ventana, textvariable = vCombobox,
values = ("Enero","Febrero","Marzo",
"Abril","Mayo","Junio",
11
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
"Julio","Agosto","Septiembre",
"Octubre","Noviembre","Diciembre")
)
button = ttk.Button(
ventana, text = "Mostrar Elección",
command = mostrarEleccion)
combobox.pack(anchor = "center")
button.pack(anchor = "center")
ventana.mainloop()
def mostrarEleccion():
if len(listbox.curselection()) > 0:
print(listbox.get(listbox.curselection()))
ventana = tk.Tk()
ventana.geometry("180x140")
listaVariables = tk.StringVar(
value=("Java","C++","Matlab","Python"))
listbox = tk.Listbox(
ventana, listvariable = listaVariables, height = 5)
listbox.pack(anchor = "center")
button = ttk.Button(
ventana, text = "Mostrar Elección",
command = mostrarEleccion)
button.pack(anchor = "center")
ventana.mainloop()
ventana = tk.Tk()
12
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
scrollbar = tk.Scrollbar(ventana)
listbox = tk.Listbox(ventana, yscrollcommand = scrollbar.set)
for numero in range(100):
listbox.insert(tk.END, "Linea número " + str(numero))
listbox.pack(side=tk.LEFT, fill=tk.BOTH)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
scrollbar.config(command = listbox.yview)
ventana.mainloop()
ventana = tk.Tk()
text = tk.Text(ventana, width = 20, height = 8)
text.insert(tk.INSERT, "Este es un texto que tiene una gran
extension")
text.insert(tk.END, "\nIncluso puede haber saltos dentro del texto")
text.pack(anchor = "center")
ventana.mainloop()
def aumentar10():
if vProgreso.get() + 10 < 100:
vProgreso.set(vProgreso.get() + 10)
else:
vProgreso.set(0)
ventana = tk.Tk()
ventana.geometry("180x100")
vProgreso = tk.IntVar()
progressbar = ttk.Progressbar(
ventana, variable=vProgreso)
label = ttk.Label(ventana, textvariable=vProgreso)
13
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
button = ttk.Button(
ventana, text="Avanzar 10%", command=aumentar10)
vProgreso.set(0)
progressbar.pack(anchor="center")
label.pack(anchor="center")
button.pack(anchor="center")
ventana.mainloop()
ventana = tk.Tk()
ventana.geometry("180x100")
vValor = tk.IntVar()
scale = ttk.Scale(ventana, variable=vValor, from_=0, to=100)
scale.pack(anchor="center")
label = ttk.Label(ventana, textvariable=vValor)
label.pack(anchor="center")
ventana.mainloop()
ventana = tk.Tk()
ventana.geometry("180x100")
spinbox = ttk.Spinbox(ventana, from_=0, to=10)
spinbox.pack(anchor="center")
ventana.mainloop()
14
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
ventana = tk.Tk()
ventana.geometry("180x100")
frame = ttk.Frame(ventana)
label1 = ttk.Label(frame, text="Texto 1")
label2 = ttk.Label(frame, text="Texto 2")
separator = ttk.Separator(frame, orient="vertical")
frame.pack(anchor="center")
label1.grid(column=0, row=0)
separator.grid(column=1, row=0, sticky=(tk.N,tk.S))
label2.grid(column=2, row=0)
ventana.mainloop()
ventana = tk.Tk()
ventana.geometry("180x100")
labelframe = ttk.Labelframe(ventana, text="Datos de usuario")
label1 = ttk.Label(labelframe, text="Nombre: Luis")
label2 = ttk.Label(labelframe, text="País: Perú")
labelframe.pack(anchor="center")
label1.grid(column=0, row=0, sticky=tk.W)
label2.grid(column=0, row=2, sticky=tk.W)
ventana.mainloop()
ventana = tk.Tk()
ventana.geometry("200x120")
notebook = ttk.Notebook(ventana)
label1 = ttk.Label(notebook, text="Perro\nGato\nRatón")
15
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
ventana = tk.Tk()
ventana.geometry("400x300")
canvas = tk.Canvas(width=400, height=300, bg='white')
canvas.pack(expand="yes", fill="both")
canvas.create_polygon(200, 10,
380, 280,
10, 100,
380, 100,
10, 280,
fill='yellow',
outline='blue',
dash=(5, 3))
ventana.mainloop()
6. Ejemplo de uso
Teniendo en cuenta el bosquejo de interfaz gráfica:
def celsiusAFahrenheit():
celsius = vCelsius.get()
fahrenheit = 1.8*celsius + 32
fahrenheit = round(fahrenheit + 0,1)
vFahrenheit.set(fahrenheit)
16
MT104 – 2019-2 Interfaces Gráficas de Usuario (GUI)
def fahrenheitACelsius():
fahrenheit = vFahrenheit.get()
celsius = (fahrenheit - 32)/1.8
celsius = round(celsius + 0,1)
vCelsius.set(celsius)
ventana = tk.Tk()
vCelsius = tk.DoubleVar()
vFahrenheit = tk.DoubleVar()
ventana.mainloop()
17