重新打开GTK和matplotlib窗口 - GTK窗口为空

1 投票
1 回答
1168 浏览
提问于 2025-04-17 14:26

我的程序是用 GTKglade 开发的,它可以接收一些数据,并且有一个选项可以显示一个单独的窗口,这个窗口里有一个 matplotlib 散点图 来表示这些数据。

我遇到的问题是,如果用户关闭了图表的 窗口,再重新打开时,图表不会显示。窗口里只是空空的 GTK Window 我相信这个问题有简单的解决办法,但关于我的问题(或者说 GTKmatplotlib 的结合)相关的资源并不多。

我为我的 散点图 创建了一个 模块,这样我可以方便地重复使用它。我只是想让它正常工作,所以代码的结构并不是特别完美。

##Scatterplot Module:

import gtk
import matplotlib
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
from matplotlib.figure import Figure


class ScatterPlot:
    def __init__(self):
       self.window = gtk.Window()
       self.window.connect("destroy", lambda x: self.destroy())
       self.window.set_default_size(500,400)
       self.is_hidden = False

       self.figure = Figure(figsize = (5,4), dpi=100)
       self.ax = self.figure
       self.ax = self.ax.add_subplot(111)
       self.canvas = FigureCanvas(self.figure)
       self.window.add(self.canvas)

       self.Xs = list()
       self.Ys = list()

   def set_axis(self, xLimit = (0,384) , yLimit = (0,100)):
       self.ax.set_xlim(xLimit)
       self.ax.set_ylim(yLimit)

   def plot(self, xs, ys):
       self.Xs.extend([xs])
       self.Ys.extend([ys])
       self.ax.plot(xs,ys,'bo')

   def update(self):
       self.window.add(self.canvas)

   def set_title(self, title):
       self.ax.set_title(title)

   def show(self):
       self.window.show_all()
       self.is_hidden = False

   def hide(self):
       self.window.hide()
       self.is_hidden = True

   def destroy(self):
       self.window.destroy()

我这样调用这个模块:

class GUI:
    def __init__(self):
        self.scatterplot = scatterplot.ScatterPlot()

        #When the user presses the "Graph" button it calls the following function
    def graph():
        self.scatterplot.plot(someDataX, someDataY)
        self.scatterplot.set_axis()
        self.scatterplot.set_title("Some Title")
        self.scatterplot.show()

(这只是我的代码长什么样的一个例子。)

散点图 关闭时,我调用的是 self.window.destroy 而不是 self.window.hide。当尝试重新打开时,我调用同样的 graph() 函数,但正如上面所说,GTK Window 并没有显示图表。(第一次打开时,它显示得很好)

我的猜测:

  • 我是不是应该用 .hide() 而不是 .destroy()
  • scatterplot 的构造函数里有没有需要再次调用的代码来创建 plot
  • 还是说我每次调用 graph() 时都应该重新实例化 plot

1 个回答

1

我的解决方案:

来自:

class ScatterPlot:
    def __init__(self):
        #remove the following two lines
        self.canvas = FigureCanvas(self.figure)
        self.window.add(self.canvas)

把这两行代码移动到 show() 函数里

def show(self):
    self.canvas = FigureCanvas(self.figure)
    self.window.add(self.canvas)
    self.window.show_all()
    self.is_hidden = False

这样移动这两行代码后,当你重新打开窗口时,图形就能显示出来了。

顺便提一下,关闭窗口时调用 .destroy().show() 都可以。我不太确定哪一个更好。

撰写回答