(详细分析)基于pyqt5、pyqtgraph和GLViewWidget持续动态更新3D散点图点的位置,提高刷新帧数,使其有飘动的效果

目录

  • 1、问题描述
  • 2、解决办法

1、问题描述

今天收到私信,提问者想要的效果为如何动态更新点的位置。而他刷新画布的方式是在循环内直接对部件GLViewWidget进行重置操作,并遇到了内存泄漏的问题。

这个问题我考虑了一下:对GLViewWidget进行初始化,会直接把该部件内的所有内容(画布、坐标轴等)直接删除。若想继续更新点的位置,需要重新添加新的画布和坐标轴等,而这一块是需要占用内存和时间的。若在循环内一直做这个操作,不仅容易造成内存泄漏,也可能会造成窗口卡顿(多线程QThread情况下)。

2、解决办法

抓住问题关键,我们想要一直更新点的位置,并提高帧数。GLViewWidget是我们最基础的部件,我们是在其上添加画布,添加坐标轴然后更新点的位置。

打个比方:我们想在黑板上的坐标轴上画3D图,并持续更新点的位置。每次更新我们需要做的仅仅是用黑板擦擦掉之前的点,然后再标上新的点,这样便完成了一次更新操作。而为了刷新点去把GLViewWidget重置就得不偿失了,这是把整个黑板重置了,连带添加的画布和坐标轴一起删除了。当更新点时又要添加新的画布和坐标轴,这显然造成了内存的浪费,不免出现内存泄漏的问题。

切记,我们想要的仅仅是更新点的位置,最简单的操作即:擦掉之前的点,并画上新的点。GLViewWidget只需要初始化一次。循环内只需擦除和重新描点即可。
具体解决办法如下:

# 类内,若不做类,可以把self去掉
self.distance = 120  # 设置初始视角高度                                                        
self.pos = np.zeros((100, 3))  # 初始化100个点位置                                            
self.size = np.ones(100) * 0.5  # 设置初始点大小0.5                                           
self.color = np.zeros((100, 4))  # 设置初始100个点的颜色,(0, 0, 0, 0)为透明无色                      
self.g = gl.GLGridItem()                                                               
self.size_axes = self.distance / 4                                                     
self.g.setSize(x=self.size_axes, y=self.size_axes, z=self.size_axes)                   
self.guiplot.addItem(self.g) # guiplot为GLViewWidget部件                                                         
self.sp = gl.GLScatterPlotItem(pos=self.pos, size=self.size, color=self.color, pxMode=False)  
self.guiplot.addItem(self.sp)  # 最主要的时间花费在这  

# 添加坐标轴Item             
ax = gl.GLAxisItem()    
ax.setSize(40, 40, 40)  
self.guiplot.addItem(ax)   

# 上一步完成了部件初始化,并画了初始点

# 编写更新点集坐标的函数,update()
def update():
	pass
def draw():
	while(True):
  	    self.update()
  	    self.sp.setData(pos=self.pos, size=self.size, color=self.color, pxMode=False)# 本步即画图,更新点显示      

希望能帮助到你。若有问题,欢迎留言交流学习!

你可能感兴趣的:(基于python,pyqt5,python,gui,3d)