PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)

https://blog.csdn.net/panrenlong/article/details/80183519?ops_request_misc=&request_id=&biz_id=102&utm_term=python%20matplotlib%20%E5%9C%A8%E6%8E%A7%E4%BB%B6%E6%98%BE%E7%A4%BA&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-80183519.first_rank_v2_pc_rank_v29_10

感谢这位大佬的文章,解决了困扰我许久的难题!!!
站在巨人肩膀,在此之上,添加一些给小白(我自己)的更通俗的说明。最好跟上面的文章对比着看。
原文章是在QtDesigner中的"Dialog"类型的界面中的控件上 显示matplotlib曲线绘图,此时我想更改为使用"MainWindow"类型的界面进行显示
PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)_第1张图片
PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)_第2张图片

采用Main Window类型界面进行显示

我将原文章的部分代码进行修改,方便对比查看

  • 原文章中的模块区域 testplot2pyqt5 这个是QtDesigner设计好的ui文件转py文件后的名字,根据自己的ui文件转py文件的名字更改即可。方便对比关键区域,我这里都没有更改。
  • 将QtDesigner设计出来的ui文件转py文件,网上教程很多,我用的是Pycharm中的自己加上的PyUic的插件(也是网上的教程),有兴趣大家可以去查一下。
#-*-coding:utf-8-*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import numpy as np

# 更改第1处
# 引入模块部分仅更改这里,Ui_Dialog改为Ui_MainWindow
from testplot2pyqt5ui import Ui_MainWindow 


import matplotlib
matplotlib.use("Qt5Agg")  # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

#创建一个matplotlib图形绘制类
class MyFigure(FigureCanvas):
    def __init__(self,width=5, height=4, dpi=100):
        #第一步:创建一个创建Figure
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        #第二步:在父类中激活Figure窗口
        super(MyFigure,self).__init__(self.fig) #此句必不可少,否则不能显示图形
        #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
        self.axes = self.fig.add_subplot(111)
    #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
    def plotsin(self):
        self.axes0 = self.fig.add_subplot(111)
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(2 * np.pi * t)
        self.axes0.plot(t, s)
    def plotcos(self):
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(2 * np.pi * t)
        self.axes.plot(t, s)

