python - 另一个类的方法在调用时不能完全工作

标签 python matplotlib pyqt

我有这个代码:

class Matplotlib_figure(QMainWindow):
  minimumCoords = None
  maximumCoords = None
  initial_marker = None
  final_marker = None
  limite = None

  def __init__(self):
    #A lot of stuff to draw a matplotlib figure

  def minimumLimit(self):
    self.cMinL = self.figure_canvas.mpl_connect("button_press_event", self.select_minimumLimit)
    self.limite = "minimum"

  def select_minimumLimit(self, event):
    if event.button == 1:
        self.clearMarker()  #This is another method that i call

        Matplotlib_figure.minimumCoords = None
        Matplotlib_figure.minimumCoords = event.xdata

        if Matplotlib_figure.minimumCoords <= Matplotlib_figure.maximumCoords or Matplotlib_figure.maximumCoords == None:

            marker = self.axes.axvline(event.xdata,0,1, linestyle='dashed',
                linewidth = 2, color = "green" )    
            self.figure_canvas.draw_idle()
            Matplotlib_figure.initial_marker = marker


class Data(QDialog):
  minimum = None
  maximum = None

  def __init__(self, parent):
    QDialog.__init__(self, None, QWindowsStayOnTopHint)
    uic.loadUi("", self)

  def show_lines(self):
    SelectData.minimo = self.lineEdit.text()
    SelectData.maximo = self.lineEdit_2.text()

    Matplotlib_figure.minimumCoords = float(SelectData.minimo)
    Matplotlib_figure.maximumCoords = float(SelectData.maximo)

  #Here is where i want to call a method in the Matplotlib_figure class
    view = Matplotlib_figure()
    view.minimumLimit()
    view.maximumLimit()

问题出在 Data 类中。当我想调用Matplotlib_figure类中的minimumLimit方法(来自Data类中的show_lines)时,它不会触发figure_canvas.mpl_connect方法,并且 select_minimumLimit 方法不起作用。

我做错了什么?希望你能帮助我。

最佳答案

我认为关键问题来自matplotlib event handling docs中的这条注释。 :

The canvas retains only weak references to the callbacks. Therefore if a callback is a method of a class instance, you need to retain a reference to that instance. Otherwise the instance will be garbage-collected and the callback will vanish.

因此,您在 show_lines 方法中创建了一个新的view,但这是一个局部变量。当函数返回时,变量超出范围,Python 可能会尝试删除它。通常,如果您保存对方法的引用,则该方法将保留它所属的对象,而这种情况不会发生,但因为 mpl_connect 仅采用对函数 的弱引用它不保留 view,因此当 show_lines 返回时,该方法也会丢失,因此回调将恢复为不执行任何操作。

您可以通过重写 show_lines 来保存 View 来解决此问题,例如:

def show_lines(self):
    SelectData.minimo = self.lineEdit.text()
    SelectData.maximo = self.lineEdit_2.text()

    Matplotlib_figure.minimumCoords = float(SelectData.minimo)
    Matplotlib_figure.maximumCoords = float(SelectData.maximo)

    #Here is where i want to call a method in the Matplotlib_figure class
    self.view = Matplotlib_figure()
    self.view.minimumLimit()
    self.view.maximumLimit()

现在,只要 Data 实例存在,Matplotlib_figure 实例就会被保留。

[之前的答案基于下面保留的问题错误]

我不太了解 QT 框架或 matplotlib API,但在我看来,您已经创建了一个 ViewWidget 实例,它是一个完全独立的类( QT QMainWindow 类(如果我认识到的话)与 Matplotlib_figure 是一个完全不同的 python 模块。因此,我希望当您调用 minimumLimit() 时,您会收到 AttributeError 异常,并且我不希望它调用您的方法。如果您愿意,您必须创建它的实例并调用它:

view = Matplotlib_figure()
view.minimumLimit()
view.maximumLimit()

如果没有更多关于 ViewWidget 来源的上下文,很难理解您认为它应该如何工作。您创建的 matplotlib 图形是不相关的 QMainWindow 类的子类,这也有点奇怪。你想用这个实现什么目的?您能为代码提供更多上下文吗?

关于python - 另一个类的方法在调用时不能完全工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35703563/

相关文章:

javascript - Jasmine 中的 "Almost Equal"

python 将一组 fronzensets 合并为一组

python - python elementTree XML 解析器的性能问题

python - PyQt 启动时加载函数(qml 加载器)

python - PyQt 中的动态小部件添加

python - 使用 Python 脚本包装在 Bash-Shell 中输入的所有命令

python - 在 Matplotlib 中用上标或下标编写单位的最佳做法是什么?

python - 如何在 Seaborn 的热图轴上表达类

python - 使用带有 %matplotlib inline 的 ipython notebook 时如何保持当前图形?

python - 每个时间间隔用数据库更新表