【发布时间】:2011-06-06 07:02:24
【问题描述】:
我正在使用 Tkinter 用 Python 编写客户端-服务器程序。我需要服务器来跟踪连接的客户端。为此,我想让客户端在单击退出按钮(角落中的标准“X”)后向服务器发送一条自动消息。如何知道用户何时退出程序?
【问题讨论】:
标签: python client-server tkinter exit
我正在使用 Tkinter 用 Python 编写客户端-服务器程序。我需要服务器来跟踪连接的客户端。为此,我想让客户端在单击退出按钮(角落中的标准“X”)后向服务器发送一条自动消息。如何知道用户何时退出程序?
【问题讨论】:
标签: python client-server tkinter exit
您想使用顶层窗口的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() .我做错了吗?
protocol 方法引用了一个函数。通过添加尾括号,您将调用app.on_delete 并将该方法的结果传递给协议处理程序。正确用法是root.protocol("WM_DELETE_WINDOW", app.on_delete)
Frame 子类中的退出按钮command=self.quit)。也就是说,它确实回答了这个仅询问标准退出按钮的问题。
quit 时,您只是在指示mainloop 退出,并且窗口被优雅地销毁。
你可以使用pythonatexit模块。
例如:
import atexit
def doSomethingOnExit():
pass
atexit.register(doSomethingOnExit)
【讨论】:
就我而言,以下代码不起作用:
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。
.protocol,而不是 .wm_protocol。无论如何,这两个选项在我的机器上的行为方式完全相同,我假设 piertoni 的版本与我的不同(毫不奇怪,因为答案可以追溯到 2012 年)。
protocol 和 wm_protocol 是完全一样的功能。
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 上发布了相同的答案。
【讨论】: