调用时,来自另一个类的方法不能完全起作用

时间:2016-02-29 15:40:50

标签: 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类中。当我想调用minimumLimit类中的Matplotlib_figure方法(来自Data类中的show_lines)时,它不会触发figure_canvas.mpl_connect方法,并且select_minimumLimit方法不起作用

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

1 个答案:

答案 0 :(得分:1)

我认为关键问题来自matplotlib event handling docs

中的这一说明
  

画布仅保留对回调的弱引用。因此,如果回调是类实例的方法,则需要保留对该实例的引用。否则,实例将被垃圾收集,回调将消失。

所以你在view方法中创建了一个新的show_lines,但这是一个局部变量。当函数返回时,变量超出范围,python可能会尝试删除它。通常,如果将方法的引用保存为off,则该方法会保留对象的方法,但这不会发生,但因为mpl_connect只对函数进行弱引用,所以它不会保留view ,因此当show_lines返回时,该方法也会丢失,因此回调将恢复为什么都不做。

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

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()

现在只要Matplotlib_figure实例是Data实例,就会保留ViewWidget实例。

[基于有问题的错误的先前答案]

我不太了解QT框架或matplotlib API,但在我看来,您已经创建了QMainWindow的实例,这是一个完全独立的类(子类)来自Matplotlib_figure的QT minimumLimit()类,如果我认识到这是一个完全不同的python模块。因此,当您致电AttributeError时,我会指望您获得view = Matplotlib_figure() view.minimumLimit() view.maximumLimit() 例外,我不希望它会调用您的方法。如果你想要,你必须创建一个实例并调用它:

ViewWidget

如果没有更多关于matplotlib来自何处的背景,很难理解您认为这应该如何运作。你正在创建一个QMainWindow数字,这是一个不相关的SELECT dept.DeptName, COUNT(emp.EmpId) AS NUM_OF_EMPLOYEES FROM Dept dept INNER JOIN Employee emp ON dept.DeptId = emp.deptId GROUP BY dept.DeptName; 类的子类,这有点奇怪。你想用这个来实现什么?你能为代码提供更多的上下文吗?