PySide QPushButton 和 matplotlib 的连接

3

我正在尝试使用matplotlib开发一个非常简单的pyside/Qt程序。我希望在按下按钮时绘制一张图表。到目前为止,我可以在构造函数中绘制一些内容,但是我无法将Pyside事件与matplotlib连接起来。有没有办法做到这一点?

import sys
import platform

import numpy as np
import PySide
from PySide.QtGui import QApplication, QMainWindow, QTextEdit,\
                         QPushButton,  QMessageBox, QWidget, QVBoxLayout
from PySide import QtCore



__version__ = '0.0.1'


import matplotlib

matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas


class MainWindow(QMainWindow):


    def __init__(self, parent=None):

        super(MainWindow, self).__init__(parent)

        self.main_frame = QWidget()
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent( self.main_frame )
        self.axes = self.figure.add_subplot(111)
        vbox = QVBoxLayout( )
        vbox.addWidget( self.canvas )
        self.main_frame.setLayout( vbox )
        self.setCentralWidget( self.main_frame )
        self.button = QPushButton('Run')

    def button_pressed(self):
        data1 = np.loadtxt('FStream.dat')
        data2 = np.loadtxt('FShield.dat')
        self.axes.plot(data1[0],data1[1],data2[0],data2[1])
        print 'pressed'
        self.canvas.draw()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    frame = MainWindow()

    frame.button.clicked.connect(frame.button_pressed)
    frame.button.show()  


    frame.show()
    app.exec_()

非常感谢!

编辑:将代码修改为调用draw()。

编辑2:将不同的功能分离到不同的函数中,现在看起来是这样的:

import sys
import platform

import numpy as np
import PySide
from PySide.QtGui import QApplication, QMainWindow, QTextEdit,\
                         QPushButton,  QMessageBox, QWidget, QVBoxLayout
from PySide import QtCore



__version__ = '0.0.1'

from ui_pygradient_uni import Ui_MainWindow
import matplotlib
import widgets.matplotlibwidget

matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'

#from matplotlib.figure import Figure
#from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas


class MainWindow(QMainWindow):


    def __init__(self, parent=None):

        super(MainWindow, self).__init__(parent)

        self.main_frame = widgets.matplotlibwidget.MatplotlibWidget()

        self.button = QPushButton('Run')

        vbox = QVBoxLayout( )
        vbox.addWidget( self.main_frame.canvas )
        self.main_frame.setLayout( vbox )
        self.setCentralWidget( self.main_frame )

    def button_pressed(self):
        data1 = np.loadtxt('FStream.dat')
        data2 = np.loadtxt('FShield.dat')
        self.axes.plot(data1[0],data1[1],data2[0],data2[1])
        self.canvas.draw()
        print 'pressed'


if __name__ == '__main__':
    app = QApplication(sys.argv)
    frame = MainWindow()

    frame.button.clicked.connect(frame.main_frame.Plot)
    frame.button.show()  


    frame.show()
    app.exec_()

而 matplotlibwidget 就像这样:

import matplotlib
import numpy as np


matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'


from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas



class MatplotlibWidget(FigureCanvas):

    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(Figure())

        self.setParent(parent)
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.axes = self.figure.add_subplot(111)


    def Plot(self):


        data1 = np.loadtxt('FStream.dat')
        data2 = np.loadtxt('FShield.dat')

        self.axes.plot(data1[0],data1[1],data2[0],data2[1])
        self.canvas.draw()

您点击信号的连接看起来应该可以正常工作。button_pressed()插槽没有被调用吗?您能否更具体地说明什么不起作用? - jdi
按钮正在被按下,连接正在工作 - 终端上显示“pressed”。但是图表没有被重新绘制。 - Ivan
你试过@jeff的答案了吗?他是在我问那个问题之后发布的。 - jdi
绘图已经成功了,但为什么每次都必须重新绘制图形呢?如果self.canvas没有连接到MainWindow而是在Widget中,会发生什么?self.canvas.setParent()应该连接什么? - Ivan
@Ivan,你确实已经将self.canvas与小部件连接起来了,就是你的self.main_frame - Jeff
刚刚重写了它,是的,谢谢你指出来。 - Ivan
1个回答

2

尝试输入

self.canvas.draw()

之后

self.axes.plot(data1[0],data1[1],data2[0],data2[1])

您的GUI代码看起来没问题,button_pressed 被正确调用,但图表没有被重新绘制。

问题就在这里,而且它起作用了。为什么每次都必须重新绘制图形呢? - Ivan
@Ivan,我不确定为什么我们必须显式调用“draw”。我认为“plot”方法应该为我们完成它。 - Jeff
我猜这是因为轴对象不一定是显示对象(画布),也许您希望在决定现在应该发生绘制事件之前绘制多次? - jdi
嗯,也许吧。我还在尝试弄清楚matplotlib中Figure、Canvas和Axes之间的区别。谢谢。 - Ivan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接