Écrivez une application GUI avec un bouton intitulé "Good-bye"
. Lorsque vous cliquez sur Button
, la fenêtre se ferme.
C'est mon code jusqu'à présent, mais cela ne fonctionne pas. Quelqu'un peut-il m'aider avec mon code?
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()
Avec une modification minimale de votre code (vous ne savez pas s'ils ont enseigné des cours ou non dans votre cours), changez:
def close_window(root):
root.destroy()
à
def close_window():
window.destroy()
et ça devrait marcher.
Explication:
Votre version de close_window
Est définie pour attendre un seul argument, à savoir root
. Par la suite, tous les appels à votre version de close_window
Doivent avoir cet argument, ou Python vous donnera une erreur d'exécution .
Lorsque vous avez créé un Button
, vous avez dit au bouton d'exécuter close_window
Lorsqu'il est cliqué. Cependant, le code source du widget Button est quelque chose comme:
# 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.
#...
Comme l'indique mon code, la classe Button
appellera votre fonction sans arguments. Cependant, votre fonction attend un argument. Vous avez donc eu une erreur. Donc, si nous retirons cet argument, afin que l'appel de fonction s'exécute à l'intérieur de la classe Button, nous nous retrouvons avec:
def close_window():
root.destroy()
Ce n'est pas vrai non plus, car root
ne reçoit jamais de valeur. Ce serait comme taper print(x)
quand vous n'avez pas encore défini x
.
En regardant votre code, j'ai pensé que vous vouliez appeler destroy
sur window
, j'ai donc changé root
en window
.
Vous pouvez créer une classe qui étend la classe Tkinter Button
, qui sera spécialisée pour fermer votre fenêtre en associant la méthode destroy
à son attribut command
:
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()
Voici la sortie:
Et la raison pour laquelle votre code ne fonctionnait pas auparavant:
def close_window ():
# root.destroy()
window.destroy()
J'ai un léger sentiment que vous pourriez avoir la racine d'un autre endroit, puisque vous avez fait window = tk()
.
Lorsque vous appelez la destruction sur le window
dans le Tkinter signifie la destruction de l'application entière, car votre window
(fenêtre racine) est la fenêtre principale de l'application. À mon humble avis, je pense que vous devriez changer votre window
en 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()
Vous pouvez associer directement l'objet fonction window.destroy
à l'attribut command
de votre button
:
button = Button (frame, text="Good-bye.", command=window.destroy)
De cette façon, vous n'aurez pas besoin de la fonction close_window
pour fermer la fenêtre pour vous.
Vous pouvez utiliser lambda
pour passer une référence à l'objet window
comme argument à close_window
une fonction:
button = Button (frame, text="Good-bye.", command = lambda: close_window(window))
Cela fonctionne parce que l'attribut command
attend un objet appelable ou appelable comme. Un lambda
est un appelable, mais dans ce cas, il s'agit essentiellement du résultat de l'appel d'une fonction donnée avec des paramètres définis.
En gros, vous appelez le wrapper lambda de la fonction qui n'a pas d'arguments, pas la fonction elle-même.
from tkinter import *
window = tk()
window.geometry("300x300")
def close_window ():
window.destroy()
button = Button ( text = "Good-bye", command = close_window)
button.pack()
window.mainloop()