使用PyQt中的Signals在类之间传递数据

时间:2016-02-06 19:10:58

标签: python matplotlib pyqt signals-slots

我需要使用一个信号连接两个不同的类,该信号将变量中的文本从一个类发送到另一个类。

第一堂课是Matplotlib。我在导航工具栏中添加了QPushButton,以使用QDialog访问QLineEdit(这是另一个类)。我需要使用变量将QLineEdit中写的文本发送到Matplotlib图的类中,这样我就可以在图中创建一个注释。

这是到目前为止的代码:

class Dialog(QDialog):

  list_of_notes = []         #I create a list to add text, each time i open the QDialog

  def __init__(self):
    #A lot of stuff in here

  def printVariable(self, text):
    Dialog.lisf_of_notes.append(text)
    MatplotlibFigure().addNote()

    self.close()

class MatplotlibFigure(QMainWindow):
  def __init__(self):
    #A lot of stuff in here

   self.axes = self.figure_canvas.figure.add_subplot(111)

  def addNote(self):
   for i,s in enumerate(Dialog.list_of_notes):
     note = self.axes.annotate(i, xy=(0.2, 0.2))  #This is the note i want to create
     note.draggable()
     self.figure_canvas.draw_idle()

因此,当我按下QDialog中的“接受”按钮时,我可以看到文本已添加到列表中,每次打开对话框时。但是,当我想从我添加到列表中的最后一个对象创建注释时,在for循环中没有任何反应。

有什么问题?希望你能帮帮我。

----------------编辑----------------------------- < / H2>

我做了一些修改。我创建了一个信号mysignal来发出变量text,其中包含我在QDialog中写的文字。

这是修改后的代码:

class Dialog(QDialog):
  def __init__(self, my_figure):

    mysignal = pyqtSignal(str)

    self.my_figure = MatplotlibFigure()
    QDialog.__init__(self)

    self.connect(self.btn_accept, SIGNAL("clicked()"), self.send_text)
    self.mysignal.connect(self.printVariable)

  def send_text(self):              #I get the text from the QLineEdit and send it using 
    text = self.lineEdit.text()     #the created signal
    self.mysignal.emit(text)

  def printVariable(self, text):
    self,my_figure.addNote(text) 
    self.close()

class MatplotlibFigure(QMainWindow):
  def __init__(self):
    QMainWindow.__init__(self)
    self.notes_list =[]

  def openDialog(self, text):    #I open the QDialog clicking a button
    textMat = Dialog(text)
    textMat.exec_()

  def addNote(self, text):
    self.notes_list.append(text)

    notes = self.axes.annotate(text, xy=(0.2, 0.2), bbox = dict(facecolor="red"))
    notes.draggable()
    self.figure_canvas.draw_idle()

所以,我打开QDialog,我可以写文字。它正确地添加到列表中,但图中仍未绘制该注释。

1 个答案:

答案 0 :(得分:3)

问题在于代码行

MatplotlibFigure().addNote()

此行实例化MatplotlibFigure类的 new 实例,并调用addNote方法。但是,每次打开对话框时,您都不想创建新的图形,您希望将注释添加到(可能)预先存在的MatplotlibFigure实例中。

因为您没有显示创建QDialog的代码,所以很难建议选项,但是可以将对现有MatplotlibFigure的引用传递给构造函数QDialog。例如

class Dialog(QDialog):

  list_of_notes = []         

  def __init__(self, my_figure):
      self.my_figure = my_figure
      ...

  def printVariable(self, text):
      Dialog.list_of_notes.append(text)
      self.my_figure.addNote()

      self.close()

修改您创建Dialog的代码,以传递对图的引用。例如my_dialog = Dialog(reference_to_my_figure)

我还想指出,将注释列表存储在类属性中并不是一种特别好的编码实践。我不认为你甚至需要存储笔记列表,除非你打算重复使用它们(你的当前代码会在每次添加新笔记时再次添加所有以前添加的笔记。这样的东西应该可以正常工作(如果你真的想这样做,我已经在列表中包含了可选的存储空间

class Dialog(QDialog): 

  def __init__(self, my_figure):
      self.my_figure = my_figure
      ...

  def printVariable(self, text):
      self.my_figure.addNote(text)

      self.close()


class MatplotlibFigure(QMainWindow):
  def __init__(self):
      #A lot of stuff in here
      self.notes_list = []
      self.axes = self.figure_canvas.figure.add_subplot(111)

  def addNote(self, text):
      #optional
      self.notes_list.append(text)

      # now add the note to the figure
      note = self.axes.annotate(text, xy=(0.2, 0.2))  #This is the note i want to create
      note.draggable()
      self.figure_canvas.draw_idle()

但请注意,所有注释都将指向图(0.2,0.2)上的相同位置(我假设您将在以后的代码中修复此问题)。

我还建议你做一些关于面向对象编程的Python教程,特别是涉及类与实例(或对象),类属性与实例属性以及如何设计可重用类的东西。看起来你的一些问题源于你并不完全理解这些概念。