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

使用__call__方法结合pyqtgraph更新PlotWidget时setData不生效求助

问题分析与解决方案

核心问题

你的代码存在Graph实例不统一的关键问题:

  • Window类中创建了self.Graph = Graph()并添加到界面布局,这是用户能看到的绘图组件
  • MyWidget类内部又创建了self.Graph = Graph(),计时器触发时更新的是这个未被添加到界面的实例的绘图数据,所以界面上的图表完全没变化

同时全局变量count的滥用也会导致逻辑混乱,建议改用类成员变量替代。

修改步骤

1. 给MyWidget添加自定义信号,移除内部Graph实例

把MyWidget改成通过信号通知外部触发绘图更新,避免多实例冲突:

class MyWidget(QWidget):
    # 定义自定义信号,计时器完成时触发
    timer_finished = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.layout = QVBoxLayout()
        self.layout.setSpacing(10)
        self.layout.setContentsMargins(10,10,10,10)
        self.setLayout(self.layout)
        self.UiComponents()
        # 移除内部无用的Graph实例
        # self.Graph=Graph()
        self.show()

    # 修改showTime方法中的触发逻辑
    def showTime(self):
        if self.start:
            self.count -= 1

        if self.count == 0:
            self.start = False
            self.label.setText("Completed !!!! ")  
            # 发送信号通知外部更新图表
            self.timer_finished.emit()

        if self.start:
            text = str(self.count / 10) + " s"
            self.label.setText(text)

2. 替换全局变量为类成员变量

把全局count改成MyWidget的成员变量,消除全局变量副作用:

class MyWidget(QWidget):
    timer_finished = pyqtSignal()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # ... 其他初始化代码
        self.count = 30  # 用类成员变量替代全局count
        self.start = False

    # 修改所有用到global count的方法
    def get_seconds(self):
        self.start = False
        second, done = QInputDialog.getInt(self, 'Seconds', 'Enter Seconds:')
        if done:
            self.count = second * 10
            self.label.setText(str(second))

    def start_action(self):
        self.start = True
        if self.count == 0:
            self.start = False

    def reset_action(self):
        self.start = False
        self.count = 0
        self.label.setText("//TIMER//")

3. 在Window类中统一连接信号与Graph实例

修改Window类,将MyWidget的信号连接到界面上的Graph组件:

class Window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_gui()
        self.setWindowTitle("GC Monitor")
        self.setGeometry(100, 100, 800, 600)  # 调大窗口适配图表

    def init_gui(self):
        self.window = QWidget()
        self.layout = QGridLayout()
        self.setCentralWidget(self.window)
        self.window.setLayout(self.layout)

        self.Mywidget= MyWidget()
        self.Graph = Graph()

        # 关键:连接信号,让计时器触发界面上的Graph更新
        self.Mywidget.timer_finished.connect(self.Graph.readpanda)

        self.layout.addWidget(self.Mywidget,0,0,1,1)
        self.layout.addWidget(self.Graph,0,1,1,1)  # 调整布局让图表占更多空间

4. 移除Graph类中无用的__call__方法

现在直接通过信号触发readpanda,__call__方法可以删除:

class Graph(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # ... 原有初始化代码保持不变

    # 删除以下无用方法
    # def __call__(self, *args, **kwargs):
    #     if count==0:
    #         self.readpanda()

    # ... 其他方法保持不变

额外优化建议

  • 全局变量data建议改成Graph的成员变量,避免全局污染
  • readpanda中读取文件的逻辑可以优化,比如记录上次读取的位置,避免每次遍历整个文件
  • 在updatePlot末尾添加self.plot.autoRange(),确保新增数据自动显示在视图范围内

内容的提问来源于stack exchange,提问作者Dan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 10:25:34