You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 01:39:40