# 更改第2处
# 将QDialog,Ui_Dialog 更改为QMainWindow,Ui_MainWindow
# 个人理解为将 QDialog类 界面类型名称Ui_Dialog 更改为需要的两种即可
# Ui_Dialog其实就是ui转py文件后,转换后的py文件内 类 的名称
class MainDialogImgBW(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(MainDialogImgBW,self).__init__()
        self.setupUi(self)
        self.setWindowTitle("显示matplotlib绘制图形")
        self.setMinimumSize(0,0)

        #第五步:定义MyFigure类的一个实例
        self.F = MyFigure(width=3, height=2, dpi=100)
        #self.F.plotsin()
        self.plotcos()
        #第六步:在GUI的groupBox中创建一个布局,用于添加MyFigure类的实例(即图形)后其他部件。
        self.gridlayout = QGridLayout(self.groupBox)  # 继承容器groupBox
        self.gridlayout.addWidget(self.F,0,1)

        #补充:另创建一个实例绘图并显示
        self.plotother()

    def plotcos(self):
        t = np.arange(0.0, 5.0, 0.01)
        s = np.cos(2 * np.pi * t)
        self.F.axes.plot(t, s)
        self.F.fig.suptitle("cos")
    def plotother(self):
        F1 = MyFigure(width=5, height=4, dpi=100)
        F1.fig.suptitle("Figuer_4")
        F1.axes1 = F1.fig.add_subplot(221)
        x = np.arange(0, 50)
        y = np.random.rand(50)
        F1.axes1.hist(y, bins=50)
        F1.axes1.plot(x, y)
        F1.axes1.bar(x, y)
        F1.axes1.set_title("hist")
        F1.axes2 = F1.fig.add_subplot(222)

        ## 调用figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot方法
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        y = [23, 21, 32, 13, 3, 132, 13, 3, 1]
        F1.axes2.plot(x, y)
        F1.axes2.set_title("line")
        # 散点图
        F1.axes3 = F1.fig.add_subplot(223)
        F1.axes3.scatter(np.random.rand(20), np.random.rand(20))
        F1.axes3.set_title("scatter")
        # 折线图
        F1.axes4 = F1.fig.add_subplot(224)
        x = np.arange(0, 5, 0.1)
        F1.axes4.plot(x, np.sin(x), x, np.cos(x))
        F1.axes4.set_title("sincos")
        self.gridlayout.addWidget(F1, 0, 2)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainDialogImgBW()
    main.show()
    #app.installEventFilter(main)
    sys.exit(app.exec_())

更换为Main Window界面类型的代码仅更改两处,如果想换为Widget类型界面显示,我猜应该差不多。

Main Window类型界面+动态加载ui界面

#-*-coding:utf-8-*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import numpy as np

# 更改1
# 动态加载后就不需要这个了
# from testplot2pyqt5 import Ui_MainWindow

import matplotlib
matplotlib.use("Qt5Agg")  # 声明使用QT5
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

# 更改2
# 动态加载ui文件所必须的模块
from PyQt5 import uic

#创建一个matplotlib图形绘制类
class MyFigure(FigureCanvas):
    def __init__(self,width=5, height=4, dpi=100):
        #第一步:创建一个创建Figure (其实就是类的实例化)
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        #第二步:在父类中激活Figure窗口
        super(MyFigure,self).__init__(self.fig) #此句必不可少,否则不能显示图形
        #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
        self.axes = self.fig.add_subplot(111)
    #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
    def plotsin(self):
        self.axes0 = self.fig.add_subplot(111)
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(2 * np.pi * t)
        self.axes0.plot(t, s)
    def plotcos(self):
        t = np.arange(0.0, 3.0, 0.01)
        s = np.sin(2 * np.pi * t)
        self.axes.plot(t, s)

# 更改3
class MainDialogImgBW():
    def __init__(self):
        super(MainDialogImgBW,self).__init__()
        # 更改4 我的ui文件名字起错了,对原文章的ui多了ui两个字母
        self.ui = uic.loadUi('testplot2pyqt5ui.ui')
        # 更改5 把这个代码注释掉
        # 有了它无法运行,至于为什么我不清楚,有机会查查setupui的机制
        # self.setupUi(self)  
        # 更改6和7 self后面要加 ".ui"  
        # 这属于界面显示的代码,动态加载的ui界面必须在代码里声明要对ui进行操作
        self.ui.setWindowTitle("显示matplotlib绘制图形")
        self.ui.setMinimumSize(0,0)

        #第五步:定义MyFigure类的一个实例
        self.F = MyFigure(width=3, height=2, dpi=100)
        #self.F.plotsin()
        self.plotcos()
        #第六步:在GUI的groupBox中创建一个布局,用于添加MyFigure类的实例(即图形)后其他部件。
        # 更改8 同理,要加 ".ui",因为要对ui界面内的groupBox控件进行操作
        self.gridlayout = QGridLayout(self.ui.groupBox)  # 继承容器groupBox
        self.gridlayout.addWidget(self.F,0,1)

        #补充:另创建一个实例绘图并显示
        self.plotother()

    def plotcos(self):
        t = np.arange(0.0, 5.0, 0.01)
        s = np.cos(2 * np.pi * t)
        self.F.axes.plot(t, s)
        self.F.fig.suptitle("cos")
    def plotother(self):
        F1 = MyFigure(width=5, height=4, dpi=100)
        F1.fig.suptitle("Figuer_4")
        F1.axes1 = F1.fig.add_subplot(221)
        x = np.arange(0, 50)
        y = np.random.rand(50)
        F1.axes1.hist(y, bins=50)
        F1.axes1.plot(x, y)
        F1.axes1.bar(x, y)
        F1.axes1.set_title("hist")
        F1.axes2 = F1.fig.add_subplot(222)

        ## 调用figure下面的add_subplot方法,类似于matplotlib.pyplot下面的subplot方法
        x = [1, 2, 3, 4, 5, 6, 7, 8, 9]
        y = [23, 21, 32, 13, 3, 132, 13, 3, 1]
        F1.axes2.plot(x, y)
        F1.axes2.set_title("line")
        # 散点图
        F1.axes3 = F1.fig.add_subplot(223)
        F1.axes3.scatter(np.random.rand(20), np.random.rand(20))
        F1.axes3.set_title("scatter")
        # 折线图
        F1.axes4 = F1.fig.add_subplot(224)
        x = np.arange(0, 5, 0.1)
        F1.axes4.plot(x, np.sin(x), x, np.cos(x))
        F1.axes4.set_title("sincos")
        self.gridlayout.addWidget(F1, 0, 2)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainDialogImgBW()
    # 更改9 同理,要加 ".ui",因为要对ui界面进行显示操作
    main.ui.show()
    #app.installEventFilter(main)
    sys.exit(app.exec_())

QtDesigner界面设计

为了防止有像我一样的小白连QtDesigner也不会用,把界面设置也说一下吧
PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)_第3张图片
PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)_第4张图片

PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)_第5张图片
PYQT5+matplotlib+QtDesigner matplotlib嵌入QtDesigner的控件上进行显示(动态加载ui文件或使用py文件显示界面)_第6张图片

小总结

  • 动态加载ui ,关键是将ui界面的文件load进来,要不他也不知道你的界面长啥样。
from PyQt5 import uic
   self.ui = uic.loadUi('testplot2pyqt5ui.ui')
  • 凡是需要操作界面内的控件或者界面本事的,必须加 “.ui”
self.ui.xxxxxxx(要干的事情)

你可能感兴趣的:(干货,pycharm,python,pyqt5,matplotlib)