拦截 Tkinter“退出”命令?
Posted
技术标签:
【中文标题】拦截 Tkinter“退出”命令?【英文标题】:Intercept Tkinter "Exit" command? 【发布时间】:2011-06-06 07:02:24 【问题描述】:我正在使用 Tkinter 用 Python 编写客户端-服务器程序。我需要服务器来跟踪连接的客户端。为此,我想让客户端在单击退出按钮(角落中的标准“X”)后向服务器发送一条自动消息。如何知道用户何时退出程序?
【问题讨论】:
How do I handle the window close event in Tkinter? 的可能重复项 【参考方案1】:您想使用顶层窗口的wm_protocol 方法。具体来说,您对WM_DELETE_WINDOW
协议感兴趣。如果您使用该方法,它允许您注册一个回调,该回调会在窗口被销毁时调用。
用法:
root.protocol("WM_DELETE_WINDOW", app.on_delete)
【讨论】:
所以我在调用root.mainloop()
之前添加了这一行:root.protocol("WM_DELETE_WINDOW", app.on_delete())
,但是当窗口打开而不是关闭时调用on_delete()
.我做错了吗?
@John:protocol
方法引用了一个函数。通过添加尾括号,您将调用app.on_delete
并将该方法的结果传递给协议处理程序。正确用法是root.protocol("WM_DELETE_WINDOW", app.on_delete)
设置类似的协议似乎只适用于主窗口的操作系统关闭按钮,但不适用于例如Frame
子类中的退出按钮command=self.quit
)。也就是说,它确实回答了这个仅询问标准退出按钮的问题。
@martineau:正确,该协议仅在要求窗口管理器销毁窗口时才起作用。当您调用quit
时,您只是在指示mainloop
退出,并且窗口被优雅地销毁。
布莱恩:感谢您的确认。我认为不理解区别是为什么不止一个其他答案声称设置协议不起作用。【参考方案2】:
你可以使用pythonatexit
模块。
例如:
import atexit
def doSomethingOnExit():
pass
atexit.register(doSomethingOnExit)
【讨论】:
这对我来说非常有效。其他的从未被触发。【参考方案3】:就我而言,以下代码不起作用:
root.protocol("WM_DELETE_WINDOW", app.on_delete) # doesn't work
但是,它使用这种形式:
root.wm_protocol ("WM_DELETE_WINDOW", app.on_delete) # does work
【讨论】:
没有答案说要使用.protocol
,但是...接受的答案已经说过要使用.wm_protocol
。
@ArtOfWarfare:接受的答案提到 wm_protocol,但其代码 sn-p 使用 .protocol
,而不是 .wm_protocol
。无论如何,这两个选项在我的机器上的行为方式完全相同,我假设 piertoni 的版本与我的不同(毫不奇怪,因为答案可以追溯到 2012 年)。
protocol
和 wm_protocol
是完全一样的功能。【参考方案4】:
FWIW:也可以分配特定于小部件的行为。
如果您希望在特定小部件被销毁时执行操作,您可以考虑覆盖 destroy() 方法。请参阅以下示例:
class MyButton(Tkinter.Button):
def destroy(self):
print "Yo!"
Tkinter.Button.destroy(self)
root = Tkinter.Tk()
f = Tkinter.Frame(root)
b1 = MyButton(f, text="Do nothing")
b1.pack()
f.pack()
b2 = Tkinter.Button(root, text="f.destroy", command=f.destroy)
b2.pack()
root.mainloop()
当按钮 'b2' 被按下时,框架 'f' 被销毁,带有子 'b1' 和“Yo!”被打印出来了。
我在this topic 上发布了相同的答案。
【讨论】:
以上是关于拦截 Tkinter“退出”命令?的主要内容,如果未能解决你的问题,请参考以下文章
tkinter "x" 在退出时执行 ser.close()