这几天想做一个python GUI
中嵌入matplotlib
图像的程序,在网上也搜了很多博客,主要是绘制出来图像在布局上的位置问题不太清楚,今天就整理了一下。
其实绘制图像就相当于一个Widget
组件,我们把他添加到Layout
布局中就可以。然后具体的绘制图像就跟平时使用plot
绘制大差不差,只是我们最终不是使用show()
方法展示,而是使用draw()
方法将图像展示到GUI界面中。
首先打开QtDesigner,创建一个Main Window窗口
可以自己拖动左边的组件,我这里简单添加了几个组件和按钮
接着可以设置布局,设置好布局之后放大缩小窗口的大小,里面组件的大小也会跟着改变,我自己一般使用的是垂直布局和水平布局较多,在QtDesigner中,按住Ctrl选择组件,然后点右键选择布局,一般在同一行的选择水平布局。
接着设置整体窗口的布局,在QtDesigner的右上角,选择最外层的MainWindow点击右键选择垂直布局
最后设置完大概是这个样子,看着有点怪,不过我们导出后一会还会手动添加画图的Widget组件,先ctrl+s保存文件,导出的是一个.ui文件
我们打开pycharm,将.ui文件转换为.py文件,在存放.ui文件的文件夹上点击右键选择Open in Terminal打开命令行。
输入命令pyuic5 -o qt_plt.py qt_plt.ui
,qt_plt.ui是ui文件名称,qt_plt.py是要导出的.py文件的名称
修改.py文件中的代码
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'qt_plt.ui'
#
# Created by: PyQt5 UI code generator 5.9.2
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import matplotlib
import sys
import numpy as np
matplotlib.use('Qt5Agg')
# 使用 matplotlib中的FigureCanvas (在使用 Qt5 Backends中 FigureCanvas继承自QtWidgets.QWidget)
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(720, 585)
# 1. 创建画板组件
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
# GUI界面总体的垂直布局
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.horizontalLayout.addWidget(self.pushButton)
self.verticalLayout.addLayout(self.horizontalLayout)
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setObjectName("pushButton_2")
# 将按钮加入垂直布局中
self.verticalLayout.addWidget(self.pushButton_2)
# 将画板组件加入到垂直布局中 放在按钮下方
self.verticalLayout.addWidget(self.canvas)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 720, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
# 连接点击事件到按钮上
self.pushButton_2.clicked.connect(self.plot_)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "打开文件"))
self.pushButton.setText(_translate("MainWindow", "选择"))
self.pushButton_2.setText(_translate("MainWindow", "绘制"))
# 定义绘制的方法
def plot_(self):
# 绘制双柱状图
A_means_score = [0.710, 0.765, 0.798, 0.762]
B_means_score = [0.84, 0.892, 0.902, 0.895]
index = np.arange(4)
bar_width = 0.35
plt.bar(index, A_means_score, bar_width, # A班x轴数据起始位置为index序列
alpha=0.4, color='b', label='DIA_RED')
plt.bar(index + bar_width, B_means_score, bar_width, # B班x轴起始位置与A班数据错开
alpha=0.4, color='r', label='DIFS-FI')
x_labels = ['NBC', 'C4.5', 'SVM', 'KNN']
plt.xticks(index + bar_width / 2, x_labels) # index+bar_width/2 使得标签居中显示
plt.legend()
# 将之前的plt.show() 改成self.canvas.draw()
self.canvas.draw()
# 运行程序
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main_window = Ui_MainWindow()
w = QtWidgets.QMainWindow()
main_window.setupUi(w)
w.show()
app.exec()
点击绘制按钮之后的结果