文章目录
-
- 提升
- 编写画布类
- 加载UI并编写业务逻辑
提升
QT Designer并没有提供matplotlib画布控件,但可以对Widget控件进行提升,以适配Matplotlib的画布,具体流程如下
- 提升的类名称:MplCanvas
- 头文件:mpl_canvas(⚠️ 不要加.py后缀,只需模块名)
- 点击【添加】-> 选中刚添加的条目 -> 点击【提升】。
上述步骤只提供了最简单的可用方案,在拖拽QWidget到主窗口之后,QT会自动创建一个centralwidget为其父控件,此时在对象查看器 中,选中 centralWidget,并点击顶部菜单->窗体,即可更改其布局逻辑。
此外,为了安置工具栏,再从窗口部件盒中拖拽一个QWidget放入画布下方,重命名为toolbar_container。由于工具栏的高度是恒定的,所以在【centralWidget】的属性中找到【layoutStretch】,将其设为1,0,表示第一个部件(画布)转矩所有剩余空间,第二个部件(工具栏)保持最小尺寸。
最终得到的布局结果如下图所示

编写画布类
刚刚在提升widget的过程中,设置了一个mpl_canvas的头文件,该头文件就是自定义的画布控件,文件名为【mpl_canvas.py】,类为【MplCanvas】,具体实现如下
# mpl_canvas.py
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class MplCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super().__init__(fig)
self.setParent(parent)
def plot(self, x, y, title=""):
self.axes.clear()
self.axes.plot(x, y, marker='o', linestyle='-')
self.axes.set_title(title)
self.axes.grid(True)
self.draw() # 刷新画布
关于改代码的详细解读,可见将Matplotlib嵌入到PyQT6。
加载UI并编写业务逻辑
接下来就是常规的QT开发流程了,创建主程序文件,但要与与mpl_canvas.py和mainwindow.ui放在同一目录,代码如下
import sys
import numpy as np
from PyQt6 import uic
from PyQt6.QtWidgets import QApplication, QMainWindow, QHBoxLayout, QWidget
from matplotlib.backends.backend_qtagg import NavigationToolbar2QT as NavigationToolbar
from mpl_canvas import MplCanvas
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("mainwindow.ui", self)
self.toolbar_container = self.findChild(QWidget, "toolbar_container")
layout = self.toolbar_container.layout()
if layout is None:
layout = QHBoxLayout(self.toolbar_container)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(0)
self.toolbar = NavigationToolbar(self.mpl_canvas, self)
layout.addWidget(self.toolbar)
self.update_plot()
def update_plot(self):
x = np.linspace(0, 10, 100)
y = np.sin(x)
self.mpl_canvas.plot(x, y, title="test")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
需要注意,尽管main.py中并没有显式调用MplCanvas,但还是需要导入该类,否则 uic.loadUi 运行时会报 ImportError。


