PyQtGraph如何不复制实现在多个图表中同步展示同一图形项
核心前提
Qt Graphics View 框架规定单个 QGraphicsItem 实例只能归属一个 QGraphicsScene,而 pyqtgraph 每个 PlotItem 都持有独立的 scene,因此无法直接将同一个图形项实例添加到多个绘图中,我们的优化方向是降低同步逻辑的开发成本、减少冗余内存占用。
通用同步组方案(适配绝大多数场景)
你原来的方案需要给每个线条手动绑定双向信号,扩展性很差,我们可以封装通用的同步逻辑,一次编写就能支持所有属性的自动双向同步,不管有多少个绘图、多少条线都不需要重复写绑定代码。
import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import QObject, pyqtSignal from pyqtgraph import GraphicsLayoutWidget, PlotItem, InfiniteLine class SyncGroup(QObject): # 同步信号:携带变更的源实例避免循环触发 sigSyncNeeded = pyqtSignal(object) def __init__(self, item_class, *init_args, **init_kwargs): super().__init__() self.item_class = item_class self.init_args = init_args self.init_kwargs = init_kwargs self.items = [] def create_item(self): # 创建新的同逻辑线条实例,自动加入同步组 item = self.item_class(*self.init_args, **self.init_kwargs) self.items.append(item) # 绑定所有变更信号,其他图形项可按需扩展信号列表 item.sigPositionChanged.connect(lambda: self.sigSyncNeeded.emit(item)) item.sigClicked.connect(lambda: self.sigSyncNeeded.emit(item)) self.sigSyncNeeded.connect(lambda source: self.sync_all(source)) return item def sync_all(self, source_item): for item in self.items: if item is source_item: continue item.blockSignals(True) # 同步所有属性,可根据需求扩展 item.setPos(source_item.pos()) item.setPen(source_item.pen()) item.setVisible(source_item.isVisible()) item.setMovable(source_item.isMovable()) item.blockSignals(False) if __name__ == '__main__': app = QApplication(sys.argv) # 创建一个同步组,对应一条逻辑上的线 line_sync_group = SyncGroup(InfiniteLine, pos=5, movable=True) # 生成两个视图实例,分别添加到两个绘图 line1 = line_sync_group.create_item() line2 = line_sync_group.create_item() # 绘图创建 plot1 = PlotItem() plot2 = PlotItem() plot1.setXRange(0, 10) plot2.setXRange(0, 10) plot1.addItem(line1) plot2.addItem(line2) # 布局展示 widget = GraphicsLayoutWidget() widget.addItem(plot1, 0, 0) widget.addItem(plot2, 1, 0) widget.show() sys.exit(app.exec())
超大数量线条的极致优化方案
如果你的线条规模超过1000条,哪怕双倍实例都有性能压力,可以把所有线条的状态(位置、样式、可见性等)抽成独立的数据模型,所有视图层的线条实例只负责渲染,不存储状态,所有修改直接作用于数据模型,模型变更后批量通知所有绘图更新,这种方案的内存开销几乎只增加了数据模型的大小,视图实例的冗余开销极低。
内容的提问来源于stack exchange,提问作者Nevermore
相关产品推荐
相关产品推荐

