20. Interfaces gráficas - manuelmarinduque/Apuntes_Python_3 GitHub Wiki

Creación de interfaces gráficas de usuario con tkinter

Tomado de Interfaces gráficas I. Vídeo 42 Documentación oficial

Una interface gráfica o GUI está conformada por un conjunto de elementos gráficos como ventanas, botones, menús, casillas de ingreso de texto y demás elementos. Su utilidad es servir de intermediario para la interacción entre el usuario y el programa, mediante eventos que hace el usuario a los widgets del GUI.

A través de los eventos es como un usuario interactúa con el programa.

Estructura de ventana con tkinter

  1. Importar la librería tkinter y sus módulos.

  2. Crear la ventana raíz: Contenedor de frames. Es un objeto de la clase Tk(). Para que pueda estar en ejecución y a la escucha de eventos de usuario debe estar en bucle infinito, mediante el método mainloop().

Se le puede aplicar los siguientes atributos:

  • title(string): Da título a la ventana.

  • resizable(width, height): Aplica condiciones para redimensionar la ventana: 0 no redimensiona ancho o alto, 1 lo contrario.

  • iconbitmap(string ruta imagen): Cambia el ícono de la ventana. Se debe usar una imagen en formato .ico (buscar en internet programas de conversión).

  • Con el método config() se puede cambiar el color de fondo de la ventana: root.config(bg="color").

  • Con el método destroy() se cierra la ventana: root.destroy().

from tkinter import mainloop, Tk

# Crear la ventana raiz:
raiz = Tk()
raiz.title("Ventana de prueba")
# Redimensionar sólo a lo ancho:
raiz.resizable(1,0)
raiz.config(bg="green")

# El método mainlopp() debe estar siempre al final
raiz.mainloop()
  1. Crear el frame: Contenedor o lienzo de widgets. Es un objeto de la clase Frame(root, width, height), que recibe como parámetros principales: el nombre de la ventana raíz, el ancho y el alto (no en pixeles). La ventana raíz se adapta al tamaño de su contenido interno. Sólo se le da tamaño fijo al frame y no a la raíz. Luego empaquetar el frame, mediante el método pack(), para que pueda estar dentro de la ventana raíz:
from tkinter import Tk, Frame, Pack, mainloop

root = Tk()
miFrame = Frame(root, width=500, height=400)
miFrame.pack()

# Aquí van los widgets

root.mainloop()
  • Otra alternativa para dar tamaño al frame: config(width="?", height="?")

  • Métodos para dar estilos al frame:

    • config(bg="color"): Cambiar el color de fondo del frame.

    • Para adaptar el frame a la ventana raíz: miFrame.pack(fill="both", expand="True").

    • Ver vídeo 43, minuto 7:45, para posicionar el frame al empaquetarlo dentro de la ventana raíz; minuto 12:10 para aplicar estilos a los bordes del frame y la raíz.

  1. Dentro del frame se crean los elementos o widgets necesarios del programa para la interacción con el usuario. Luego posicionar el widget dentro del frame, mediante el método grid()), que se muestra más adelante. Si se empaqueta el widget, no se respeta el tamaño dado al frame.

Métodos y parámetros de los widgets

  • Label(contenedor, text, opciones): Objeto de la clase Label(). Se utiliza para mostrar texto o imágenes.

  • Entry(contenedor, textvariable, opciones): Objeto de la clase Entry(). Son recuadros que se utilizan para introducir texto. Si se trabaja con valores numéricos, se deben castear. El parámetro textvariable asocia el valor de una variable, objeto de de la clase StringVar(), a un Entry()

  • Text(contenedor, width, height, opciones): Objeto de la clase Text(). Son recuadros que se utilizan para introducir texto largo para comentarios, biografías y demás. Dar un ancho y un alto para ajustarlo.

  • Button(contenedor, text, opciones, command=función): Objeto de la clase Button(). Su utilidad es para que el usuario interactúe con el programa, al pulsar botones se ejecutan funciones del programa (eventos). En el parámetro command se especifica la función a ejecutar al pulsar el botón.

  • Scrollbar(contenedor, command): Objeto de la clase Scrollbar. En el parámetro command se especifica el widget a que pertenece seguido de un punto y el modo: yview o hview.

  • Radiobutton(contenedor, text, variable, value=x, command=función): Objeto de la clase Radiobutton(). Son botones de selección para preguntas de respuesta única. Cada widget tiene un valor x en formato entero, que se le asigna a la variable cuando se selecciona. Ver configuración

  • Checkbutton(contenedor, text, variable, onvalue=x, offvalue=y, command=función): Objeto de la clase Checkbutton(). Son botones de selección para preguntas de respuesta múltiple. El valor de la variable es x cuando se selecciona y y cuando no lo está. Ver configuración

  • Menu(contenedor, ): Objeto de la clase Menu(). Es una barra en la parte superior de la ventana con opciones de sub-menú. Ver configuración

  1. Al final de todo el código debe estar el método mainloop().

