使用Qt Designer表单和PyQt5在QWidget中绘制matplotlib图 [英] Plotting matplotlib figure inside QWidget using Qt Designer form and PyQt5

查看:288
本文介绍了使用Qt Designer表单和PyQt5在QWidget中绘制matplotlib图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道将matplotlib图形链接到Qt Designer创建的表单的最佳方法.我有一个在QtDesigner中创建的表单,然后通过pyuic5编译为python.我的主要程序是:

I don't understand the best way to link a matplotlib figure to a form created from Qt Designer. I have a form I created in QtDesigner and then compiled to python through pyuic5. My main program is:

import app_framework as af
import matplotlib
from PyQt5 import QtWidgets
import sys

matplotlib.use('Qt5Agg')

app = QtWidgets.QApplication(sys.argv)
form = af.MyApp()
form.show()
app.exec_()

myApp调用从Qt Designer创建的app_framework.py表单,然后通过pyuic5(design.py)进行转换:

where myApp calls the app_framework.py form created from Qt Designer then converted by pyuic5 (design.py):

from PyQt5.QtWidgets import QApplication, QMainWindow
import design

class MyApp(QMainWindow, design.Ui_mainWindow):
   def __init(self):
       super(self.__class__, self).__init__()
       <button initializations>
       <function definitions for button callbacks>

对于在该框架中的什么地方我可以将一个matplotlib图形链接到QtDesigner中的预制空窗口小部件或类似的东西,我感到困惑,因此我可以在事情发生时在GUI窗口中绘制新数据(输入文本,按钮按下等)

I'm confused as to where in this framework I can link a matplotlib figure to a premade empty widget in QtDesigner, or something of that sort, so that I can plot new data in the GUI window as things happen (text entered, button push, etc.)

我在 SO 和<一个href ="http://matplotlib.org/examples/user_interfaces/embedding_in_qt5.html" rel ="noreferrer"> matplotlib的网站,但是我不确定我是否了解为此创建空间的正确过程Qt Designer表单中的窗口小部件,然后链接一个图,和/或创建一个窗口小部件,然后进行链接和绘制.

I've found some threads here on SO and matplotlib's site, but I'm not sure I understand the correct process for creating the space for this widget in the Qt Designer form then linking a plot, and/or creating a widget post hoc and then linking and plotting.

到目前为止,我要做的是在Qt Creator中创建一个空的QWidget,然后在pyuic5编译之后,按如下所示更改design.py文件:

What I've done so far is create an empty QWidget inside Qt Creator and then after pyuic5 compile, I alter the design.py file as follows:

from PyQt5 import QtCore, QtGui, QtWidgets

# **** ADDED THIS
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
# **** 

class Ui_mainWindow(object):
    def setupUi(self, mainWindow):
        <mainWindow setup stuff>
        self.centralwidget = QtWidgets.QWidget(mainWindow)

        # ****ALTERED THIS FROM self.plotWidget = QtWidgets.QWidget(self.centralWidget)
        self.plotWidget = MplWidget(self.centralWidget)
        # ***** 

        self.plotWidget.setGeometry(QtCore.QRect(20, 250, 821, 591))
        self.plotWidget.setObjectName("plotWidget")

  # **** ADDED THIS 
class MplCanvas(Canvas):
    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        Canvas.__init__(self, self.fig)
        Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        Canvas.updateGeometry(self)


class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.canvas = MplCanvas()
 # ***********

然后将app_framework.py设为:

and then app_framework.py as:

from PyQt5.QtWidgets import QApplication, QMainWindow
import design

class MyApp(QMainWindow, design.Ui_mainWindow):
   def __init(self):
       super(self.__class__, self).__init__()
       self.setupUi(self)
       self.pushButton_plotData.clicked.connect(self.plot_data)

    def plot_data(self):
        x=range(0, 10)
        y=range(0, 20, 2)
        self.plotWidget.canvas.ax.plot(x, y)
        self.plotWidget.canvas.draw()

我以为这可以用,但是当我单击绘图按钮时,什么也没发生.它不会锁定,只是不会绘制任何内容.我猜想我缺少在此空窗口小部件中绘制matplotlib图形和/或画布的基本知识.

I thought this would work, but when I click the plot push button, nothing happens. It doesn't lock up, it just doesn't plot anything. I'm guessing I'm missing something fundamental for plotting a matplotlib figure and/or canvas in this empty widget.

推荐答案

我通过此

I found the solution through the help of this SO post, which links to this free sample chapter of a book I'm probably gonna need to buy. As sort of mentioned in a number of other posts, one needs to "Promote" the blank QtWidget to a MplWidget using the header mplwidget. After doing this, and then running the pyuic5 command, "from mplwidget import MplWidget" will appear in the design.py file which can be updated anytime without worry about overwritting. Then, create an mplwidget.py file with:

# Imports
from PyQt5 import QtWidgets
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas
import matplotlib

# Ensure using PyQt5 backend
matplotlib.use('QT5Agg')

# Matplotlib canvas class to create figure
class MplCanvas(Canvas):
    def __init__(self):
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        Canvas.__init__(self, self.fig)
        Canvas.setSizePolicy(self, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        Canvas.updateGeometry(self)

# Matplotlib widget
class MplWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)   # Inherit from QWidget
        self.canvas = MplCanvas()                  # Create canvas object
        self.vbl = QtWidgets.QVBoxLayout()         # Set box for plotting
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)

然后,应用程序框架可以与我之前的一样.运行时,按下图按钮,图形将按预期显示.我想我基本上已经做了所有事情来手工提升" QWidget,只是缺少了vbl内容,但是每次编辑Qt Designer表单时,所有这些都将被覆盖.

Then, the app framework can be as I had earlier. When run, and pushing the plot button, the figure appears as expected. I think I basically had done everything to "Promote" the QWidget by hand just missing the vbl stuff, but all that would be overwritten everytime the Qt Designer form is editted.

app_framework.py:

app_framework.py:

from PyQt5.QtWidgets import QApplication, QMainWindow
import design

class MyApp(QMainWindow, design.Ui_mainWindow):
   def __init(self):
       super(self.__class__, self).__init__()
       self.setupUi(self)
       self.pushButton_plotData.clicked.connect(self.plot_data)

    def plot_data(self):
        x=range(0, 10)
        y=range(0, 20, 2)
        self.plotWidget.canvas.ax.plot(x, y)
        self.plotWidget.canvas.draw()

main.py:

from PyQt5 import QtWidgets
import sys

# Local Module Imports
import app_framework as af

# Create GUI application
app = QtWidgets.QApplication(sys.argv)
form = af.MyApp()
form.show()
app.exec_()

这篇关于使用Qt Designer表单和PyQt5在QWidget中绘制matplotlib图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