关闭tkinter窗口时,它是隐藏的,但仍然存在

时间:2018-01-07 00:46:19

标签: python python-3.x tkinter python-3.6

这是一个问题,因为我需要打开和关闭窗口作为程序功能的一部分。通过窗口持久化(我可以从“窗口”菜单中选择它们),它们会在使用程序时占用越来越多的内存。

我在MacOS High Sierra上使用Python 3.6。

有没有办法让窗户真正毁灭?

我想破坏子窗口的示例程序:

import tkinter as tk

def subWindow():
  top = tk.Toplevel(root)

root = tk.Tk()

button = tk.Button(root, text="New Window", command=subWindow)
button.pack()

root.mainloop()

使用.destroy()的非工作示例:

import tkinter as tk

def subWindow():
  top = tk.Toplevel(root)
  top.protocol("WM_DELETE_WINDOW", top.destroy())

root = tk.Tk()

button = tk.Button(root, text="New Window", command=subWindow)
button.pack()

root.mainloop()

按下“新窗口”按钮时回溯:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1699, in __call__
    return self.func(*args)
  File "test.py", line 5, in subWindow
    top.protocol("WM_DELETE_WINDOW", top.destroy())
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/tkinter/__init__.py", line 1959, in wm_protocol
    'wm', 'protocol', self._w, name, command)
_tkinter.TclError: bad window path name ".!toplevel"

另一个不抛出异常但仍然不会导致子窗口被破坏的例子:

import tkinter as tk

def subWindow():
  top = tk.Toplevel(root)

  def closeSubWindow():
    top.destroy()

  top.protocol("WM_DELETE_WINDOW", closeSubWindow)

root = tk.Tk()

button = tk.Button(root, text="New Window", command=subWindow)
button.pack()

root.mainloop()

1 个答案:

答案 0 :(得分:0)

当您关闭由该方法创建的辅助窗口时,如果它已关闭,则 获取<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>repl.it</title> <link href="index.css" rel="stylesheet" type="text/css" /> <link href="https://fonts.googleapis.com/css?family=Muli" rel="stylesheet"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script src="index.js"></script> </head> <body> <center><div id = "mainTitle">Please make a selection</div></center><br><br> <center> <div class = "scoreTitle">You</div> <div class = "scoreTitle" id = "scoreTitle2">Tie</div> <div class = "scoreTitle">Cpu</div> </center> <center> <input class = "scoreBox" id = "scoreBox1" type = "text" disabled> <input class = "scoreBox" id = "scoreBox2" type = "text" disabled> <input class = "scoreBox" id = "scoreBox3" type = "text" disabled> </center><br><br><br> <center><div class = "lowerTitle">Computer</div></center><br><br> <center> <div id = "computerRock"> <img class = "image" src = "https://image.ibb.co/eR6Fga/rock.png"> </div> <div id = "computerPaper"> <img class = "image" src = "https://image.ibb.co/mv0aga/paper.png"> </div> <div id = "computerScissors"> <img class = "image" src = "https://image.ibb.co/mPKqEv/scissors.png"> </div> </center> <center><hr></center> <center> <div id = "playerRock"> <img class = "image" src = "https://image.ibb.co/eR6Fga/rock.png"> </div> <div id = "playerPaper"> <img class = "image" src = "https://image.ibb.co/mv0aga/paper.png"> </div> <div id = "playerScissors"> <img class = "image" src = "https://image.ibb.co/mPKqEv/scissors.png"> </div> </center> <br><br><center><div class = "lowerTitle">Player</div></center> </body> </html>,但默认情况下您关闭任何窗口。如果您想亲眼看看,请尝试添加:

destroy

print(root.winfo_children()) 直接儿童的小部件列为root的成员,ToplevelsubWindow的最后一行。

当默认关闭窗口协议正在进行时,进一步window.protocol("WM_DELETE_WINDOW", callback)会调用callback,例如单击X按钮或 Alt-F4 。在关闭窗口之前,它可以用来询问用户的事情,例如:“你真的要关闭吗?”。但是,当你定期关闭一个窗口时,无论如何它应该被销毁,这意味着虽然top.protocol("WM_DELETE_WINDOW", closeSubWindow)没有引发错误,但它应该是多余的,除非默认行为被某种方式覆盖。

虽然上述情况可能属实,但正如Bryan在评论中指出的那样,对创建的Topleveltop的引用是本地名称,没有任何意义在subWindow方法之外。