Tk/Tkinter:检测应用程序失去焦点

5
我正在制作一个Tkinter应用程序。在该应用程序中,我想弹出一个上下文菜单,我使用Tk.Menu.post()来完成这个操作。
我不知道如何使这个菜单在应用程序失去焦点时消失。我需要这样做是因为即使切换到另一个窗口,菜单仍然保持在顶部,留下了一个菜单“痕迹”。
我在菜单上放置了事件,如果菜单具有焦点并且用户将焦点移动到另一个应用程序,则触发该事件。这个方法效果很好。
如果主应用程序窗口有焦点怎么办?我可以在应用程序窗口上放置事件,以关闭菜单;但是,当我给菜单焦点时,这个方法被调用,将关闭菜单。菜单是以主应用程序为父级创建的,因此我不确定为什么在菜单获得焦点时触发了主应用程序上的事件。
我该如何区分主应用程序窗口失去焦点到另一个应用程序与失去焦点到我的菜单之间的差异?
我不想使用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()

你在哪个平台上? - Bryan Oakley
1
回答你的一个问题,窗口有焦点,而不是应用程序。[已删除可能行不通的解决方案]。 - Brad Lanam
这样怎么样:当主窗口失去焦点后,经过X秒钟,如果菜单没有获得焦点,则降低菜单窗口。 - Brad Lanam
请分享您找出的答案并接受它,以便未回答的问题列表中有更少的项。谢谢 :) - Alok
@jgoeders - 为了保持事情有条不紊,请将您的答案作为对此问题的答案添加并接受该答案(您可以完全接受自己对自己问题的答案- SO是关于拥有世界上最好的编程问答,无论答案来自提出问题的同一人还是不是一个问题。) - ArtOfWarfare
1个回答

3

self.focus_get()将返回具有焦点的对象,可用于区分接收焦点的菜单与某些其他应用程序。

例如,当焦点移动到另一个应用程序时,可以使用以下方法来移除菜单:

def app_lost_focus(self, event):
    if self.focus_get() != self.menu:
        self.destroy_menu(event)
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接