【问题标题】:Interacting with MatplotlibWidget created with Qt Designer in python code在 python 代码中与使用 Qt Designer 创建的 MatplotlibWidget 交互
【发布时间】:2013-08-13 18:47:15
【问题描述】:

我在与我通过 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_())

【问题讨论】:

    标签: python matplotlib pyqt python-embedding


    【解决方案1】:

    您需要首先为 MatplotlibWidget 定义自己的类(在您的主脚本中,而不是 UI 代码中),然后在 Window() 定义中将其实例化。为此,您还需要从 _qt4agg matplotlib 后端模块和 Figure 类导入 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")
    

    希望对您有所帮助。

    【讨论】:

    【解决方案2】:

    你只需要添加一行:

    self.mplwidget.draw()
    

    在你的:

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

    无需手动定义类,使用Qt Designer创建的MatplotlibWidget即可。

    【讨论】:

      【解决方案3】:

      根据 embert 的回答,关于原始问题中的代码,以下是经过测试和工作的: 要么

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

      或者

      x=[0,10,100]
      y=[3,4,5]
      
      self.matplotlibwidget.axes.set_xscale('log')
      self.matplotlibwidget.axes.set_title('GRAPH')
      self.matplotlibwidget.axes.hold(True)
      
      self.matplotlibwidget.axes.plot(x,y)
      

      【讨论】:

        【解决方案4】:

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

        hold(False):如果为False,则每次调用plot时都会清除图形

        因此改变

        self.mplwidget = MatplotlibWidget(self.centralwidget)
        

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

        或调用plot后设置属性

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-23
          • 1970-01-01
          • 2021-08-23
          • 2011-09-04
          • 2017-03-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多