我正在尝试具有3个单独的包含不同事物的窗口(图)。我不会提前确定每个窗口的内容,因为这些窗口只是容器。但是从广义上讲,一个或几个窗口将包含数据图,而一个窗口将包含这些(交互式)图的大多数(也许是全部)控制器。
因此,基本上,我正在围绕matplotlib编写包装代码,以便用户可以受益于预定义的模板来显示数据。将有一些预定义的模具,随着时间的流逝,将添加新的模具。
所以我正在做这样的事情:
class DefaultViewer:
def __init__(self, **kwargs):
self.graph_win = ContainerWindow(label='Some Graph')
self.ctrl_win = ContainerWindow(label='Controller elements')
# other code here....
def set_controllers(self):
self.sld_gstart = ElementControlSlider(self.ctrl_win.grid, xpos=0, label='Gate Start')
self.sld_gwidth = ElementControlSlider(self.ctrl_win.grid, xpos=1, label='Gate Width')
self.sld_saturation = ElementControlSlider(self.ctrl_win.grid, xpos=2, label='Saturation')
(稍后可能会有一些OtherViewer类可以使用不同的窗口)。
容器窗口。它提供了一些有用的默认值,否则它还将接受传递来覆盖这些默认值的所有内容:
class ContainerWindow:
""" Contains the ElementControlers in a single window, and/or the graphs etc. """
def __init__(self, nrows=5, ncols=12, width_pad=0.4, heigh_pad=0.4, figsize=(12,12), label='A ContainerWindow' ,**kwargs):
# Uses the default parameters or the value provided if any
self.nrows = nrows
self.ncols = ncols
self.figsize = figsize
self.figure= plt.figure(label, figsize=figsize)
self.grid = plt.GridSpec(nrows, ncols, wspace=width_pad, hspace=heigh_pad, figure=self.figure)
最后是ElementControlSlider:
class ElementControlSlider:
def __init__(self, grid, xpos=1,ypos=1, width=5, label='' , val_min=0, val_max=100, init_val=50, text_box_pos=(0,0),**kwargs):
self.ax_slider = plt.subplot(grid[xpos, ypos:ypos+width], label=label)
self.ax_text = plt.subplot(grid[xpos, ypos + width + 1], label=label)
self.slider = Slider(self.ax_slider, label, val_min, val_max, valinit=init_val)
self.slider.valtext.set_visible(False)
self.textbox = TextBox(self.ax_text, '', self.slider.val)
def update_text(self, value):
try:
val = int(value)
assert(val > 0)
except (ValueError, AssertionError):
self.textbox.set_val(str(self.slider.val))
else:
self.slider.set_val(val)
我对matplotlib的理解似乎是错误的。我本质上是在每个ContainerWindow中实例化一个不同的图形(self.figure = plt.figure(....)。它们得到了不同的标签,如果我在Pycharm中进行调试,它们的确是不同的对象-到目前为止很好。 >
然后我在每个窗口中实例化一个网格(GridSpec(...))。因此,每个窗口都有其自己的网格(将要在其中放置图形和/或控制器元素的网格)。对于每个网格,我都会引用该窗口的图形。
然后,当我实例化一个控制器元素时,我将其传递给将要放置其的网格的引用(具有对其父图的引用的网格,例如,我希望它驻留在其中的WindowContainer )。
但是,如果我更改了ContainerWindow的声明顺序,则会将滑块分配给错误的图形/窗口。
为什么我的对象引用最终错误?我该如何做,以便无论实例化窗口的顺序如何,我的滑块最终都正确无误?