如何在Data类的ctrl函数中调用Plot类的graphWidget实现绘图?
问题解决:Data类中绘制数据到Plot类的图形组件
问题原因
原代码中Data.ctrl函数里graphWidget = Plot().graphWidget的写法是每次创建一个全新的Plot实例,这个实例并没有被添加到界面中,自然无法找到正确的绘图组件进行绘制。
可行解决方案
方案一:初始化时传递绘图组件(推荐)
通过修改Data类的构造函数,让它接收界面上已存在的graphWidget实例并保存,这样ctrl函数就能直接操作该组件绘图。
完整修正代码:
import sys from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QVBoxLayout, QPushButton, QMainWindow, QApplication) import pyqtgraph as pg class Data(QWidget): def __init__(self, graph_widget): super().__init__() self.graphWidget = graph_widget # 保存传入的绘图组件 self.layout = QHBoxLayout() button_widget = QWidget() button_layout = QVBoxLayout() self.btn_off = QPushButton("Off") self.btn_off.clicked.connect(self.ctrl) button_layout.addWidget(self.btn_off) # 修复按钮未添加到布局的问题 button_widget.setLayout(button_layout) self.layout.addWidget(button_widget, stretch=1) self.setLayout(self.layout) def ctrl(self): # 生成测试数据并绘制 y = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] x = [30, 32, 34, 32, 33, 31, 29, 32, 35, 45] self.graphWidget.plot(x, y) class Plot(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout() ly_widget = QWidget() ly = QVBoxLayout() self.graph() ly.addWidget(self.graphWidget) ly_widget.setLayout(ly) self.layout.addWidget(ly_widget) # 创建Data实例时传入当前的graphWidget widget2 = Data(self.graphWidget) self.layout.addWidget(widget2, stretch=4) self.setLayout(self.layout) def graph(self): self.graphWidget = pg.PlotWidget() class MainWidget(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout() bottom_widget = Plot() self.layout.addWidget(bottom_widget, stretch=10) self.setLayout(self.layout) class Window(QMainWindow): def __init__(self, widget): super().__init__() self.setCentralWidget(widget) if __name__ == "__main__": app = QApplication(sys.argv) main_widget = MainWidget() win = Window(main_widget) win.show() sys.exit(app.exec_())
方案二:通过父组件层级查找(耦合性较高)
如果不想修改构造函数,可以让Data类向上遍历父组件,找到对应的Plot实例,再获取其graphWidget进行绘制:
修改Data类的ctrl函数即可:
def ctrl(self): # 向上查找Plot类型的父组件 parent_widget = self.parent() while parent_widget is not None and not isinstance(parent_widget, Plot): parent_widget = parent_widget.parent() if parent_widget is None: return # 未找到目标组件,终止操作 # 绘制数据 y = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] x = [30, 32, 34, 32, 33, 31, 29, 32, 35, 45] parent_widget.graphWidget.plot(x, y)
关键说明
- 方案一通过依赖注入的方式传递组件,耦合性低,代码更易维护,是推荐的实现方式
- 原代码中存在按钮未添加到布局的问题,导致按钮无法显示,已在修正代码中修复
- 两种方案都避免了创建新的
Plot实例,确保操作的是界面上已加载的绘图组件
内容的提问来源于stack exchange,提问作者lp roj
相关产品推荐
相关产品推荐

