2012-04-03 17 views
12

Napisz aplikację GUI za pomocą przycisku oznaczonego "Good-bye". Po kliknięciu przycisku Button okno zostaje zamknięte.Jak zamknąć okno Tkinter, naciskając przycisk?

To jest mój kod do tej pory, ale nie działa. Czy ktoś może mi pomóc z moim kodem?

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

Hej Matt. Dziękuję za jasne pytanie i czysty i prosty przykład kodu, który należy dołączyć. Czy mógłbyś również uwzględnić traceback (awarię) w przyszłości, gdy twój kod "nie działa"? Pomoże to również ludziom niemal natychmiast zorientować się, która część twojego kodu jest zepsuta. Oczywiście w tym przypadku przykład kodu jest tak mały, że łatwo go zidentyfikować, ale może naprawdę pomóc w uzyskaniu odpowiedzi w przyszłości w trudniejszych sytuacjach. – jdi

+0

Dla każdego, kto nie od razu zauważył problem, błąd jest następujący: "TypeError: close_window() brakuje 1 wymaganego argumentu pozycyjnego:" root''. Oznacza to, że nie było żadnego argumentu przekazywanego do wywołania zwrotnego 'close_window', ponieważ nigdy nie ma funkcji' command = '. Odebrane wywołania zwrotne zdarzenia otrzymują argument - obiekt zdarzenia. –

Odpowiedz

7

Można by utworzyć klasę, która rozszerza klasę Tkinter Button, że będą specjalizuje zamknąć okno kojarząc metodę destroy jego command atrybut:

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() 

To wyjście:

enter image description here


A powód, dlaczego Twój kod nie działał wcześniej:

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

mam lekkie uczucie może dostał pierwiastek z jakimś innym miejscu, ponieważ zrobiłeś window = tk().

Po wywołaniu niszczenia na window w Tkinter oznacza zniszczenie całej aplikacji, ponieważ twoje główne okno aplikacji to window (okno główne). IMHO, myślę, że powinieneś zmienić swoje window na 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

Przy minimalnym do edycji kodu (nie wiem, czy oni prowadził zajęcia lub nie w trakcie), zmień:

def close_window(root): 
    root.destroy() 

do

def close_window(): 
    window.destroy() 

i powinno działać .


Objaśnienie:

Twoja wersja close_window definiuje się spodziewać jeden argument, a mianowicie root. Następnie wszelkie wywołania twojej wersji close_window muszą mieć ten argument, lub Python da ci błąd czasu wykonania.

Po utworzeniu Button po kliknięciu przycisku wyświetlił się komunikat o uruchomieniu close_window. Jednak kod źródłowy widget przycisk jest coś takiego:

# 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. 
    #... 

W moich stanów kodowych, klasa Button wezwie swoją funkcję bez argumentów. Jednak twoja funkcja oczekuje sporu. W ten sposób wystąpił błąd. Tak więc, jeśli weźmiemy się ten argument, tak aby wywołanie funkcji wykona wewnątrz klasy Buttona, jesteśmy w lewo z:

def close_window(): 
    root.destroy() 

To nie jest w porządku, chociaż, albo, ponieważ root nie jest przypisana wartość.To byłoby jak pisanie w print(x), kiedy jeszcze nie zdefiniowałeś x.

Patrząc na kod, pomyślałem chciał zadzwonić destroy na window, więc zmieniłem root do window.

1

Można użyć lambda przekazać referencję do obiektu window jako argument close_window funkcji:

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

To działa, ponieważ atrybut command spodziewa się wymagalne lub wymagalne jak przedmiot. A lambda jest wywoływalne, ale w tym przypadku jest to w zasadzie wynik wywołania danej funkcji z ustawionymi parametrami.

W skrócie, wywołujecie opakowanie lambda funkcji, która nie ma argumentów, a nie samą funkcję.

6

można powiązać bezpośrednio z przedmiotu function window.destroy do atrybutem buttoncommand:

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

W ten sposób nie trzeba będzie funkcję close_window aby zamknąć okno dla Ciebie.

-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() 
Powiązane problemy