与在python代码中使用Qt Designer创建的MatplotlibWidget交互

时间:2013-08-13 18:47:15

标签: python matplotlib pyqt python-embedding

我遇到了与我通过Qt Designer创建的MatplotlibWidget交互的问题。我无法更改轴标签,比例,提供标题或任何内容。我做错了吗?

这是使用Qt Designer生成的示例UI代码:

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.mplwidget = MatplotlibWidget(self.centralwidget)

        self.mplwidget.setGeometry(QtCore.QRect(70, 50, 400, 300))
        self.mplwidget.setObjectName("mplwidget")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

from matplotlibwidget import MatplotlibWidget

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QMainWindow.__init__(self, parent, f)

        self.setupUi(self)

这是我编写的用于与UI python代码交互的python代码:

from PyQt4 import QtGui, QtCore
from TestUI2 import MainWindow

class Window(MainWindow):
    def __init__(self):
        MainWindow.__init__(self)

        x=[0,10,100]
        y=[3,4,5]

        self.mplwidget.axes.set_xscale('log') # Nothing Happens 
        self.mplwidget.axes.set_title('GRAPH') # Nothing Happens

        self.mplwidget.axes.plot(x,y) 


if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

4 个答案:

答案 0 :(得分:1)

您需要首先为MatplotlibWidget定义自己的类(在主脚本中,而不是UI代码中),然后在Window()定义中将其实例化。要做到这一点,你还需要从_qt4agg matplotlib后端模块和图类中导入FigureCanvas:

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

然后在Matplotlib类定义中创建Figure子图和Figure画布的实例,然后可以使用这些实例与主窗口中的绘图进行交互。 所以使用你的代码看起来像这样:

from PyQt4 import QtGui, QtCore
from TestUI2 import MainWindow

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

class Window(MainWindow):
    def __init__(self):
        MainWindow.__init__(self)

        x=[0,10,100]
        y=[3,4,5]

        self.mplwidget = MatplotlibWidget(self.centralwidget)

        self.mplwidget.setGeometry(QtCore.QRect(70, 50, 600, 500))
        self.mplwidget.setObjectName("mplwidget")

        self.mplwidget.plotDataPoints(x,y)    

class MatplotlibWidget(Canvas):        
    def __init__(self, parent=None, title='Title', xlabel='x label', ylabel='y label', dpi=100, hold=False):
        super(MatplotlibWidget, self).__init__(Figure())

        self.setParent(parent)
        self.figure = Figure(dpi=dpi)
        self.canvas = Canvas(self.figure)
        self.theplot = self.figure.add_subplot(111)        

        self.theplot.set_title(title)
        self.theplot.set_xlabel(xlabel)
        self.theplot.set_ylabel(ylabel)

    def plotDataPoints(self, x, y):
        self.theplot.plot(x,y)
        self.draw()            

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

和Ui脚本:

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)

        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")        

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)       

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QMainWindow.__init__(self, parent, f)

        self.setupUi(self)

然后,如果你想与mpl情节互动,例如改变一个标题,你可以在Window类中进行,比如说:

self.mplwidget.theplot.set_title("New Title")

希望有所帮助。

答案 1 :(得分:1)

您只需添加以下行:

self.mplwidget.draw()

在你的:

class Window(MainWindow):
    def __init__(self):

无需手动定义类,只需使用您使用Qt Designer创建的MatplotlibWidget

答案 2 :(得分:1)

根据embert的回答,关于原始问题中的代码,以下内容经过测试和处理: 任

2015-05-20 23:39:50 run children
2015-05-20 23:39:51 16991 child exited with status 0
2015-05-20 23:39:51 A child process is still alive. signals=b'\x11' SIGCHLD
2015-05-20 23:39:52 A child process is still alive. signals=b'\x11' SIGCHLD
2015-05-20 23:39:53 A child process is still alive. signals=b'\x11' SIGCHLD
2015-05-20 23:39:54 16989 child exited with status 0
2015-05-20 23:39:54 No more child processes exist.
2015-05-20 23:39:54 done

或者

x=[0,10,100]
y=[3,4,5]

self.matplotlibwidget.axes.plot(x,y)

self.matplotlibwidget.axes.set_xscale('log')
self.matplotlibwidget.axes.set_title('GRAPH')

答案 3 :(得分:0)

在设置属性后调用self.mplwidget.axes.plot(x,y)

  

hold(False):如果为False,每次调用图时都会清除数字

因此改变

self.mplwidget = MatplotlibWidget(self.centralwidget)

self.mplwidget = MatplotlibWidget(self.centralwidget, hold=True)

或在调用plot

后设置属性