用于GDB python漂亮打印机的非阻塞pyplot GUI

时间:2014-07-24 02:54:55

标签: python matplotlib tkinter gdb pretty-print

我只是想在调试时使用matplotlib来显示一些数据。请关注此页面:Analyzing C/C++ matrix in the gdb debugger with Python and Numpy - CodeProject,除非matplotlib GUI仅阻止GDB的命令行,否则它可以正常工作。这意味着如果我打开GUI窗口,GDB的命令行就会冻结,在关闭pyplot窗口之前我无法在GDB命令中输入任何内容。

要解决这个问题,我只是尝试在另一个线程中运行绘图代码,以简化测试用例,我只需创建一个名为“test-pyplot.py”的简单python源代码,其内容如下

import numpy as np
from matplotlib import pyplot as plt
from threading import Thread

class MyThread (Thread):

    def __init__(self, thread_id):
        Thread.__init__(self)
        self.thread_id = thread_id

    def run(self):
        x = np.arange(0, 5, 0.1);
        y = np.sin(x)
        plt.plot(x, y)
        plt.show(block = True) #this cause the mainloop

thread1 = MyThread(1)
thread1.start()

现在,在GDB命令行下,我只需键入:source test-pyplot.py,一个非阻塞的GUI将打开,看起来很好,GDB的命令行仍然可以接受命令,到目前为止一直很好。

但问题发生在我关闭绘图窗口时,然后我再次运行source test-pyplot.py,这次,GDB只是挂起。

我在Windows下使用python 2.7.6,我发现matplotlib默认使用tkAgg作为绘图后端,所以我试着看看这是否会发生在普通的tk GUI窗口中。这是另一个名为“test-tk.py”的测试python文件,其内容如下:

from Tkinter import *
from threading import Thread
class App():
    def __init__(self):
        self.g=Tk()
        self.th=Thread(target=self.g.mainloop)
        self.th.start()
    def destroy(self):
        self.g.destroy()
a1 = App()

如果我在GDB提示符下运行命令source test-tk.py,将显示一个tk窗口,GDB仍处于活动状态(未冻结),我可以关闭tk窗口,并输入命令source test-tk.py再次,一切正常,GDB不会挂起。我甚至可以在不关闭第一个tk窗口的情况下运行命令source test-tk.py两次,然后会显示两个tk窗口。

问题:如何在非阻塞模式下正确显示matplotlib pyplot图,哪些不挂GDB?谢谢。 通常,plt.show将在内部调用Tkinter包的mainloop函数,这是一个事件循环。 matplotlib有一个名为interactive mode的选项,可以通过调用`plt.ion()来启用它,但它不能解决我的问题。

1 个答案:

答案 0 :(得分:2)

有多个问题。而FWIW我想我之前曾经研究过这个问题,搜索gdb bugzilla。

无论如何,一个问题是你应该在一个单独的线程中运行GUI。这避免了缺乏主循环集成。这对程序来说有点困难,不过你可以使用Python技巧来减轻它的痛苦。

此外,GUI工具包通常会破坏SIGCHLD,这会破坏gdb。所以你必须使用黑客来解决这个问题。

您可以在我的概念验证gdb GUI中看到我如何处理这些问题:https://gitorious.org/gdb-gui