2012-04-03 41 views
12

Viết ứng dụng GUI có nút có nhãn "Good-bye". Khi nhấp vào Button, cửa sổ sẽ đóng lại.Cách đóng cửa sổ Tkinter bằng cách nhấn một nút?

Đây là mã của tôi cho đến nay nhưng không hoạt động. Bất cứ ai có thể giúp tôi với mã của tôi?

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. Cảm ơn bạn đã có một câu hỏi rõ ràng, và một ví dụ mã đơn giản và sạch sẽ để đi cùng. Bạn cũng có thể đảm bảo bao gồm truy nguyên (sự cố) trong tương lai khi mã của bạn "không hoạt động"? Điều đó cũng sẽ giúp mọi người gần như ngay lập tức tìm ra phần nào của mã của bạn bị hỏng. Rõ ràng trong trường hợp này, mẫu mã của bạn quá nhỏ nên dễ nhận biết, nhưng nó thực sự có thể giúp bạn nhận được câu trả lời trong tương lai về những tình huống khó khăn hơn. – jdi

+0

Đối với bất kỳ ai không thấy ngay vấn đề, lỗi là 'TypeError: close_window() thiếu 1 đối số vị trí bắt buộc: 'root''. Điều này có nghĩa là không có đối số nào được chuyển tới hàm gọi lại 'close_window', vì không bao giờ có các hàm' command = '. Ràng buộc gọi lại sự kiện không nhận được một đối số - đối tượng sự kiện. –

Trả lời

7

Bạn có thể tạo một lớp mở rộng lớp Tkinter Button, mà sẽ được chuyên để đóng cửa sổ của bạn bằng cách kết hợp các phương pháp destroy để command thuộc tính của nó:

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

Đây là kết quả:

enter image description here


Và lý do tại sao mã của bạn không làm việc trước đây:

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

Tôi có một cảm giác nhẹ bạn có thể có nguồn gốc từ một số nơi khác, vì bạn đã làm window = tk().

Khi bạn gọi phá hủy trên window trong Tkinter nghĩa là hủy toàn bộ ứng dụng, vì window (cửa sổ gốc) là cửa sổ chính cho ứng dụng. IMHO, tôi nghĩ bạn nên thay đổi window thành 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

Với chỉnh sửa tối thiểu để mã của bạn (Không chắc chắn nếu họ đã dạy các lớp hay không trong khóa học của bạn), sự thay đổi:

def close_window(root): 
    root.destroy() 

để

def close_window(): 
    window.destroy() 

và nó cũng làm việc .


Giải thích:

Phiên bản của bạn close_window được định nghĩa để mong đợi một đối số duy nhất, cụ thể là root. Sau đó, mọi cuộc gọi đến phiên bản close_window của bạn cần phải có đối số đó hoặc Python sẽ cung cấp cho bạn lỗi thời gian chạy .

Khi bạn tạo một Button, bạn đã yêu cầu nút chạy close_window khi được nhấp. Tuy nhiên, mã nguồn cho tiện ích Nút là một cái gì đó như:

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

Khi mã của tôi nêu rõ, lớp Button sẽ gọi hàm của bạn mà không có đối số. Tuy nhiên chức năng của bạn đang mong đợi một đối số. Vì vậy, bạn đã có một lỗi. Vì vậy, nếu chúng ta đưa ra lập luận rằng, do đó gọi hàm sẽ thực hiện bên trong lớp Button, chúng tôi đang trái với:

def close_window(): 
    root.destroy() 

Đó là không đúng, tuy nhiên, một trong hai, vì root không bao giờ được gán một giá trị.Nó sẽ giống như nhập vào print(x) khi bạn chưa xác định x.

Nhìn vào mã của bạn, tôi đã tìm bạn muốn gọi destroy trên window, vì vậy tôi đã thay đổi root thành window.

1

Bạn có thể sử dụng lambda để vượt qua một tham chiếu đến đối tượng window như là đối số để close_window chức năng:

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

này hoạt động bởi vì thuộc tính command đang mong đợi một callable, hoặc có thể được gọi như đối tượng. A lambda là một cuộc gọi, nhưng trong trường hợp này, về cơ bản là kết quả của việc gọi một hàm đã cho với các tham số đã đặt.

Về bản chất, bạn đang gọi trình bao bọc lambda của hàm không có arg, không phải chính hàm đó.

6

Bạn có thể kết hợp trực tiếp các chức năng đối tượng window.destroy đến command thuộc tính của button của bạn:

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

Bằng cách này bạn sẽ không cần chức năng close_window để đóng cửa sổ cho bạn.

-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() 
Các vấn đề liên quan