¿Por qué se desaconsejan múltiples instancias de Tk?

Resuelto Nae asked hace 6 años • 4 respuestas

Considere el siguiente ejemplo:

import tkinter as tk

root = tk.Tk()
root.title("root")

other_window = tk.Tk()
other_window.title("other_window")

root.mainloop()

y también vea el siguiente ejemplo que crea instancias Tkconsecutivas en lugar de a la vez, por lo que hay exactamente una instancia Tken un momento dado:

import tkinter as tk

def create_window(window_to_be_closed=None):
    if window_to_be_closed:
        window_to_be_closed.destroy()
    window = tk.Tk()
    tk.Button(window, text="Quit", command=lambda arg=window : create_window(arg)).pack()
    window.mainloop()

create_window()
  • ¿Por qué se considera malo tener múltiples casos deTk?
  • ¿Se considera el segundo fragmento un poco mejor o sufre las mismas condiciones que el primer código?
Nae avatar Jan 01 '18 03:01 Nae
Aceptado

¿Por qué se considera malo tener varias instancias de Tk?

Tkinter es solo un contenedor de Python alrededor de un intérprete Tcl integrado que importa la biblioteca Tk. Cuando crea una ventana raíz, crea una instancia de un intérprete Tcl.

Cada intérprete de Tcl es una zona de pruebas aislada. Un objeto en un entorno limitado no puede interactuar con objetos en otro. La manifestación más común de esto es que unStringVar creado en un intérprete no es visible en otro. Lo mismo ocurre con los widgets: no se pueden crear widgets en un intérprete que tenga como widget principal en otro intérprete. Las imágenes son un tercer caso: las imágenes creadas en uno no se pueden utilizar en otro.

Desde un punto de vista técnico, no hay ninguna razón por la que no puedas tener dos instancias Tkal mismo tiempo. La recomendación en contra se debe a que rara vez existe una necesidad real de tener dos o más intérpretes Tcl distintos, y causa problemas que son difíciles de comprender para los principiantes.

¿Se considera el segundo fragmento un poco mejor o sufre las mismas condiciones que el primer código?

Es imposible decir si el segundo ejemplo de la pregunta es mejor o no sin saber lo que estás tratando de lograr. Probablemente no sea mejor ya que, nuevamente, rara vez hay un momento en el que realmente necesites dos instancias.

La mejor solución el 99,9% de las veces es crear exactamente una instancia que Tkutilice durante la vida de su programa. Si necesita una segunda ventana o una posterior, cree instancias de Toplevel. En pocas palabras, así es como se diseñaron tkinter y el intérprete Tcl/Tk subyacente.

Bryan Oakley avatar Dec 31 '2017 20:12 Bryan Oakley

No estoy de acuerdo con que la tkintercomunidad desaconseje el uso de ventanas múltiples tk.Tk. Puedes tener varias tk.Tkventanas. Usar múltiples instancias de tk.Tkes la única forma de crear ventanas que sean verdaderamente independientes entre sí. El único error que comete la mayoría de las personas al crear varias tk.Tkventanas es que se olvidan de pasarlas master=...al crear PhotoImages/ StringVars/ IntVars/...

Por ejemplo, mira este código:

import tkinter as tk

root = tk.Tk()
root2 = tk.Tk()

variable = tk.StringVar() # Add `master=root2` to fix the problem
entry = tk.Entry(root2, textvariable=variable)
entry.bind("<Return>", lambda e: print(repr(variable.get())))
entry.pack()

root.mainloop()

El código anterior no funciona. master=root2Si lo agrega tk.StringVar(), funcionará perfectamente bien. Esto se debe a que tkinteralmacena la primera instancia tk.Tk()de tk._default_root. Luego, si no ingresa master=..., se asumirá que deseaba abrir la ventana tk._default_root.


Otra cosa que la gente se equivoca es cuántas veces se debe .mainloop()llamar. Maneja eventos de todas tk.Tklas ventanas que están activas, por lo que solo necesitas una .mainloop().

Para las personas que no están de acuerdo, me interesaría un ejemplo de dónde un problema real es causado por las múltiples tk.Tkventanas.

TheLizzard avatar Sep 05 '2021 09:09 TheLizzard

La mejor referencia que he encontrado hasta ahora es la sección Aplicación de Windows del tkinterbook :

En los ejemplos sencillos que hemos usado hasta ahora, sólo hay una ventana en la pantalla; la ventana raíz. Esto se crea automáticamente cuando llamas al constructor Tk .

y

Si necesita crear ventanas adicionales, puede utilizar el widget Toplevel . Simplemente crea una nueva ventana en la pantalla, una ventana que se ve y se comporta de forma muy parecida a la ventana raíz original.

Mi opinión es que una Tkinstancia crea un Toplevelwidget, además de cosas como mainloop, de las cuales debería haber solo una.

Roland Smith avatar Dec 31 '2017 20:12 Roland Smith