2012-04-03 36 views
12

Escriba una aplicación GUI con un botón etiquetado "Good-bye". Cuando se hace clic en Button, la ventana se cierra.¿Cómo cerrar una ventana de Tkinter presionando un botón?

Este es mi código hasta ahora, pero no está funcionando. ¿Alguien puede ayudarme con mi código?

from Tkinter import * 

window = Tk() 

def close_window (root): 
    root.destroy() 

frame = Frame(window) 
frame.pack() 
button = Button (frame, text = "Good-bye.", command = close_window) 
button.pack() 

window.mainloop() 
+4

Hey Matt. Gracias por tener una pregunta clara y un ejemplo de código limpio y simple para acompañar. ¿Podría también asegurarse de incluir el rastreo (bloqueo) en el futuro cuando su código "no funciona"? Eso también ayudará a las personas a descubrir casi instantáneamente qué parte de su código se ha roto. Obviamente, en este caso, la muestra del código es tan pequeña que es fácil de identificar, pero podría ayudarlo a obtener respuestas en el futuro en situaciones más difíciles. – jdi

+0

Para cualquiera que no vea el problema de inmediato, el error es 'TypeError: close_window() falta 1 argumento de posición requerido: 'root''. Esto significa que no se ha pasado ningún argumento a la devolución de llamada 'close_window', ya que nunca existe para las funciones' command = '. Las devoluciones de llamada de eventos enlazados reciben un argumento: el objeto de evento. –

Respuesta

7

Se puede crear una clase que amplíe la clase Tkinter Button, que se especializó para cerrar la ventana de su asociando el método destroy a su command atributo:

from tkinter import * 

class quitButton(Button): 
    def __init__(self, parent): 
     Button.__init__(self, parent) 
     self['text'] = 'Good Bye' 
     # Command to close the window (the destory method) 
     self['command'] = parent.destroy 
     self.pack(side=BOTTOM) 

root = Tk() 
quitButton(root) 
mainloop() 

Ésta es la salida:

enter image description here


Y la razón por la que su código no trabajar antes:

def close_window(): 
    # root.destroy() 
    window.destroy() 

tengo una ligera sensación es posible que consiguió la raíz de algún otro lugar, ya que hizo window = tk().

Cuando llama a la destrucción en el window en el Tkinter significa que destruye toda la aplicación, ya que su window (ventana raíz) es la ventana principal de la aplicación. En mi humilde opinión, creo que debe cambiar su window al root.

from tkinter import * 

def close_window(): 
    root.destroy() # destroying the main window 

root = Tk() 
frame = Frame(root) 
frame.pack() 

button = Button(frame) 
button['text'] ="Good-bye." 
button['command'] = close_window 
button.pack() 

mainloop() 
20

Con la edición mínima de su código (no estoy seguro si han impartido clases o no en su curso), cambie:

def close_window(root): 
    root.destroy() 

a

def close_window(): 
    window.destroy() 

y debería funcionar .


Explicación:

Su versión de close_window se define esperar que un solo argumento, a saber root. Posteriormente, cualquier llamada a su versión de close_window necesita tener ese argumento, o Python le dará un error en tiempo de ejecución.

Cuando creó un Button, le indicó al botón que se ejecute close_window cuando se hace clic en él. Sin embargo, el código fuente de control Botón es algo así como:

# class constructor 
def __init__(self, some_args, command, more_args): 
    #... 
    self.command = command 
    #... 

# this method is called when the user clicks the button 
def clicked(self): 
    #... 
    self.command() # Button calls your function with no arguments. 
    #... 

Como mis estados de código, la clase Button llamará a su función sin argumentos. Sin embargo, su función está esperando un argumento. Por lo tanto, tuviste un error. Por lo tanto, si tomamos que el argumento, por lo que la llamada a la función se ejecutará dentro de la clase Button, que nos queda:

def close_window(): 
    root.destroy() 

eso no es correcto, sin embargo, tampoco, porque root Nunca se le asigna un valor.Sería como escribir en print(x) cuando aún no ha definido x.

En cuanto a su código, pensé que quería llamar destroy en window, por lo que cambió a rootwindow.

1

Puede utilizar lambda a pasar una referencia al objeto window como argumento para la función close_window:

button = Button (frame, text="Good-bye.", command = lambda: close_window(window)) 

Esto funciona porque el atributo command está esperando un exigible, o se puede llamar como objeto. A lambda es invocable, pero en este caso es esencialmente el resultado de llamar a una función determinada con parámetros establecidos.

Básicamente, está llamando al envoltorio lambda de la función que no tiene argumentos, ni la función en sí misma.

6

Puede asociar directamente el objeto función window.destroy al atributo command de su button:

button = Button (frame, text="Good-bye.", command=window.destroy) 

De esta manera no se necesita la función close_window para cerrar la ventana para usted.

-1
from tkinter import * 

def close_window(): 
    import sys 
    sys.exit() 

root = Tk() 

frame = Frame (root) 
frame.pack() 

button = Button (frame, text="Good-bye", command=close_window) 
button.pack() 

mainloop() 
Cuestiones relacionadas