我使用tkinter
和matplotlib.pyplot
遇到了一个我不明白的问题。
import tkinter
import tkinter.filedialog as tk_filedialog
import numpy as np
import matplotlib.pyplot as plt
def main():
# # -- part 1 --
# tkinter.Tk().withdraw()
junk = tk_filedialog.askopenfilename()
# # -- part 2 --
x_p = np.linspace(0,10,100)
fig = plt.figure()
plt.plot(x_p,x_p,color='b')
plt.show()
print("blob")
if __name__ == '__main__':
main()
print("blab")
我的实现最初是将行tkinter.Tk().withdraw()
取消注释,但是后来你看不到会发生什么。
上述程序将运行但不会终止。它应该执行以下步骤:
问题是被tkinter.Tk().withdraw()
抑制的Tkinter窗口不会关闭。这会导致两种意外行为 - 见下文。
最令人困惑的部分是:如果您评论-- part 1 --
或-- part 2 --
,程序将按预期运行。
关闭此tkinter窗口后,将打印“blob”和“blab”,程序将按预期终止。
与Cygwin相同的行为。
有什么想法吗?我是否错过了tkinter的close()
命令?
我发现了这个:
tk_window = tkinter.Tk()
tk_window.destroy()
但这并不能解决上述问题。
答案 0 :(得分:2)
在原始代码中,您使用tkinter.Tk()
显式创建了一个根窗口。像所有tkinter小部件类调用一样,这实际上创建了Python类的实例和 tk C结构。但是,不是将Python实例绑定到名称,以便稍后可以访问它,而是立即调用方法.withdraw()
。
在你的回答中,正确保留对root
(传统名称,如self
)的引用,这样你就可以在需要时销毁tk根结构而不是当程序退出时。
实际上,如果tkinter._support_default_root
为真,默认情况下为,则Tk()实例绑定到tkinter._default_root
。在原始代码中,您可以调用tkinter._default_root.destroy()
。但我强烈建议您保留自己的参考,就像在答案中所做的那样。
在禁用对Tk()的显式调用后,为什么原始代码继续工作,并且创建了根?因为如果tkinter._support_default_root
为真,那么tkinter会为您运行_default_root = Tk()
,作为一种便利,'}特征。但是,如果您希望隐藏的默认根在该过程的持续时间内保持不变,这将非常方便。
重复:你在答案中所做的是使用tkinter的标准,记录,正确的方式。
答案 1 :(得分:1)
经过大量的反复试验,我找到了解决方案。以下代码段替换了我的问题中的第一部分代码。
[...]
# # -- part 1 --
root = tkinter.Tk()
# root.withdraw()
cwd = os.getcwd()
junk = tk_filedialog.askopenfilename()
root.destroy()
# # -- part 2 --
[...]
似乎askopenfilename()
打开了tkinter的根窗口,但是不确保在执行该行之后它被关闭/销毁。