python - Python Tkinter - 关闭窗口事件的协议处理程序
问题描述
如果用户单击窗口右上角的 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 render_gui(): global root global prev_key global listbox, label1, entry1, username prev_key = 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()
请帮我。谢谢。
解决方案
我看不到您的代码如何在根窗口或Toplevel
. 该protocol
方法要求您传入一个可调用的(即:对函数的引用)。相反,您on_closing(root)
立即调用,然后将结果传递给协议处理程序。
你需要这样调用protocol
:
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])
)
推荐阅读
- audio - 使用 FFmpeg(或 sox)减少立体声
- php - Wordpress 前端仅在以管理员身份登录时有效
- java - 如何在 HiveMQ 客户端中正确使用 SSL 配置?(MQTT)
- hive - Hive 性能改进
- django - 有没有办法可以在 CreateView 中将类或 ID 添加到使用 UserCreationForm 生成的表单中
- sql - 使用 ROW_NUMBER() 和 CASE 语句创建通话记帐表
- c - 为什么这种递归可以作为返回值?
- java - 在 Android Studio 中过滤和计算数组值
- c# - 在 Azure 应用服务上使用客户端管理的身份验证时被禁止 403
- java - 连接耳机时如何在Android中录制音频?