Iniciación a los estilos de Tkinter y los marcos

Iniciación a los estilos de Tkinter y los marcos

Iniciación a los estilos de Tkinter y los marcos -100 días de Python #15

En este décimo quinto día vamos a empezar a trabajar con los frames (marcos) de Tkinter y algunos estilos para darle una mayor personalización a los programas.

Lista de colores de Tkinter

Antes de empezar, te dejo una lista con los colores de Tkinter. Los vamos a utilizar de ahora en adelante en el curso.

Como dato curioso, esta misma tabla de colores que ves en la imagen, está creada con Tkinter. Son Label con colores y bordes colocados en grid.

Haz click derecho - Abrir imagen en una pestaña nueva para ver más grande.

colores tkinter

Los atributos o argumentos de los widgets

Los widgets de Tkinter cuentan con una serie de atributos preestablecidos en su código fuente, con los que puedes personalizarlos. La mayoría de widgets tienen muchos de estos atributos en común y podrán ser usados en muchos de ellos. Un ejemplo de esto, es el atributo background (fondo), el cual puede ser empleado para los Entry, los Button, la propia ventana, etc.

Empecemos por el siguiente código. Un Entry(), una función para enviar al pulsar el botón y un Button(). Nada que no esté explicado ya.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

#Entrada de datos
entrada = Entry(root).pack()

#Función para el botón
def enviar():
    Label(root, text="Se ha pulsado el botón").pack()

#Botón de enviar
boton = Button(root, text="Enviar", command=enviar).pack()

#Bucle de ejecución
root.mainloop()
entry tkinter

Empecemos a personalizar un poco este aspecto por defecto que llevan los tres widgets.

No obstante, antes de empezar. Mira el código del Entry(). En el __init__ mediante un comentario, aparecen todos los atributos que puede utilizar este widget. Lo mismo ocurre con el resto. Verás que algunos atributos se repiten en diferentes widgets, y que hay otros exclusivos solo para un widget en concreto.

Siempre que tengas dudas, puedes consultar esto con cualquier widget. Así sabrás fácilmente si tiene o no un atributo.

class entry tkinter

Argumentos de clave para los widgets

Todos estos argumentos o atributos, los vamos a pasar a los widgets entre sus paréntesis, como argumentos de clave. Sabrás ya, que los argumentos de clave se pueden posicionar en el orden que queramos, así que no importa si especificas primero el fondo o el color de letra de un widget.

Personalizar el widget Entry()

Empecemos personalizando un poco el Entry().

Color de fondo - Widget Entry()

Con el argumento "background" o "bg" (se puede poner de las dos formas), vas a especificar un color de fondo. De momento, elige uno de la gran tabla de colores que te he mostrado. Deberás especificar este valor con un string.

Tamaño de borde - Widget Entry()

Con "border", especificaremos el tamaño de borde en píxeles con un int.

Color de fuente - Widget Entry()

Utilizando "foreground", modificaremos el color de la letra. Esto, igual que el fondo, con un string.

Ancho - Widget Entry()

Finalmente, con "width" el tamaño en píxeles del elemento. También con un int.

No vamos a utilizar todos los posibles atributos en este día. Por el momento, es suficiente.

Por cierto, fíjate en la colocación de los elementos, cada argumento en cada fila. Este orden es opcional, pero así se ve organizado de forma más clara e intuitiva.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

#Entrada de datos
entrada = Entry(root, 
                background="springgreen",
                border=3,
                foreground="red",
                width=30
                ).pack()

#Función para el botón
def enviar():
    Label(root, text="Se ha pulsado el botón").pack()

#Botón de enviar
boton = Button(root, text="Enviar", command=enviar).pack()

#Bucle de ejecución
root.mainloop()

El resultado es este de aquí:

estilos tkinter

El siguiente paso es modificar el botón.

Personalizar el widget Button()

Para el botón, voy a utilizar los mismos estilos que con el Entry():

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

#Entrada de datos
entrada = Entry(root, 
                background="springgreen",
                border=3,
                foreground="red",
                width=30
                ).pack()

#Función para el botón
def enviar():
    Label(root, text="Se ha pulsado el botón").pack()

#Botón de enviar
boton = Button(root, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                foreground="gray98",
                border=3,
                width=25
                ).pack()

#Bucle de ejecución
root.mainloop()
modificar estilos de tkinter

Personalizar el widget Label()

Finalmente, vamos a modificar esa etiqueta que aparece al pulsar el botón.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("www.programacionfacil.org")

