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 动画填充内存

无法使用按钮和自定义数据更新 Tkinter matplotlib 图

对于实时数据,Tkinter matplotlib 画布更新太慢

Vue.js 前端路由与后端烧瓶路由冲突

导致项目冲突的7个因素,还有人不知道吗?

如何找出导致冲突的 Git 提交?