PyQt多图绘制时卡顿崩溃,如何优化内存及规范globals使用?
问题解答
1. 如何降低程序内存占用?
- 限制数据存储长度:当前代码中
self.t_domain、y_domain_r/g/b会无限累积数据,运行时间越长内存占用越高。建议设定最大保留帧数,超过阈值后删除旧数据:max_frames = 1000 # 根据业务需求调整 self.t_domain.append(self.time) if len(self.t_domain) > max_frames: self.t_domain.pop(0) for S in range(self.sensor_num): self.y_domain_r[S].append(self.data[S][0]) self.y_domain_g[S].append(self.data[S][1]) self.y_domain_b[S].append(self.data[S][2]) # 同步截断RGB数据,保持与时间轴长度一致 if len(self.y_domain_r[S]) > max_frames: self.y_domain_r[S].pop(0) self.y_domain_g[S].pop(0) self.y_domain_b[S].pop(0) - 优化绘图更新逻辑:现在每次
showPlot都清空重绘,会重复创建绘图资源。改为预先创建曲线对象,仅更新数据而非重新绘制:
先修改initPlots初始化曲线:
再修改def initPlots(self): self.plot_groups = [] for S in range(self.sensor_num): plot = pg.PlotWidget() plot.setYRange(-30, 30) self.layout.addWidget(plot, S//5, S%5) # 初始化三条RGB曲线并保存到实例属性 r_curve = plot.plot(pen=pg.mkPen(width=2, color='r'), name=f"sensor_{S}") g_curve = plot.plot(pen=pg.mkPen(width=2, color='g'), name=f"sensor_{S}") b_curve = plot.plot(pen=pg.mkPen(width=2, color='b'), name=f"sensor_{S}") self.plot_groups.append( (plot, r_curve, g_curve, b_curve) )showPlot为更新数据:def showPlot(self, number, x_axis): _, r_curve, g_curve, b_curve = self.plot_groups[number] r_curve.setData(x=x_axis, y=self.y_domain_r[number]) g_curve.setData(x=x_axis, y=self.y_domain_g[number]) b_curve.setData(x=x_axis, y=self.y_domain_b[number]) - 移除冗余打印语句:代码中的
print("init_Plots")等调试打印,长期运行会累积输出占用资源,建议删除或注释。
2. 大量使用globals()是否合理?
完全不合理,存在诸多问题:
- 可读性极差:
globals()["self.plot{0}".format(S)]这种写法让变量定义和使用脱节,后续维护时难以追踪控件对象的来源。 - 易引发命名冲突:若全局空间中出现同名变量,会直接覆盖控件对象,导致难以排查的崩溃或逻辑错误。
- 性能冗余:每次通过
globals()查找变量都要遍历全局命名空间,效率远低于直接访问实例属性。 - 违背面向对象设计:类的实例控件应该用实例属性(比如列表
self.plot_groups)管理,既符合封装原则,又方便统一操作。
3. 该问题是否属于Python的固有缺陷?
不属于,崩溃是代码逻辑和写法错误导致的:
- 内存无限累积导致内存耗尽崩溃,是未做数据截断处理的问题,任何语言不处理都会出现类似情况。
- 使用
globals()管理Qt控件,可能导致控件对象的引用关系混乱,触发Qt内存管理异常,这是写法错误而非Python的固有问题。 - 每次重绘都创建新曲线对象,会导致Qt内部绘图资源无法及时回收,累积后引发崩溃,属于绘图逻辑优化不足。
内容的提问来源于stack exchange,提问作者koreancoder
相关产品推荐
相关产品推荐

