Estate atento ya que en esta crónica encontrarás el resultado que buscas.
Solución:
La opción que prefiero* es heredar de la clase Tk. Creo que es la opción más razonable ya que la ventana es, en efecto, su aplicación. heredar de Frame
no tiene más sentido para mí que heredar de Button
o Canvas
o Label
. Dado que solo puede tener una sola raíz, tiene sentido que sea de eso de lo que herede.
También creo que hace que el código sea más legible si haces la importación como import Tkinter as tk
en vez de from Tkinter import *
. Todas sus llamadas luego mencionan explícitamente el tk
módulo. No recomiendo esto para todos los módulos, pero para mí tiene sentido con Tkinter.
Por ejemplo:
import Tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.label = tk.Label(text="Hello, world")
self.label.pack(padx=10, pady=10)
app = SampleApp()
app.mainloop()
* Nota: desde que originalmente escribí esta respuesta, he cambiado mi posición. Ahora prefiero heredar de Frame
en vez de Tk
. No hay una ventaja real de una forma u otra, es más una elección filosófica que cualquier otra cosa. Independientemente, creo que ya sea que heredes de Frame
o Tk
creo que cualquiera de las opciones es mejor que el primer ejemplo en el código que hereda de la nada.
La pequeña ventaja heredada de Frame
Cuenta con más de Tk
es en el caso de que desee que su aplicación admita varias ventanas idénticas. En ese caso, heredar de Frame
le permite crear la primera ventana como hija de root y ventanas adicionales como hijas de instancias de Toplevel
. Sin embargo, he visto muy pocos programas que alguna vez tengan la necesidad de hacer esto.
Para obtener más información sobre cómo creo que deberían estructurarse los programas Tkinter, consulte mi respuesta a la pregunta sobre la estructura del programa Python Tkinter.
Un marco generalmente se usa como maestro de geometría para otros widgets. Dado que una aplicación generalmente tiene numerosos widgets, a menudo querrá contenerlos todos en un marco, o al menos usar el marco para agregar algunos. borderwidth
acolchado u otra sutileza.
Muchos fragmentos de ejemplo que puede encontrar en la web no usan un marco porque solo quieren demostrar alguna característica en la menor cantidad de código.
Por lo tanto, use un Marco si lo necesita, de lo contrario, no lo haga.
Editar: Creo que la mejor manera de organizar una GUI se da en este tutorial de Tkinter:
simpleApp.py:
import Tkinter as tk
class SimpleApp(object):
def __init__(self, master, **kwargs):
title=kwargs.pop('title')
frame=tk.Frame(master, **kwargs)
frame.pack()
self.label = tk.Label(frame, text=title)
self.label.pack(padx=10,pady=10)
if __name__=='__main__':
root = tk.Tk()
app = SimpleApp(root,title='Hello, world')
root.mainloop()
Esto es principalmente como su primero ejemplo en eso SimpleApp
hereda de object
no Frame
. Creo que esto es mejor que subclasificar Frame
ya que no estamos anulando ninguna Frame
métodos. prefiero pensar en SimpleApp
como tener un Frame
en lugar de ser un Frame
.
Teniendo SimpleApp
subclase object
tiene una ventaja significativa sobre la subclasificación tk.Tk
sin embargo: hace que sea fácil de incrustar SimpleApp
en una aplicación más grande:
import simpleApp
import Tkinter as tk
class BigApp(object):
def __init__(self, master, **kwargs):
title=kwargs.pop('title')
frame=tk.Frame(master, **kwargs)
frame.pack()
self.simple = simpleApp.SimpleApp(frame,title=title)
frame.pack(padx=10, pady=10)
self.simple2 = simpleApp.SimpleApp(frame,title=title)
frame.pack()
if __name__=='__main__':
root = tk.Tk()
app = BigApp(root,title='Hello, world')
root.mainloop()
Por lo tanto, simpleApp.py puede ser un script independiente, así como un módulo importable. Si intentas esto con SimpleApp
heredando de tk.Tk
terminará con ventanas adicionales no deseadas.
Aquí puedes ver las comentarios y valoraciones de los lectores
Nos encantaría que puedieras comunicar este enunciado si lograste el éxito.