Lección 11 · 11 de 20
La barra de estado · tkinter
Añada una barra de estado a una ventana de tkinter: un marco abajo con etiquetas hundidas que se actualizan desde el código.

La barra de estado es un tk.Frame hundido (relief="sunken") pegado abajo con pack(side="bottom", fill="x"). Se empaqueta antes que el texto: así, aunque la ventana se encoja, cede espacio el editor y la barra no desaparece.
Dentro hay una etiqueta de mensajes que ocupa el sitio libre (fill="x", expand=True) y tres casillas de ancho fijo, también hundidas: posición, palabras y codificación. Se guardan en el diccionario cells para cambiarlas por su nombre.
update() lee el editor y escribe la barra: index("insert") devuelve la posición del cursor como "línea.columna" (la columna empieza en 0, por eso se suma 1) y get("1.0", "end").split() cuenta las palabras. Se llama tras cada tecla (<KeyRelease>), tras cada clic y una vez al empezar, con el cursor puesto con mark_set después de «Bread,».
Los mensajes de paso se escriben con config(text=...) y se quitan con after: «Opened notes.txt» vuelve a «Ready» a los 4 segundos.
En DMarlon Studio es la Barra de estado de la paleta: el estudio la genera como una etiqueta hundida pegada al borde de abajo, con un icono opcional, y su texto se cambia desde el código con configure(text=...).
Código · main.py
import tkinter as tkroot = tk.Tk()root.title("Notes")root.geometry("520x260")# The status bar: a Frame docked at the bottom with sunken labels inside.bar = tk.Frame(root, bd=1, relief="sunken")bar.pack(side="bottom", fill="x") # packed first, so it always keeps its placemessage = tk.Label(bar, text="Ready", anchor="w", padx=6)message.pack(side="left", fill="x", expand=True)cells = {}for name, width in (("position", 14), ("words", 10), ("encoding", 7)): cells[name] = tk.Label(bar, width=width, relief="sunken", bd=1) cells[name].pack(side="left")cells["encoding"].config(text="UTF-8")text = tk.Text(root, wrap="word", bg="white", fg="black", font=("Helvetica", 14), padx=10, pady=8, insertbackground="black", highlightthickness=0)text.pack(fill="both", expand=True)text.insert("1.0", "Shopping list\n\nBread, milk and eggs.\nCall Ana about the trip.")def update(event=None): # read the editor and write the bar line, col = text.index("insert").split(".") cells["position"].config(text=f"Ln {line}, Col {int(col) + 1}") cells["words"].config(text=f"{len(text.get('1.0', 'end').split())} words")text.bind("<KeyRelease>", update) # after each key…text.bind("<ButtonRelease-1>", update) # …and each click in the texttext.mark_set("insert", "3.6") # the cursor after "Bread,"update()message.config(text="Opened notes.txt") # a message from code…root.after(4000, lambda: message.config(text="Ready")) # …that goes after 4 sroot.mainloop()Para recordar
- Empaquete la barra primero, con
side="bottom". relief="sunken"le da el aspecto hundido.- Actualícela desde los eventos con
config(text=...). afterquita los mensajes de paso.
Ejercicio
Añada a la barra una casilla con el número de caracteres y haga que el mensaje cambie a «Modified» en cuanto se escriba algo.