【问题标题】:Tkinter Toplevel : Destroy window when not focusedTkinter Toplevel:未聚焦时销毁窗口
【发布时间】:2016-12-07 23:25:21
【问题描述】:

我有一个Toplevel 小部件,只要用户点击窗口外,我就想销毁它。我尝试在互联网上寻找解决方案,但似乎没有关于此主题的文章。

我怎样才能做到这一点。感谢您的帮助!

【问题讨论】:

    标签: python tkinter focus destroy toplevel


    【解决方案1】:

    您可以尝试类似的方法: fen 是你的顶层

    fen.bind("<FocusOut>", fen.quit)
    

    【讨论】:

    • &lt;FocusOut&gt; 似乎可以工作,但是当我在主窗口内单击时响应不是很灵敏(仅当我在外部单击时才有效)。还有其他方法吗?
    • 你可以添加一个 然后
    【解决方案2】:

    我遇到了类似的问题,并修复了它。以下示例工作正常。 它在主窗口顶部显示一个顶级窗口,作为自定义配置菜单。 每当用户点击其他地方时,配置菜单就会消失。

    警告:不要在顶层窗口上使用 .transient(parent) ,否则会出现您描述的症状:单击主窗口时,菜单不会消失。您可以尝试在下面的示例中取消注释“self.transient(parent)”行以重现您的问题。

    例子:

    import Tix
    
    
    class MainWindow(Tix.Toplevel):
    
        def __init__(self, parent):
            # Init
            self.parent = parent
            Tix.Toplevel.__init__(self, parent)
            self.protocol("WM_DELETE_WINDOW", self.destroy)
            w = Tix.Button(self, text="Config menu", command=self.openMenu)
            w.pack()
    
        def openMenu(self):
            configWindow = ConfigWindow(self)
            configWindow.focus_set()
    
    
    class ConfigWindow(Tix.Toplevel):
    
        def __init__(self, parent):
            # Init
            self.parent = parent
            Tix.Toplevel.__init__(self, parent)
            # If you uncomment this line it reproduces the issue you described
            #self.transient(parent)
            # Hides the window while it is being configured
            self.withdraw()
            # Position the menu under the mouse
            x = self.parent.winfo_pointerx()
            y = self.parent.winfo_pointery()
            self.geometry("+%d+%d" % (x, y))
            # Configure the window without borders
            self.update_idletasks() # Mandatory for .overrideredirect() method
            self.overrideredirect(True)
            # Binding to close the menu if user does something else
            self.bind("<FocusOut>", self.close)  # User focus on another window
            self.bind("<Escape>", self.close)    # User press Escape
            self.protocol("WM_DELETE_WINDOW", self.close)
            # The configuration items
            w = Tix.Checkbutton(self, text="Config item")
            w.pack()
            # Show the window
            self.deiconify()
    
    
        def close(self, event=None):
            self.parent.focus_set()
            self.destroy()
    
    
    tixRoot = Tix.Tk()
    tixRoot.withdraw()
    app = MainWindow(tixRoot)
    app.mainloop()
    

    【讨论】:

      【解决方案3】:

      当我有 2 个 &lt;tkinter.Entry&gt;s 时,其他解决方案对我不起作用,但我发现了这个:

      import tkinter as tk
      
      focus = 0
      
      def focus_in(event):
          global focus
          focus += 1
      
      def focus_out(event):
          global focus
          focus -= 1
          if focus == 0:
              root.destroy()
      
      root = tk.Toplevel()
      root.bind("<FocusIn>", focus_in)
      root.bind("<FocusOut>", focus_out)
      root.mainloop()
      

      它有一个窗口被聚焦的次数的计数器。当计数器达到 0 时,它会破坏窗口。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多