Python 按钮在第二个(嵌套)图形中不起作用

Python 按钮在第二个(嵌套)图形中不起作用,python,button,matplotlib,fedora,Python,Button,Matplotlib,Fedora,我想我在Matplotlib中遇到了一个bug,尽管我真的希望它只是我缺少的一些简单的东西 我正在编写的代码在Ubuntu11.10、Ubuntu12.04和MacOS上运行良好。最近我在我的机器上安装了Fedora18,我注意到Matplotlib有一些问题:我有一个带按钮的图形。单击按钮,将打开另一个窗口,其中也有一些按钮。在我的Fedora系统上,第二个窗口中的按钮处于非活动状态。它们不响应悬停(不改变颜色),也不响应单击 下面是一小段模拟此问题的代码。这在我的Ubuntu 12.04上运

我想我在Matplotlib中遇到了一个bug,尽管我真的希望它只是我缺少的一些简单的东西

我正在编写的代码在Ubuntu11.10、Ubuntu12.04和MacOS上运行良好。最近我在我的机器上安装了Fedora18,我注意到Matplotlib有一些问题:我有一个带按钮的图形。单击按钮,将打开另一个窗口,其中也有一些按钮。在我的Fedora系统上,第二个窗口中的按钮处于非活动状态。它们不响应悬停(不改变颜色),也不响应单击

下面是一小段模拟此问题的代码。这在我的Ubuntu 12.04上运行良好,但在Fedora上不起作用。它的工作原理如下:用一个大按钮显示一个图形,如果你点击这个按钮,它将显示另一个图形,而这个图形又有一个按钮。如果一切正常,第二个按钮应响应悬停,并在单击时向终端打印内容

import pylab
from matplotlib.widgets import Button


def draw_button1(event):

    pylab.figure()
    a = pylab.axes([0.1, 0.1, 0.8, 0.8])
    b = Button(a, 'Button 1')

    def say_something(event):
        print "This works."

    b.on_clicked(say_something)
    pylab.show()

def draw_button2():
    pylab.figure()
    a = pylab.axes([0.1, 0.1, 0.8, 0.8])
    b = Button(a, 'Button 2')
    b.on_clicked(draw_button1)
    pylab.show()

draw_button2()
我不知道是什么原因造成的。我尝试了很多方法:

  • 我安装了来自yum repository的Matplitlib 1.2.0、1.2.1以及我从源代码构建的最新1.3.0rc2。他们都做同样的事。我还安装了Matplotlib的所有相关依赖项,甚至是那些可选的

  • 我试着在我的Fedora机器上,在Ubuntu 12.04上远程运行我的代码。。也许X渲染这些窗口的方式有问题?仍然在我的Ubuntu上工作,在我的Fedora上渲染

  • 谷歌在这个问题上大发雷霆,但这并没有真正起到作用。人们建议使用
    pylab.ion()
    pylab.ioff()
    进行交互式绘图,但这也没有帮助

  • 如果有任何帮助,下面是我的Matplotlib构建:

    BUILDING MATPLOTLIB
                matplotlib: yes [1.3.0rc2]
                    python: yes [2.7.3 (default, Aug  9 2012, 17:23:57)  [GCC
                            4.7.1 20120720 (Red Hat 4.7.1-5)]]
                  platform: yes [linux2]
    
    REQUIRED DEPENDENCIES AND EXTENSIONS
                     numpy: yes [version 1.7.1]
                  dateutil: yes [using dateutil version 1.5]
                   tornado: yes [using tornado version 3.1]
                 pyparsing: yes [using pyparsing version 1.5.6]
                     pycxx: yes [Couldn't import.  Using local copy.]
                    libagg: yes [pkg-config information for 'libagg' could not
                            be found. Using local copy.]
                  freetype: yes [version 15.0.9]
                       png: yes [version 1.5.13]
    
    OPTIONAL SUBPACKAGES
               sample_data: yes [installing]
                  toolkits: yes [installing]
                     tests: yes [using nose version 1.3.0]
    
    OPTIONAL BACKEND EXTENSIONS
                    macosx: no  [Mac OS-X only]
                    qt4agg: no  [PyQt4 not found]
                   gtk3agg: yes [version 3.4.6]
                 gtk3cairo: yes [version 3.4.6]
                    gtkagg: yes [Gtk: 2.24.18 pygtk: 2.24.0]
                     tkagg: no  [The C/C++ header for Tk (tk.h) could not be
                            found.  You may need to install the development
                            package.]
                     wxagg: no  [requires wxPython]
                       gtk: yes [Gtk: 2.24.18 pygtk: 2.24.0]
                       agg: yes [installing]
                     cairo: yes [version 1.8.10]
                 windowing: no  [Microsoft Windows only]
    
    OPTIONAL LATEX DEPENDENCIES
                    dvipng: yes [version 1.14]
               ghostscript: yes [version 9.06]
                     latex: no
                   pdftops: yes [version 0.20.2]
    

    非常感谢

    您遇到了范围界定问题。当button对象超出范围时,它的所有回调都将被清除。要使按钮正常工作,需要保留对周围
    按钮
    对象的引用

    def draw_button2():
        pylab.figure()
        a = pylab.axes([0.1, 0.1, 0.8, 0.8])
        b = Button(a, 'Button 2')
        b.on_clicked(draw_button1)
        pylab.show()
        return b
    
    b = draw_button2()
    
    这将使您的第一个按钮工作,但要使第二个按钮工作,您将需要某种全局结构。最简单的方法是将所有这些函数封装在一个类中以跟踪它们,最简单的方法是向figure对象添加属性:

    import pylab
    from matplotlib.widgets import Button
    
    
    def draw_button1(event):
        fig = pylab.figure()
        a = pylab.axes([0.1, 0.1, 0.8, 0.8])
        b = Button(a, 'Button 1')
    
        def say_something(event):
            print "This works."
    
        b.on_clicked(say_something)
        fig._my_btn = b
        pylab.show()
    
    def draw_button2():
        fig = pylab.figure()
        a = pylab.axes([0.1, 0.1, 0.1, 0.1])
        b = Button(a, 'Button 2')
        b.on_clicked(draw_button1)
        pylab.show()
        fig._my_btn = b
    
    
    draw_button2()
    

    非常感谢。这确实解决了它!因此,实际上它在我的其他系统上也不应该工作得很好……再一次,每当我认为我在某个库中发现一个bug时,结果证明它是错误的。:)@戴安娜:你读过按钮的例子吗?()如果是的话,我会提交一份PR,明确这一点很重要。至于为什么它在任何地方都能工作,有一些变化是在一段时间前回调的工作方式(更改->weakrefs),但我不确定这在发布的版本中会出现在哪里。是的,我在大约六个月前根据这个例子编写了我的代码。但这一次,除了这个,我真的在其他地方寻找问题。它在我的其他系统上工作,所以我认为我很可能做对了,问题出在Matplotlib的某个地方。非常感谢你的提示!