Python Tkinter-关闭窗口事件上的协议处理程序

Python Tkinter-关闭窗口事件上的协议处理程序,python,python-3.x,tkinter,window,protocols,Python,Python 3.x,Tkinter,Window,Protocols,如果用户单击窗口右上角的X按钮,如何覆盖顶层窗口的退出功能?我尝试过这个代码,但没有运气 def chat(): global root, private_chat, chat_list_window, chat_list, ip, port, address,username global private_chat_window, private_chat_messages, private_chat_label, private_chat_entry address = (ip,int(po

如果用户单击窗口右上角的X按钮,如何覆盖顶层窗口的退出功能?我尝试过这个代码,但没有运气

def chat():
global root, private_chat, chat_list_window, chat_list, ip, port, address,username
global private_chat_window, private_chat_messages, private_chat_label, private_chat_entry
address = (ip,int(port))


invited_client = chat_list[len(chat_list) -1].get(chat_list[len(chat_list) -1].curselection())

private_chat_window.append(tk.Toplevel(root))
length = len(private_chat_window)
private_chat_window[length-1].title("Private Chat with '" +  invited_client[2] + "'" )


private_chat_messages.append(Listbox(private_chat_window[length -1], width=80, height=30))
private_chat_messages[length-1].grid(row=1,column=1, columnspan=3,rowspan=1)
private_chat_messages[length-1].insert(END, "Inviting client '" + invited_client[2] + "'for a private chat...")


private_chat_label.append(ttk.Label(private_chat_window[length -1], text='Message Entry Box : '))
private_chat_label[length-1].grid(row=2,column=1)


private_chat_entry.append(ttk.Entry(private_chat_window[length -1] , width=60))
private_chat_entry[length-1].grid(row=2, column=2, columnspan = 2)    


daemon = Pyro4.Daemon()       
uri_str = daemon.register(Messaging())      

private_chat_window[length-1].bind('<KeyPress>', lambda event: private_chat_onkeypress(event,private_chat_messages[length -1], private_chat_entry[length -1], uri_str = uri_str) )
chat_list_window[len(chat_list_window)-1].destroy()

s.sendto(str.encode(":::PrivateChatInvitation:::" + '<' + username + '><' +  str(uri_str) + '>' + json.dumps(invited_client)) , address)


Thread(target = daemon.requestLoop).start()
Thread(target=check_successful_connection(uri_str, private_chat_messages[length -1])).start()

#EXIT
private_chat_window[length -1].protocol("WM_DELETE_WINDOW", on_closing(private_chat_window[length -1]))
private_chat_window[length -1].mainloop()


def on_closing(window_instance):

    if messagebox.askokcancel("Quit", "Do you want to quit?"):
         window_instance.destroy()
def chat():
全局根目录、专用聊天室、聊天室列表窗口、聊天室列表、ip、端口、地址、用户名
全局专用聊天窗口、专用聊天信息、专用聊天标签、专用聊天条目
地址=(ip,int(端口))
已邀请的客户机=聊天列表[len(聊天列表)-1]。获取(聊天列表[len(聊天列表)-1]。curselection()
private_chat_window.append(tk.Toplevel(root))
长度=len(私人聊天窗口)
私人聊天窗口[length-1]。标题(“与“+”邀请的“客户端[2]+”私人聊天”)
private_chat_messages.append(列表框(private_chat_窗口[length-1],width=80,height=30))
私人聊天信息[length-1]。网格(行=1,列=1,列span=3,行span=1)
私人聊天信息[length-1]。插入(结束,“邀请客户端”+“邀请客户端”[2]+“私人聊天…”)
private_chat_label.append(ttk.label(private_chat_窗口[length-1],text='Message Entry Box:'))
私有聊天标签[length-1]。网格(行=2,列=1)
private\u chat\u entry.append(ttk.entry(private\u chat\u窗口[长度-1],宽度=60))
私有聊天项[length-1]。网格(行=2,列=2,列span=2)
daemon=Pyro4.daemon()
uri_str=daemon.register(消息传递())
private_chat_窗口[length-1]。绑定(“”,lambda事件:private_chat_onkeypress(事件,private_chat_消息[length-1],private_chat_条目[length-1],uri_str=uri_str))
聊天列表窗口[len(聊天列表窗口)-1].destroy()
s、 sendto(str.encode(“:::privatechatinvestment:::”+“”+json.dumps(invested\u client)),地址)
线程(target=daemon.requestLoop).start()
线程(target=check\u successful\u connection(uri\u str,private\u chat\u messages[length-1])。start()
#出口
私有聊天窗口[length-1]。协议(“WM\U删除窗口”,在关闭时(私有聊天窗口[length-1]))
私有聊天窗口[length-1].mainloop()
def on_关闭(窗口_实例):
如果messagebox.askokcancel(“退出”,“您想退出吗?”):
window\u实例.destroy()
协议处理程序在顶级窗口上不起作用,但是当连接到根主窗口时,它可以正常工作。代码如下:

def render_gui(): 全局根 全局上下键 全局列表框,标签1,条目1,用户名 上一个键=0

root = tk.Tk()
root.title("Welcome Client '" + username + "'" )


listbox = Listbox(root, width=80, height=30)      
listbox.grid(row=1,column=1, columnspan=5,rowspan=3)


vsb = tk.Scrollbar(root, orient="vertical", command=listbox.yview)
hsb = tk.Scrollbar(root, orient="horizontal", command=listbox.xview)
vsb.grid(row=1, column=4,rowspan = 3, sticky='ns')
hsb.grid(row=3, column=0,rowspan = 1, columnspan=5, sticky = 'wes')


#Menubar

menubar = Menu(root)
filemenu = Menu(menubar,tearoff=0)
filemenu.add_command(label="Private Chat",command=private_chat_threader) #Hmppp
menubar.add_cascade(label="Options", menu= filemenu)
root.config(menu=menubar)

listbox.configure(yscrollcommand=vsb.set,xscrollcommand=hsb.set)

label1 = ttk.Label(root, text='Message Entry Box : ')
label1.grid(row=4,column=1)

entry1 = ttk.Entry(root, width=60)
entry1.grid(row=4, column=2)    

root.geometry('490x520')
root.bind('<KeyPress>', onKeyPress)

root.protocol("WM_DELETE_WINDOW", on_closing(root))
root.mainloop()
root=tk.tk()
title(“欢迎客户机“+”用户名“+”))
列表框=列表框(根,宽度=80,高度=30)
网格(行=1,列=1,列span=5,行span=3)
vsb=tk.Scrollbar(root,orient=“vertical”,command=listbox.yview)
hsb=tk.Scrollbar(root,orient=“horizontal”,command=listbox.xview)
网格(行=1,列=4,行span=3,sticky='ns')
网格(行=3,列=0,行span=1,列span=5,粘性='wes')
#梅努巴
菜单栏=菜单(根)
filemenu=Menu(menubar,tearoff=0)
文件菜单。添加命令(label=“Private Chat”,command=Private\u Chat\u threader)#Hmppp
menubar.add_级联(label=“Options”,menu=filemenu)
root.config(menu=menubar)
configure(yscrollcommand=vsb.set,xscrollcommand=hsb.set)
label1=ttk.Label(根,text='Message输入框:')
标签1.网格(行=4,列=1)
entry1=ttk.Entry(根,宽度=60)
entry1.grid(行=4,列=2)
根几何体('490x520')
root.bind(“”,onKeyPress)
协议(“WM_删除_窗口”,on_关闭(根))
root.mainloop()

请帮帮我。谢谢。

我看不出您的代码如何在根窗口或顶层运行。
协议
方法要求您传入一个可调用函数(即:对函数的引用)。相反,您在关闭(root)时立即调用
,然后将结果传递给协议处理程序

您需要像这样调用
协议

private_chat_window[length -1].protocol("WM_DELETE_WINDOW", on_closing)
如果需要传递参数,可以像对任何其他回调一样使用
lambda
functools.partial
。例如:

private_chat_window[length-1].protocol(
    "WM_DELETE_WINDOW", 
    lambda: on_closing(private_chat_window[length -1])
)