在tkinter mainloop

时间:2017-09-18 12:21:38

标签: python matplotlib tkinter multiprocessing

我一直面临一个暗示Matplotlib,Tkinter和多处理的问题。进程:

我写了一个程序,创建一个Tkinter窗口来询问用户输入。一旦tkinter窗口关闭,它就会产生几个进程,其中一些进程使用matplotlib绘制数据。我用Python 2.7.6和Linux(Ubuntu 14.04)运行程序。

两个部分都可以自行运行,只有当它们组合在一起时才会崩溃,显示以下错误,有时甚至会冻结X服务器。

XIO:  fatal IO error 11 (Resource temporarily unavailable) on X server ":0.0"
  after 167 requests (167 known processed) with 17 events remaining.
XIO:  fatal IO error 0 (Success) on X server ":0.0"
  after 171 requests (171 known processed) with 19 events remaining.

这段代码系统地为我重现了这个问题:

import Tkinter as tk
from time import sleep
from multiprocessing import Process
import matplotlib.pyplot as plt

class Plotter(Process):
  """
  A minimalist version of the plotting process, to illustrate
  """
  def run(self):
    f = plt.figure()
    plt.show(block=False)
    while True:
      sleep(.2)
      f.canvas.draw()
      print("-Loop")

if __name__ == "__main__":
  # If these two lines are commented, the two mpl windows show up
  # and both processes loop fine
  root = tk.Tk()
  root.mainloop() # Wait for the user to quit the main window
  # End of the first part: the Tkinter window is now closed

  p1 = Plotter()
  p2 = Plotter()

  p1.start()
  p2.start() # If this line is commented, the program runs fine

此程序将弹出一个tkinter窗口。当用户关闭时,程序崩溃,有时导致所有窗口锁定,直到Python通过tty被杀死。 有趣的是,如果只启动其中一个进程,它运行正常。更有趣的是,如果省略Tkinter窗口,即使有两个或更多进程,一切都运行良好。据我测试,崩溃只发生在tkinter和两个或多个进程创建matplotlib数字。

我在两台不同的机器上测试了这个程序,使用matplotlib 1.3.1和2.0.2,两者都出现同样的问题。我可能错过了matplotlib和tkinter之间的微妙交互,但我希望这个代码能够运行这两个进程,即使之前关闭了tkinter应用程序。

有谁知道为什么会这样?如何在tkinter窗口的主循环方法后使用matplotlib生成进程?

谢谢

1 个答案:

答案 0 :(得分:0)

由于我找不到这个问题的任何答案,我提出了一个解决方法: 我使用了matplotlib的另一个后端,而不是依赖于Tk。我之所以选择Qt4Agg,是因为我无法让其他人工作。

为此,只需添加

即可
import matplotlib
matplotlib.use("qt4agg")

之前导入pyplot。 您也可以使用

import matplotlib.pyplot as plt
plt.switch_backend("backend")

这可以在导入pyplot后完成,但请注意,这是一个实验性功能!

切换后端后,我不得不在代码中更改一些内容。例如,除非我调用plt.pause(.01),否则不会弹出或更新绘图窗口,这对于TkAgg来说是不必要的。

我认为这种自我回复只是部分解决方案,因为它没有解决或解释问题。