Tkinter/Matplotlib 后端冲突导致无限主循环
Posted
技术标签:
【中文标题】Tkinter/Matplotlib 后端冲突导致无限主循环【英文标题】:Tkinter/Matplotlib backend conflict causes infinite mainloop 【发布时间】:2013-07-06 07:46:54 【问题描述】:考虑运行以下代码(注意这是一个非常简化的版本来演示问题):
import matplotlib.pyplot as plot
from tkinter import * #Tkinter if your on python 2
def main():
fig = plot.figure(figsize=(16.8, 8.0))
root = Tk()
w = Label(root, text="Close this and it will hang!")
w.pack()
root.mainloop()
print('Code never reaches this point')
if __name__ == '__main__':
main()
关闭第一个窗口可以正常工作,但关闭第二个窗口会导致代码挂起,因为root.mainloop()
会导致无限循环。这个问题是调用fig = plot.figure(figsize=(16.8, 8.0))
引起的。有谁知道在调用 matplotlib.pyplot 后如何让 root 成功关闭?
【问题讨论】:
pyplot
也启动了它自己的主循环,我怀疑这是你的问题。请参阅matplotlib.org/examples/user_interfaces 了解如何将 mpl 嵌入到您选择的 gui 中
有没有办法强制关闭 pyplot 主循环?该问题会影响 pyplot 调用后的所有后续 tkinter 窗口,即使在不同的模块中也是如此。
【参考方案1】:
import matplotlib
from tkinter import *
def main():
fig = matplotlib.figure.Figure(figsize=(16.8, 8.0))
root = Tk()
w = Label(root, text="Close this and it will not hang!")
w.pack()
root.mainloop()
print('Code *does* reach this point')
if __name__ == '__main__':
main()
在 Tkinter
窗口中嵌入 matplotlib 图形时,请使用 matplotlib.figure.Figure
而不是 plt.Figure
。
【讨论】:
我的答案仍然有效——尤其是使用matplotlib.figure.Figure
而不是plt.Figure
。仅此更改即可使您的代码正常工作。
很酷,我需要一行代码,你能解释一下 matplotlib.figure.Figure 和 plt.Figure 之间的后端区别,因为它适用于主循环吗?谢谢!
plt.figure
使用图形管理器来处理 mainloop/gui 等。 matplotlib.figure.Figure
只是一个 Figure
对象,而与 gui 争吵是你的问题。【参考方案2】:
我通过在打开 Tkinter 窗口之前“关闭”matplotlib 绘图(绘图完成后)解决了 matplotlib 与 Tkinter 冲突的问题:
plt.close()
tk = Tkinter()
...
【讨论】:
以上是关于Tkinter/Matplotlib 后端冲突导致无限主循环的主要内容,如果未能解决你的问题,请参考以下文章
无法使用按钮和自定义数据更新 Tkinter matplotlib 图