#Entrada de datos
entrada = Entry(root, 
                background="springgreen",
                border=3,
                foreground="red",
                width=30
                ).pack()

#Función para el botón
def enviar():
    Label(root, 
            text="Se ha pulsado el botón",
            background="skyblue",
            width=26
            ).pack()

#Botón de enviar
boton = Button(root, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                foreground="gray98",
                border=3,
                width=25
                ).pack()

#Bucle de ejecución
root.mainloop()

Iremos viendo más personalizaciones de estilos en otros capítulos. De momento, continuemos con el siguiente tema, los frames o marcos de Tkinter.

¿Qué son los frames de Tkinter?

Los frames de Tkinter, son marcos. Secciones en el programa. Serían el equivalente a los "div" en el desarrollo web. En Tkinter, los podemos obtener mediante el widget LabelFrame().

Crear un LabelFrame() en Tkinter

Crear un LabelFrame() es de lo más sencillo.

#Importaciones
from tkinter import *

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

#Se crea el marco
marco = LabelFrame(root, text="Marco en la ventana principal",)
marco.pack()

#Bucle de ejecución
root.mainloop()

Si ejecutas esto, va a salir una ventana vacía.

El marco aparece según el contenido que lleve dentro. Por lo tanto, vamos a añadirle el botón y la entrada de texto que hicimos anteriormente. Esta vez, los elementos, en lugar de poner que salgan en la ventana "root", le vamos a poner que salgan en el marco. Lo importante aquí, es que te fijes en el primer argumento del Entry(), del Label() y Button(). Estos ponen marco en lugar de root. Lo que le indica que los elementos deben ser mostrados sobre ese marco.

#Importaciones
from tkinter import *
import tkinter

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

marco = LabelFrame(root, text="Marco en la ventana principal",)
marco.pack()

#Entrada de datos
entrada = Entry(marco, 
                background="springgreen",
                border=5,
                foreground="red",
                width=30
                )
entrada.pack()
entrada.insert(0,"Escriba su nombre...")
entrada.bind("<Button-1>", lambda e: entrada.delete(0, tkinter.END))

#Función para el botón
def enviar():
    nombre = entrada.get() #Obtiene y almacena el texto de la entrada
    Label(marco, 
            text=f"Hola {nombre}",
            background="skyblue",
            width=27
            ).pack()
    entrada.delete(0, tkinter.END)
    entrada.insert(0,"Escriba su nombre...")   

#Botón de enviar
boton = Button(marco, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                border=3,
                width=26
                ).pack()

#Bucle de ejecución
root.mainloop()
Marcos tkinter

Añadir márgenes a los elementos de Tkinter

Como puedes ver en el programa que llevamos hasta ahora, el marco y los elementos están muy pegados al borde de la ventana y ni se visualizan del todo bien. Para solucionar esto, se pueden añadir unos márgenes a un widget. Estos márgenes se indican en píxeles en el propio pack() del elemento. Fíjate en la línea 11:

#Importaciones
from tkinter import *
import tkinter

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

marco = LabelFrame(root, text="Marco en la ventana principal",)
marco.pack(padx=15, pady=15)

#Entrada de datos
entrada = Entry(marco, 
                background="springgreen",
                border=5,
                foreground="red",
                width=30
                )
entrada.pack()
entrada.insert(0,"Escriba su nombre...")
entrada.bind("<Button-1>", lambda e: entrada.delete(0, tkinter.END))

#Función para el botón
def enviar():
    nombre = entrada.get() #Obtiene y almacena el texto de la entrada
    Label(marco, 
            text=f"Hola {nombre}",
            background="skyblue",
            width=27
            ).pack()
    entrada.delete(0, tkinter.END)
    entrada.insert(0,"Escriba su nombre...")   

#Botón de enviar
boton = Button(marco, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                border=3,
                width=26
                ).pack()

#Bucle de ejecución
root.mainloop()
margenes marco tkinter

Ahora, se ve con un mejor aspecto, sin embargo, el marco no deja margen entre su línea delimitadora y los widgets. Establezcamos unos márgenes entre el marco y el contenido. Esto lo hacemos esta vez en la propia declaración del marco. Fíjate en las líneas 12 y 13.

#Importaciones
from tkinter import *
import tkinter

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

marco = LabelFrame(root, 
                    text="Marco en la ventana principal",
                    padx=15,
                    pady=15)
                    
marco.pack(padx=15, pady=15)

