我正在制作Tkinter应用程序。在应用程序中,我想弹出一个上下文菜单,这是使用Tk.Menu.post()完成的。
我不知道当应用程序失去焦点时如何使此菜单消失。 我需要执行此操作,因为即使在切换到另一个窗口时,菜单仍位于顶部,而使菜单保留为“工件”。
我在菜单上放置了一个<FocusOut>
事件,如果菜单具有焦点并且用户将焦点移至另一个应用程序,则会触发该事件。这很好。
如果主应用程序窗口具有焦点,该怎么办?我可以在应用程序窗口上放置一个<FocusOut>
事件,以关闭菜单。但是,当我将注意力集中在菜单上时,该菜单最终被调用,从而关闭了菜单。该菜单是使用parent作为主要应用程序创建的,因此,我不确定为什么当菜单获得焦点时,主应用程序上的<FocusOut>
甚至会被触发。
如何区分主应用程序窗口失去焦点到另一个应用程序与主菜单窗口失去焦点到我的菜单?
我不想使用tk_popup(),因为我希望用户继续向主窗口提供输入。 (使用菜单是可选的)。
感谢@Brad Lanam,我想出了一个解决方案,其中包括:
from Tkinter import *
class App(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
self.entry = Entry(self)
self.entry.grid(padx=30, pady=30)
self.entry.focus_set()
self.entry.bind("<Tab>", self.put_menu)
self.entry.bind("<Down>", self.set_focus_on_menu)
self.menu = Menu(self, tearoff=False)
self.menu.add_command(label="test")
self.menu.bind("<FocusOut>", self.destroy_menu)
self.bind("<FocusIn>", self.app_got_focus)
self.bind("<FocusOut>", self.app_lost_focus)
self.bind("<3>", self.put_menu)
def app_got_focus(self, event):
self.config(background="red")
def app_lost_focus(self, event):
self.config(background="grey")
######## SOLUTION BEGIN #########
if self.focus_get() != self.menu:
self.destroy_menu(event)
######## SOLUTION END ###########
def set_focus_on_menu(self, event):
self.menu.focus_set()
def menu_got_focus(self, event):
self.menu.activate(0)
def put_menu(self, event):
self.menu.post(self.winfo_x() + self.entry.winfo_x(), self.winfo_y() + self.entry.winfo_y()+20)
def destroy_menu(self, event):
self.menu.destroy()
app = App()
app.mainloop()
最佳答案
self.focus_get()将返回具有焦点的对象,该对象可用于区分接收焦点的菜单与其他应用程序。
例如,要在焦点移到另一个应用程序时删除菜单:
def app_lost_focus(self, event):
if self.focus_get() != self.menu:
self.destroy_menu(event)
关于python - Tk/Tkinter : Detect application lost focus,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18089068/