2013-08-06 85 views
4

我正在製作一個Tkinter應用程序。在應用程序中,我想彈出一個上下文菜單,我使用Tk.Menu.post()。Tk/Tkinter:檢測應用程序失去焦點

我不知道如何讓這個菜單在應用程序失去焦點時消失。我需要這樣做,因爲菜單保持在最前面,即使切換到另一個窗口時,也會留下菜單「工件」。

我在菜單上放置了一個<FocusOut>事件,如果菜單具有焦點並且用戶將焦點移動到另一個應用程序,則會觸發該事件。這很好。

如果主應用程序窗口有焦點,該怎麼辦?我可以在應用程序窗口上放置一個<FocusOut>事件,該窗口關閉菜單;然而,當我關注菜單,關閉菜單時,這最終會被調用。該菜單是以父應用程序爲主創建的,因此我不確定爲什麼主菜單上的<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() 
+0

是什麼平臺你? –

+0

linux,Fedora 18 – jgoeders

+1

要回答你的一個問題,窗口有重點,而不是應用程序。 [刪除了不可行的解決方案]。 –

回答

2

self.focus_get()將返回其可用於區分具有焦點的對象,接收焦點的菜單,和其他一些應用程序。

例如,當焦點移動到另一個應用程序以刪除菜單:

def app_lost_focus(self, event): 
    if self.focus_get() != self.menu: 
     self.destroy_menu(event) 
相關問題