如何处理Tkinter中的窗口关闭事件?

时间:2023-02-13 00:02:06

How do I handle the window close event (user clicking the 'X' button) in a Python Tkinter program?

如何在Python Tkinter程序中处理窗口关闭事件(用户单击“X”按钮)?

4 个解决方案

#1


102  

Tkinter supports a mechanism called protocol handlers. Here, the term protocol refers to the interaction between the application and the window manager. The most commonly used protocol is called WM_DELETE_WINDOW, and is used to define what happens when the user explicitly closes a window using the window manager.

Tkinter支持一种称为协议处理程序的机制。这里,术语协议指的是应用程序和窗口管理器之间的交互。最常用的协议称为WM_DELETE_WINDOW,用于定义用户使用窗口管理器显式关闭窗口时发生的情况。

You can use the protocol method to install a handler for this protocol (the widget must be a Tk or Toplevel widget):

您可以使用协议方法为此协议安装处理程序(该小部件必须是Tk或Toplevel小部件):

Here you have a concrete example:

这里有一个具体的例子:

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()

def on_closing():
    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        root.destroy()

root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()

#2


13  

Matt has shown one classic modification of the close button.
The other is to have the close button minimize the window.
You can reproduced this behavior by having the iconify method
be the protocol method's second argument.

Matt展示了关闭按钮的一个经典修改。另一种是让关闭按钮最小化窗口。您可以通过将iconify方法作为协议方法的第二个参数来重现此行为。

Here's a working example, tested on Windows 7:

这是一个在Windows 7上测试的工作示例:

# Python 3
import tkinter
import tkinter.scrolledtext as scrolledtext

class GUI(object):

    def __init__(self):
        root = self.root = tkinter.Tk()
        root.title('Test')

    # make the top right close button minimize (iconify) the main window
        root.protocol("WM_DELETE_WINDOW", root.iconify)

    # make Esc exit the program
        root.bind('<Escape>', lambda e: root.destroy())

    # create a menu bar with an Exit command
        menubar = tkinter.Menu(root)
        filemenu = tkinter.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Exit", command=root.destroy)
        menubar.add_cascade(label="File", menu=filemenu)
        root.config(menu=menubar)

    # create a Text widget with a Scrollbar attached
        txt = scrolledtext.ScrolledText(root, undo=True)
        txt['font'] = ('consolas', '12')
        txt.pack(expand=True, fill='both')

gui = GUI()
gui.root.mainloop()

In this example we give the user two new exit options:
the classic file menu -> Exit, and also the Esc button.

在这个例子中,我们为用户提供了两个新的退出选项:经典文件菜单 - >退出,以及Esc按钮。

#3


0  

