如何在PyQt GUI主窗口内嵌入Matplotlib图表实现同窗口显示
问题根因
你的代码有两个核心错误导致图表无法内嵌到主窗口:
- 原
atualizar方法中的绘图调用路径完全错误:MplCanvas本身就是FigureCanvas的子类,不存在self.FigureCanvas.canvas这个属性,绘图轴对象就是初始化时定义的self.ax,直接调用即可。 - 你没有将实例化后的
MplCanvas控件添加到主窗口的布局层级中,Qt中所有控件必须挂载到对应布局下才会被渲染显示,这是图表无法出现在主窗口内的核心原因。
正确实现步骤
- 在Qt Designer中预留图表位置
打开生成Ui_MainWindow的.ui文件,在需要放置图表的区域拖入一个QWidget控件,将其objectName设置为chart_container(可自定义),右键点击该控件为其指定任意一种布局(水平/垂直/网格布局均可,未设置布局的控件无法自适应窗口大小)。 - 修正Matplotlib画布类
去掉错误的属性调用逻辑,画布类正确写法如下:from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from PyQt5 import QtWidgets class MplCanvas(FigureCanvas): def __init__(self, parent=None): self.fig = Figure(figsize=(5, 4), dpi=100) self.ax = self.fig.add_subplot(111) super().__init__(self.fig) self.setParent(parent) self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.updateGeometry() - 主窗口中嵌入画布
在main.py的主窗口初始化逻辑中,完成ui加载后将画布实例添加到预留的容器布局中,示例代码如下:import sys from PyQt5.QtWidgets import QMainWindow, QApplication # 导入Qt Designer生成的界面类 from your_ui_module import Ui_MainWindow # 导入上述定义的MplCanvas类 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) # 实例化画布,父控件指定为预留的图表容器 self.chart_canvas = MplCanvas(self.ui.chart_container) # 将画布添加到容器的布局中 self.ui.chart_container.layout().addWidget(self.chart_canvas) # 绑定更新按钮的触发事件 self.ui.update_btn.clicked.connect(self.refresh_chart) def refresh_chart(self): # 获取时间输入框的值,不需要使用全局变量 tempoInicio = self.ui.campoTempoInicio.dateTime().toPyDateTime() print(tempoInicio) x = range(0, 10) y = range(0, 20, 2) # 清空原有绘图内容,避免曲线叠加 self.chart_canvas.ax.clear() self.chart_canvas.ax.plot(x, y) # 刷新画布显示新内容 self.chart_canvas.draw() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
注意事项
- 不要通过全局变量传递界面控件的取值,所有控件都可以通过
self.ui.控件objectName直接访问,全局变量很容易引发状态不同步的问题。 - 每次更新绘图前调用
ax.clear()清空历史内容,避免多次触发绘图后曲线叠加混乱。 - 必须给Qt Designer中预留的占位控件设置布局,否则画布不会跟随窗口缩放自动调整大小。
内容的提问来源于stack exchange,提问作者Vinicius Francioni
相关产品推荐
相关产品推荐

