¿Cómo abro otra ventana en tkinter?
Usa tk.Toplevel(). Crear un segundo tk.Tk() es lo único que hay que evitar: arranca un segundo intérprete de Tcl independiente, y a partir de ahí las dos ventanas se portan mal de formas difíciles de rastrear.
import tkinter as tk
root = tk.Tk()
def open_settings():
win = tk.Toplevel(root)
win.title("Ajustes")
win.geometry("300x200")
tk.Label(win, text="Aquí van los ajustes").pack(padx=20, pady=20)
tk.Button(root, text="Ajustes…", command=open_settings).pack()
root.mainloop() Mantenerla al frente, o hacerla modal
transient ata la ventana nueva a su ventana padre, de modo que se queda por encima y se minimiza con ella. grab_set va más lejos y bloquea la entrada en todas las demás ventanas hasta que esta se cierre: eso es lo que hace que un diálogo sea modal.
win.transient(root)
win.grab_set() # modal: nada más responde
win.wait_window() # y espera aquí hasta que se cierreEvitar que se abra dos veces
Si haces clic dos veces en el botón, acabas con dos ventanas. Guarda una referencia y compruébala antes de abrir otra: winfo_exists() te dice si la que recuerdas sigue en pantalla.
def open_settings():
if getattr(self, "settings", None) and self.settings.winfo_exists():
self.settings.lift()
return
self.settings = tk.Toplevel(self.root)Recuperar datos de la segunda ventana
Un Toplevel no es una función, así que no puede devolver un valor. O le das a la segunda ventana un callback al que entregar su resultado, o haces que escriba en un atributo que quien la abrió lee cuando wait_window() termina. Una clase por ventana simplifica los dos patrones, y por eso las aplicaciones tkinter de varias ventanas suelen acabar organizadas así.
Hacerlo sin buscarlo
Añade un formulario y se convierte en su propia clase de ventana, mientras la ventana principal recibe un ayudante open_<formulario>(). Así, una pantalla de inicio de sesión que lleva a la principal son dos pestañas del lienzo y no un problema de cableado. La capa de base de datos, cuando está activa, se pasa a cada ventana por ti.
Diseña la ventana visualmente y ve el código Python generado sobre la marcha.
Abrir el diseñador de tkinter →