Depending on the Tkinter activity, end esp. when using Tkinter.after, stopping this activity with destroy() -- even by using protocol(), a button, etc. -- will disturb this activity ("while executing" error) rather than just terminate it. The best solution in almost every case is to use a flag. Here is a simple, silly example of how to use it (although I am certain that most of you don't need it! :)

根据Tkinter活动,结束esp。当使用Tkinter.after时,使用destroy()停止此活动 - 即使使用protocol(),按钮等 - 将干扰此活动(“执行时”错误)而不是仅仅终止它。几乎在每种情况下,最好的解决方案是使用标志。这是一个如何使用它的简单,愚蠢的例子(虽然我确信你们大多数人都不需要它!:)

from Tkinter import *

def close_window():
  global running
  running = False
  print "Window closed"

root = Tk()
root.protocol("WM_DELETE_WINDOW", close_window)
cv = Canvas(root, width=200, height=200); cv.pack()

running = True;
# This is an endless loop stopped only by setting 'running' to 'False'
while running: 
  for i in range(200): 
    if not running: break
    cv.create_oval(i,i,i+1,i+1); root.update() 

This terminates graphics activity nicely. You only need to check running at the right place(s).

这很好地终止了图形活动。您只需要检查在正确的地方跑步。

#4


-14  

Use the closeEvent

使用closeEvent

def closeEvent(self, event):
# code to be executed

#1


102  

Tkinter supports a mechanism called protocol handlers. Here, the term protocol refers to the interaction between the application and the window manager. The most commonly used protocol is called WM_DELETE_WINDOW, and is used to define what happens when the user explicitly closes a window using the window manager.

Tkinter支持一种称为协议处理程序的机制。这里,术语协议指的是应用程序和窗口管理器之间的交互。最常用的协议称为WM_DELETE_WINDOW,用于定义用户使用窗口管理器显式关闭窗口时发生的情况。

You can use the protocol method to install a handler for this protocol (the widget must be a Tk or Toplevel widget):

您可以使用协议方法为此协议安装处理程序(该小部件必须是Tk或Toplevel小部件):

Here you have a concrete example:

这里有一个具体的例子:

import tkinter as tk
from tkinter import messagebox

root = tk.Tk()

def on_closing():
    if messagebox.askokcancel("Quit", "Do you want to quit?"):
        root.destroy()

root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()

#2


13  

Matt has shown one classic modification of the close button.
The other is to have the close button minimize the window.
You can reproduced this behavior by having the iconify method
be the protocol method's second argument.

Matt展示了关闭按钮的一个经典修改。另一种是让关闭按钮最小化窗口。您可以通过将iconify方法作为协议方法的第二个参数来重现此行为。

Here's a working example, tested on Windows 7:

这是一个在Windows 7上测试的工作示例:

# Python 3
import tkinter
import tkinter.scrolledtext as scrolledtext

class GUI(object):

    def __init__(self):
        root = self.root = tkinter.Tk()
        root.title('Test')

    # make the top right close button minimize (iconify) the main window
        root.protocol("WM_DELETE_WINDOW", root.iconify)

    # make Esc exit the program
        root.bind('<Escape>', lambda e: root.destroy())

    # create a menu bar with an Exit command
        menubar = tkinter.Menu(root)
        filemenu = tkinter.Menu(menubar, tearoff=0)
        filemenu.add_command(label="Exit", command=root.destroy)
        menubar.add_cascade(label="File", menu=filemenu)
        root.config(menu=menubar)

    # create a Text widget with a Scrollbar attached
        txt = scrolledtext.ScrolledText(root, undo=True)
        txt['font'] = ('consolas', '12')
        txt.pack(expand=True, fill='both')

gui = GUI()
gui.root.mainloop()

In this example we give the user two new exit options:
the classic file menu -> Exit, and also the Esc button.

在这个例子中,我们为用户提供了两个新的退出选项:经典文件菜单 - >退出,以及Esc按钮。

#3


0  

Depending on the Tkinter activity, end esp. when using Tkinter.after, stopping this activity with destroy() -- even by using protocol(), a button, etc. -- will disturb this activity ("while executing" error) rather than just terminate it. The best solution in almost every case is to use a flag. Here is a simple, silly example of how to use it (although I am certain that most of you don't need it! :)

根据Tkinter活动,结束esp。当使用Tkinter.after时,使用destroy()停止此活动 - 即使使用protocol(),按钮等 - 将干扰此活动(“执行时”错误)而不是仅仅终止它。几乎在每种情况下,最好的解决方案是使用标志。这是一个如何使用它的简单,愚蠢的例子(虽然我确信你们大多数人都不需要它!:)

from Tkinter import *

def close_window():
  global running
  running = False
  print "Window closed"

root = Tk()
root.protocol("WM_DELETE_WINDOW", close_window)
cv = Canvas(root, width=200, height=200); cv.pack()

running = True;
# This is an endless loop stopped only by setting 'running' to 'False'
while running: 
  for i in range(200): 
    if not running: break
    cv.create_oval(i,i,i+1,i+1); root.update() 

This terminates graphics activity nicely. You only need to check running at the right place(s).

这很好地终止了图形活动。您只需要检查在正确的地方跑步。

#4


-14  

Use the closeEvent

使用closeEvent

def closeEvent(self, event):
# code to be executed