Как закрыть окно Tkinter нажатием кнопки?
Напишите графическое приложение с кнопкой "Good-bye"
. Когда
Нажимается Button
, окно закрывается.
Это мой код до сих пор, но он не работает. Может ли кто-нибудь помочь мне с моим кодом?
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()
Ответы
Ответ 1
С минимальным редактированием вашего кода (не уверен, что они преподавали классы или нет в вашем курсе), измените:
def close_window(root):
root.destroy()
к
def close_window():
window.destroy()
и он должен работать.
Объяснение:
Ваша версия close_window
определяется как ожидаемый один аргумент, а именно root
. Впоследствии любые вызовы вашей версии close_window
должны иметь этот аргумент, или Python даст вам ошибку времени выполнения.
Когда вы создали Button
, вы сказали кнопке запустить close_window
при нажатии. Однако исходный код для виджета Button выглядит примерно так:
# 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.
#...
Как мой код говорит, класс Button
будет вызывать вашу функцию без аргументов. Однако ваша функция ожидает аргумента. Таким образом, у вас была ошибка. Итак, если мы выберем этот аргумент, чтобы вызов функции выполнялся внутри класса Button, мы остаемся с:
def close_window():
root.destroy()
Это тоже не так, потому что root
никогда не назначается значение. Это было бы похоже на ввод текста print(x)
, если вы еще не определили x
.
Посмотрев на свой код, я решил, что вы хотите называть destroy
на window
, поэтому я изменил root
на window
.
Ответ 2
Вы можете создать класс, который расширяет класс Tkinter Button
, который будет специализирован для закрытия вашего окна, связав метод destroy
с его атрибутом 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()
Это вывод:
![enter image description here]()
И причина, по которой ваш код не работал раньше:
def close_window ():
# root.destroy()
window.destroy()
У меня есть небольшое чувство, что вы можете получить корень из другого места, так как вы сделали window = tk()
.
Когда вы вызываете destroy на window
в Tkinter, это означает уничтожение всего приложения, так как ваше window
(корневое окно) является основным окном для приложения. IMHO, я думаю, вы должны изменить свой window
на 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()
Ответ 3
Вы можете напрямую связать объект функции window.destroy
с атрибутом command
вашего button
:
button = Button (frame, text="Good-bye.", command=window.destroy)
Таким образом вам не понадобится функция close_window
, чтобы закрыть окно для вас.
Ответ 4
Вы можете использовать lambda
для передачи ссылки на объект window
в качестве аргумента функции close_window
:
button = Button (frame, text="Good-bye.", command = lambda: close_window(window))
Это работает, потому что атрибут command
ожидает вызываемого или вызываемого объекта.
A lambda
является вызываемым, но в этом случае он по существу является результатом вызова данной функции с заданными параметрами.
В сущности, вы вызываете лямбда-оболочку функции, у которой нет аргументов, а не самой функции.
Ответ 5
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()