El parámetro contenedor se refiere al nombre del frame en el que está el widget, cada uno tiene una gran cantidad de opciones, que se pueden definir también con el método config (útil en funciones que manipulan los widgets):

Opción Descripción
Text Texto que a mostrar
Anchor Controla la posición del texto, si hay espacio suficiente para él (center por defecto)
Bg Color de fondo
Bitmap Mapa de bits que se mostrará como gráfico
Bd Grosor del borde (2px por defecto)
Font Recibe dos parámetros: tipo de fuente y tamaño
Fg Color de la fuente
Width Ancho de label en caracteres, no pixeles
Height Altura de label en caracteres, no pixeles
Image Recibe como parámetro un objeto de la clase PhotoImage(file), que contiene la ruta del arhivo en file
Justify left, right, o center
Show En un entry, muestra el texto en el caracter que se espefifique

Posicionar los widgets mediante el método grid()

Tomado de Interface gráfica IV. Vídeo 45

La estructura del frame se convierte en una grilla, la cual es una tabla conformada por filas y columnas, formando una cuadrícula. En cada celda de la tabla cuadriculada se ubica un widget. No se respeta el tamaño dado al frame, por lo que no es necesario definirse. La grilla es con el objetivo de un fácil y cómodo posicionamiento de los widgets al no depender del uso de coordenadas (método place(x,y)), que lo vuelve complejo:

nombreWidget.grid(row=?, column=?) Recibe dos parámetros principalmente: el número de la fila y el de la columna. Las coordenadas de las celdas se ubican como en una matriz de dos dimensiones, empezando por 0.

Otros parámetros del método grid():

  • sticky: Pone el texto de un widget, como label, a la derecha e:east, izquierda w:west, arriba _n_nort, abajo s:south y combinaciones de las anteriores.

  • padx/pady: Aplica un margen interno con valores en píxeles.

  • columnspan = celdas: Une horizontalmente la cantidad de celdas indicadas.

El widget entry para contraseña

Poner show="*" como parámetro dentro de Entry() al construir el widget.

Configurando el scrollbar

  • Posicionar el scrollbar en una columna del grid que únicamente lo contenga, al lado del widget al que pertenece.

  • Para que el tamaño del scrollbar se ajuste al alto o ancho del widget al que pertece y para que se pueda arrastrar el posicionador interno: Agregar parámetro sticky="nsew" dentro del método grid().

  • Para que el posicionador interno se ubique en la línea en la que se está escribiendo o está el cursor: Agregar parámetro yscrollcommand=nombreScroll.set) dentro del método config del widget al a que pertenece.

Ventanas emergentes

Ventanas modales para informar, avisar o permitir realizar tareas al usuario. Emergen cuando se ha dado click en alguna opción o botón del programa, por lo que se definen dentro de una función. Para usarlas, se necesita la clase messagebox de la librería tkinter.

Tipos de ventanas emergentes:

  • Información: messagebox.showInfo(titulo, cuerpo)

  • Advertencia: messagebox.showWarning(titulo, cuerpo)

  • Pregunta si/no: valor = messagebox.askquestion(titulo, cuerpo). La ventana tiene dos botones "si" y "no". Al pulsar sobre uno de esos devuelve un valor: "yes" o "no", con el que la función, donde se define la ventana, utiliza para aplicar funcionalidades a través de un condicional.

  • Pregunta aceptar/cancelar: valor = messagebox.askokcancel(titulo, cuerpo). La ventana tiene dos botones "aceptar" y "cancelar". Al pulsar sobre uno de esos devuelve un valor: "True" o "False".

  • Pregunta reintentar/cancelar: valor = messagebox.askretrycancel(titulo, cuerpo). La ventana tiene dos botones "reintentar" y "cancelar". Al pulsar sobre uno de esos devuelve un valor: "True" o "False". Útil para cuando el programa está en ejecución en segundo plano y no se puede cerrar de inmediato.

Ventana de "Abrir archivo"

Ver vídeo y fuente

Eventos al pulsar sobre botones

Al pulsar sobre un botón se ejecuta la función definida en su parámetro command. Si la función no recibe parámetros, no se escribe los paréntesis; en caso contrario, al recibir parámetros se debe definir luego de command una función lambda que retorne el llamado a la función, pasando dichos parámetros. Esto se hace para que al abrir el programa no se ejecuten tales funciones de inmediato.

Un Entry() debe tener asociado en su parámetro textvariable el valor de una variable, objeto de de la clase StringVar(). El valor de dicha variable lo define la función que ejecuta un botón. Para asignar un valor a tal variable se usa el método set() y para obtener su valor se usa el método get(). Si se usa POO, tales variables se definen en el constructor de la clase.

Ahora bien, al pulsar sobre un botón se ejecuta una función que manipula las variables StringVar, teniendo dos fines: el ingreso de datos (método get), escritos en un Entry(), a una BBDD; o para mostrar datos en un Entry() (método set).

Ejemplos

  • Ver archivo practica_entry.py para un ejemplo sencillo y App usuario para un ejemplo complejo usando POO.
⚠️ **GitHub.com Fallback** ⚠️