Python 为什么我的窗户关闭后会重新打开?

Python 为什么我的窗户关闭后会重新打开?,python,python-3.x,tkinter,tk,Python,Python 3.x,Tkinter,Tk,我在测试我朋友的Tkinter代码时,遇到了这种奇怪的行为 当我使用Windows“X”按钮(窗口右上角)关闭此Tk窗口(类/方法?)时,它会关闭,然后再重新打开一秒钟。第二次单击“X”按钮最终关闭窗口。 下面是窗口的代码(假设定义了所有按钮命令): 是否有理由我必须点击窗口上的关闭按钮两次 编辑:使示例实际工作。对不起,伙计们! 第二次编辑:好吧,这很奇怪。这是完美的,这意味着其他地方的代码一定有问题。这太奇怪了。没关系,我把它修好了。感谢@abarnert的帮助 如果其他人对此感到奇怪,我的

我在测试我朋友的
Tkinter
代码时,遇到了这种奇怪的行为

当我使用Windows“X”按钮(窗口右上角)关闭此Tk窗口(类/方法?)时,它会关闭,然后再重新打开一秒钟。第二次单击“X”按钮最终关闭窗口。 下面是窗口的代码(假设定义了所有按钮命令):

是否有理由我必须点击窗口上的关闭按钮两次

编辑:使示例实际工作。对不起,伙计们!

第二次编辑:好吧,这很奇怪。这是完美的,这意味着其他地方的代码一定有问题。这太奇怪了。

没关系,我把它修好了。感谢@abarnert的帮助

如果其他人对此感到奇怪,我的朋友忘了在
root.mainloop()
调用之后添加
root.destroy()
调用。尽管包含此
destroy()
方法会使
\u tkinter.TclError
处于空闲状态,但它在编译时确实工作得很好

非常感谢


重新编辑:好的,我现在明白了。事实证明,我的朋友同时导入了
tkinter
tkinter
模块,由于安装了
python2.7
,我已经导入了这两个模块。这意味着程序试图调用每个与
Tkinter
相关的函数两次。
我做得很好。

这可能是您的问题,也可能不是您的问题,但是,从以下引用:

注意:一些Python开发环境在运行像这样的Tkinter示例时遇到问题。问题通常是环境本身使用Tkinter,而mainloop调用和quit调用与环境的期望相互作用。如果您忽略显式的destroy调用,其他环境可能会出现行为异常。如果示例的行为不符合预期,请检查开发环境中特定于Tkinter的文档

只有在特定开发环境下运行此示例时,才需要调用destroy;当事件循环终止时,它显式销毁主窗口。一些开发环境不会终止Python进程,除非这样做

这意味着,如果您从IDLE或其他基于tkinter的IDE启动应用程序,或者在Windows上,在某些情况下,从任何图形IDE启动应用程序,您可能必须在
root.mainloop()之后添加
root.destroy()

如果您怀疑这可能是问题所在,并且您正在使用IDE,那么首先要测试的是在IDE之外运行问题。打开cmd.exe(“DOS提示符”)窗口,然后执行以下操作:

cd C:\Path\To\Your\Program
C:\Path\To\Python\pythonw.exe YourScript.py
如果它现在工作正常,这很可能就是问题所在。因此,下一步是添加
root.destroy()
,并确保它在命令行和空闲状态下都能正常工作

但是,请注意,在某些情况下,这将导致tkinter引发并捕获异常,并记录有关该异常的虚假错误消息。如果您正在构建用于分发的应用程序,可能需要执行以下操作:

root.mainloop()
try:
    root.destroy()
except tkinter.TclError:
    # When the destroy isn't necessary, it's actually illegal. And we
    # don't know from inside the app whether it's necessary or not.
    pass

在我的机器上,该窗口不会再次出现。“假设所有按钮命令都已定义”没有帮助-请编辑以提供工作,包括任何导入(注意,您似乎正在从tkinter导入中执行
*
-不要)。全部
[X]
-图标按钮相关服务来自Tkinter,它能够为这个外部操作的图标botton配置事件处理程序例程。设置如下
root.protocol('WM\u DELETE\u WINDOW',lambda:None)
可以改变这种行为。可能会有更复杂的安排来模仿您的体验。虽然您的其他经验/故事无法从摘录的代码片段中重现。您是否试图在空闲(任何平台)或其他图形化IDE(仅限Windows)中运行此功能?如果是这样,通常在
root.mainloop()
之后需要一个
root.destroy()
。文件解释了为什么会在某处;如果这是问题所在,我可以了解细节。如果您不确定:如果您通过从命令行键入
pythonw
或在资源管理器中双击来运行此脚本,这不是您的问题;否则,请确切地解释一下你是如何运行它的,我可以试着解释一下如何判断。@abarnert:是的,空闲。我会试试的。正如我在回答中解释的,你可能想处理这个异常;除了IDLE之外,还有其他可能发生异常的情况,您可能不希望最终用户看到它。(而且,据我所知,无法从应用程序内部判断您的家长是否设置了您的家长会干扰的事件循环,这意味着除了尝试
destroy
)您不必在
mainloop()
之后调用
root.destroy()
,因为
mainloop()
在根窗口被销毁之前,永远不会退出。此外,导入两个tkinter库——虽然很糟糕——也不会产生您所说的行为。导入不会创建或破坏任何窗口。@BryanOakley:有什么可以备份的吗?因为abarnert的解决方案(现在是我接受的答案)引用了,这表明在
Tk
上运行的Windows IDE在使用
Tkinter
@Helloman892时存在问题:我不太理解你的问题。mainloop的实际实现设计为在根窗口被破坏后退出。当然,如果您在其他环境中运行tkinter,该环境可能会更改默认行为,但在其核心,当根窗口被破坏时,mainloop将退出。这就是它的设计目的。@Bryan:问题是“你能提供什么(例如链接)来证明你的陈述吗?”,至于
mainloop()
的实现,我知道。我完全知道
root.mainloop()
try:
    root.destroy()
except tkinter.TclError:
    # When the destroy isn't necessary, it's actually illegal. And we
    # don't know from inside the app whether it's necessary or not.
    pass