Tk/Tkinter:检测应用程序失去焦点 [英] Tk/Tkinter: Detect application lost focus

查看:37
本文介绍了Tk/Tkinter:检测应用程序失去焦点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个 Tkinter 应用程序.在应用程序中,我想弹出一个上下文菜单,我使用 Tk.Menu.post() 来完成.

I am making a Tkinter application. In the application, I want to pop up a context menu, which I do using Tk.Menu.post().

我不知道如何在应用程序失去焦点时让这个菜单消失.我需要这样做,因为菜单保持在顶部,即使切换到另一个窗口,留下一个菜单 '神器'.

I don't know how to make this menu disappear when the application loses focus. I need to do this because the menu stays on top, even when switching to another window, leaving a menu 'artifact'.

我在菜单上放置了一个 事件,如果菜单有焦点并且用户将焦点移动到另一个应用程序,则会触发该事件.这很好用.

I put a <FocusOut> event on the menu, which is triggered if the menu has focus and the user moves focus to another application. This works well.

如果主应用程序窗口有焦点怎么办?我可以在应用程序窗口上放置一个 事件,关闭菜单;但是,当我将焦点放在关闭菜单的菜单上时,这最终会被调用.菜单是以父级作为主应用程序创建的,所以我不确定为什么当菜单获得焦点时甚至会触发主应用程序上的 .

What do I do if the main application window has focus? I could put a <FocusOut> event on the application window, which closes the menu; however, this ends up being called when I give focus to the menu, which closes the menu. The menu is created with parent as the main application, so I am not sure why <FocusOut> on the main app is even triggered when the menu gets focus.

我如何区分主应用程序窗口失去焦点到其他应用程序与失去焦点到我的菜单?

我不想使用 tk_popup() 因为我希望用户继续向主窗口提供输入.(菜单的使用是可选的).

I don't want to use tk_popup() because I want the user to continue to provide input to the main window. (use of the menu is optional).

感谢@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() 会返回有焦点的对象,可以用来区分菜单接收焦点,vs其他一些应用程序.

self.focus_get() will return the object that has focus, which can be used to distinguish between the menu receiving focus, vs some other application.

例如,当焦点移动到另一个应用程序时移除菜单:

For example, to remove the menu when the focus moves to another application:

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

这篇关于Tk/Tkinter:检测应用程序失去焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