我有root=Tk.Tk()
,它由标签(Tk.Label),参赛表格(Tk.Entry),按钮(Tk.Button)和嵌入式matplotlib FigureCanvasTkAgg
组成。这是一个简单的脚本,它绘制了由用户指定的系数(a,b,c)的四次函数。但是我在破坏主环时遇到了一些问题和误解。
我期待,主窗口的简单关闭(通过点击" x"在右下角)也应该导致从主循环退出。如果我要评论与嵌入画布相关的所有代码,我的脚本就是这种情况。但是使用嵌入式FigureCanvasTkAgg
,它不会发生(因此需要中断内核以便再次运行脚本)。正如其他questions中所讨论的,有两种退出主循环的方法:root.quit()
和root.destroy()
。所以我也尝试使用这些方法退出mainloop:
def close_all():
root.quit()
root.destroy()
按新按钮:
button_quit=Tk.Button(root, text="Quit", command=close_all)
button_quit.grid(row=5, column=1)
通过覆盖" x"按钮:
root.protocol('WM_DELETE_WINDOW', close_all)
我的问题:
使用这两种方法都有效。但是,如果我只使用root.destroy()
,root.mainloop()
仍会执行?关闭窗口后为什么不会销毁主循环?为什么这个问题导致FigureCanvasTkAgg
?
嵌入matplotlib图由以下完成(如果它有助于解释):
fig, ax = plt.subplots()
canvas = FigureCanvasTkAgg(fig, master=root)
plot_widget = canvas.get_tk_widget()
#(plotting with plt.plot(..))
canvas.show()
plot_widget.grid(row=6, column = 0, columnspan=3)
close_all()
函数在这个意义上起作用,已经执行了从mainloop退出,并且脚本执行停止了。但仍有一些奇怪的行为。有一些变量,例如var_a = Tk.StringVar()
,用于以某种方式从输入字段接收数据:
L_a = Tk.Label(master=root, width=10, height=2, bd =2, text="a")
E_a = Tk.Entry(master=root, width=10, bd =2, textvariable=var_a)
与
def get_value():
if not check_if_float(var_a.get()) or not check_if_float(var_b.get()) or not check_if_float(var_c.get()):
showerror(title = "Error", message = "Invalid entry. Enter integer or decimal numbers, please")
return None
a=float(var_a.get())
b=float(var_b.get())
c=float(var_c.get())
所以问题和奇怪的行为是在执行一次代码并关闭主窗口后(通过点击" x"在右上角,或点击"退出"按钮),在下一个执行代码中接收空var_a,var_b,var_c。如果内核中断,并且代码再次运行,它可以正常工作(在jupyter笔记本中运行它)。我不知道为什么会这样。
答案 0 :(得分:2)
这是因为您没有为主变量提供变量,因此它们默认为创建的第一个Tk()实例,即使它已被销毁。修复只是提供正确的根:
{{1}}
这通常不是一个问题,因为很少有你想要多次调用Tk()的情况。