#Entrada de datos
entrada = Entry(marco, 
                background="springgreen",
                border=5,
                foreground="red",
                width=30
                )
entrada.pack()
entrada.insert(0,"Escriba su nombre...")
entrada.bind("<Button-1>", lambda e: entrada.delete(0, tkinter.END))

#Función para el botón
def enviar():
    nombre = entrada.get() #Obtiene y almacena el texto de la entrada
    Label(marco, 
            text=f"Hola {nombre}",
            background="skyblue",
            width=27
            ).pack()
    entrada.delete(0, tkinter.END)
    entrada.insert(0,"Escriba su nombre...")   

#Botón de enviar
boton = Button(marco, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                border=3,
                width=26
                ).pack()

#Bucle de ejecución
root.mainloop()
padx pady tkinter labelframe

Múltiples marcos y marcos ocultos

Se pueden poner tantos marcos como queramos. En el siguiente código he especificado tres marcos y muestro el botón y el Entry() en dos de ellos.

#Importaciones
from tkinter import *
import tkinter

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

#Se crean los marcos
marco_1 = LabelFrame(root, text="Entrada de datos", padx=20, pady=20)
marco_1.pack(padx=15, pady=15) #Se le da unos márgenes en la ventana root

marco_2 = LabelFrame(root, text="Enviar", padx=20, pady=20)
marco_2.pack(padx=5, pady=15)

marco_3 = LabelFrame(root, text="Resultado", padx=20, pady=20)
marco_3.pack(padx=5, pady=15)

#Entrada de datos
entrada = Entry(marco_1, 
                background="springgreen",
                border=5,
                foreground="red",
                width=30
                )
entrada.pack()
entrada.insert(0,"Escriba su nombre...")
entrada.bind("<Button-1>", lambda e: entrada.delete(0, tkinter.END))

#Función para el botón
def enviar():
    nombre = entrada.get() #Obtiene y almacena el texto de la entrada
    Label(marco_3, 
            text=f"Hola {nombre}",
            background="skyblue",
            width=27
            ).pack()
    entrada.delete(0, tkinter.END)
    entrada.insert(0,"Escriba su nombre...")   

#Botón de enviar
boton = Button(marco_2, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                border=3,
                width=26
                ).pack()

#Bucle de ejecución
root.mainloop()
formulario con marcos en Tkinter

¿Dónde está el tercer marco?

Este es un marco inexistente hasta que se pulse el botón de "Enviar". Depende de que se ejecute el código de la función que es llamada al pulsarlo.

múltiples marcos tkinter

Posicionar marcos en el grid

Recuerda que tenemos la opción de usar grid(). Eso nos permitirá un mayor manejo de las posiciones de los elementos:

#Importaciones
from tkinter import *
import tkinter

#Creación de la ventana principal
root = Tk()
#Título de la ventana
root.title("Curso de Tkinter de Programación Fácil")

#Se crean los marcos
marco_1 = LabelFrame(root, text="Entrada de datos", padx=20, pady=20)
marco_1.grid(row=0, column=0,padx=15, pady=15) #Se le da unos márgenes en la ventana root

marco_2 = LabelFrame(root, text="Enviar", padx=20, pady=20)
marco_2.grid(row=1, column=0, padx=5, pady=15)

marco_3 = LabelFrame(root, text="Resultado", padx=20, pady=20)
marco_3.grid(row=0, column=1, padx=5, pady=15)

#Entrada de datos
entrada = Entry(marco_1, 
                background="springgreen",
                border=5,
                foreground="red",
                width=30
                )
entrada.pack()
entrada.insert(0,"Escriba su nombre...")
entrada.bind("<Button-1>", lambda e: entrada.delete(0, tkinter.END))

#Función para el botón
def enviar():
    nombre = entrada.get() #Obtiene y almacena el texto de la entrada
    Label(marco_3, 
            text=f"Hola {nombre}",
            background="skyblue",
            width=27
            ).pack()
    entrada.delete(0, tkinter.END)
    entrada.insert(0,"Escriba su nombre...")   

#Botón de enviar
boton = Button(marco_2, 
                text="Enviar", 
                command=enviar,
                background="deepskyblue",
                border=3,
                width=26
                ).pack()

#Bucle de ejecución
root.mainloop()
tkinter frames

Pasemos ya a la parte de ejercicios.

2 comentarios en «0»

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

curso Java Entrada anterior Las variables en Java
curso de Python Entrada siguiente Ejercicios de Python y Tkinter