python - 在 tk 应用程序内触发关闭事件后,matplotlib 图不会继续程序流程

标签 python macos matplotlib tk-toolkit

我发现 Windows 和 Mac 处理 python tk 窗口和 matplotlib 图 close_event 的方式之间存在一个非常烦人的差异。

我的问题是,

  1. 我正在尝试从 tk 按钮事件加载 matplotlib 图形。
  2. 我想要显示该图,并阻止 tk UI 程序流程 绘图处于事件状态,并捕获用户事件,直到绘图结束 已关闭。
  3. 情节结束后,tk 应用程序应继续运行。

显示问题的最小示例应用程序。

from Tkinter import *
from matplotlib import pyplot as plt


class Plotter:
    def __init__(self):
        self.fig = plt.figure()
        self.fig.canvas.mpl_connect('close_event', self.dispose)

        plt.plot(1, 2, 'r*')
        plt.show()
        print "done with plotter"

    def dispose(self, event):
        plt.close('all')
        print "disposed"


if __name__ == '__main__':
    def pressed():
        print 'button pressed'
        Plotter()
        print 'YAY'

    root = Tk()
    button = Button(root, text='Press', command=pressed)
    button.pack(pady=20, padx=20)

    root.mainloop()

遗憾的是,我发现这在 Windows 中按预期工作,但在使用相同版本的 python2.7、matplotlib (1.5.2) 的 mac 上却不起作用。 除了这不是一个好的 UI 实践之外,令我困扰的是这段代码在 Mac 和 Windows 上存在差异。我将不胜感激任何有助于解决此问题的反馈,同时我将开始在非阻塞线程上实现绘图仪,并在关闭时将结果传递回主应用程序。

最佳答案

您可以使用plt.ion()打开Matplotlib的交互模式,但这本身会导致程序继续运行而不会阻塞流程。要手动阻止流程,请使用 self.fig.canvas.start_event_loop_default()self.fig.canvas.stop_event_loop() 暂停程序流程,直到捕获事件。

在您的最小示例中实现:

from Tkinter import *
from matplotlib import pyplot as plt

class Plotter:
    def __init__(self):
        plt.ion()
        self.fig = plt.figure()
        self.fig.canvas.mpl_connect('close_event', self.dispose)
        self.fig.canvas.mpl_connect('button_press_event', self.on_mouse_click)

        plt.plot(1, 2, 'r*')
        plt.show()
        self.fig.canvas.start_event_loop_default()
        print "done with plotter"

    def dispose(self, event):
        self.fig.canvas.stop_event_loop()
        print "disposed"

    def on_mouse_click(self, event):
        print 'mouse clicked!'


if __name__ == '__main__':
    def pressed():
        print 'button pressed'
        Plotter()
        print 'YAY'

root = Tk()
button = Button(root, text='Press', command=pressed)
button.pack(pady=20, padx=20)

root.mainloop()

关于python - 在 tk 应用程序内触发关闭事件后,matplotlib 图不会继续程序流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39130376/

相关文章:

c++ - 无法在 OSX Yosemite 上编译 googletest

python - 剪贴板到 .txt 文件或类似的 Python OSX

python - matplotlib 和 matplotlib-base 之间的区别?

python - Matplotlib 在 pandas 数据帧上使用 `scatter_matrix` 堆积直方图

Python矢量化嵌套for循环

python - heroku 服务器上的 django makemigrations 和 migrate 不创建表

python - 替换 numpy 数组中的负值

macos - Docker - all-spark-notebook - 安装本地驱动器

python - 在 matplotlib 中单独设置 xticklabels 的颜色

python - 如何使用 rpy2 在 python 中运行 R 脚本