2017-06-13 228 views
1

我知道,从here如何防止父窗口关闭之前关闭子窗口

grab_set()[#]: 路线的所有事件此应用程序来这个小程序。

好,但它并不妨碍用户用X按钮关闭父窗口。除了其他事件之外,我怎样才能路由“X按钮关闭”事件?

MWE:

from Tkinter import * 

class Window(Toplevel): 

    def __init__(self, master): 
     Toplevel.__init__(self) 


class MainWindow(Tk): 

    def __init__(self): 
     Tk.__init__(self) 
     Button(self, command=self.open_window).grid(row=0, column=0) 

    def open_window(self): 
     win = Window(self) 
     win.grab_set() 


app = MainWindow() 
app.mainloop() 
+0

我已经更新了我的回答让我知道,如果它是你在找什么。 –

+0

你真正的问题是什么?你想改变/完成什么? –

+0

@ TadhgMcDonald-Jensen我想阻止用户在关闭子窗口之前关闭父窗口。 – Shibli

回答

1

Windows系统可以使用:

root.protocol("WM_DELETE_WINDOW", your_function_here)

我不知道其他操作系统,因为我没有测试它在Windows以外的任何东西。

在课堂上也能很好地工作。

self.root.protocol("WM_DELETE_WINDOW", self.your_method_here)

我加入一些代码到您的文章来说明其使用。请注意,当您按下X按钮时,程序将符合close_program方法。

编辑:无法在Mac上测试我已经添加了我认为可以解决您的问题。我已经在close_program方法中添加了一条if语句,以在尝试关闭之前检查顶层是否存在。

更新:我添加了一个检查变量win来处理可能的错误,如果顶层从未打开,但仍然尝试关闭根窗口。

from tkinter import * 

class Window(Toplevel): 

    def __init__(self, master): 
     Toplevel.__init__(self) 
     self.protocol("WM_DELETE_WINDOW", self.close_program) 

    def close_program(self): 
     print ("destroying Window") 
     self.destroy() 


class MainWindow(Tk): 

    def __init__(self): 
     Tk.__init__(self) 
     Button(self, command=self.open_window).grid(row=0, column=0) 
     self.protocol("WM_DELETE_WINDOW", self.close_program) 

    def open_window(self): 
     global win 
     win = Window(self) 
     win.grab_set() 

    def close_program(self): 
     if 'win' in globals(): 
      if win.winfo_exists() == 1: 
       print("top level still active") 
      else: 
       print("destroying MainWindow") 
       self.destroy() 
     else: 
      print("destroying MainWindow") 
      self.destroy() 


app = MainWindow() 
app.mainloop() 
+0

我仍然可以在你的代码之前关闭父窗口。所以没有改变。 – Shibli

+0

嗡嗡声。我无法。午餐结束后我会继续努力。我怀疑在尝试关闭之前,应该很容易创建if语句来检查子窗口是否打开。 –

+0

顺便说一句,我可以说在Mac上做File-> Close或cmd-W也触发该协议。我相信Linux也是如此。 –

1

比方说,如果存在子窗口,试图关闭父窗口就会把它成为关注的焦点,这将需要一些变化:

  1. 控装置,带.protocol("WM_DELETE_WINDOW")所以检查的密切协议为一个孩子窗口。
  2. 保持一个参考的子窗口
class MainWindow(Tk): 

    def __init__(self): 
     Tk.__init__(self) 
     Button(self, text="hello there", command=self.open_window).grid(row=0, column=0) 
     self.protocol("WM_DELETE_WINDOW", self.try_to_close) 
     self.win = None 

    def open_window(self): 
     if self.win is None or not self.win.winfo_exists(): 
      self.win = Window(self) 
     self.win.lift(self) 
     self.win.focus_set() 

    def try_to_close(self): 
     if self.win is not None and self.win.winfo_exists(): 
      self.win.lift() 
     else: 
      self.destroy() 
+0

是的,它做我想要的。另外,在'self.win.focus_set()'后加'self.win.grab_set()'也防止点击父按钮。尼斯。 – Shibli