赞
踩
今天收到私信,提问者想要的效果为如何动态更新点的位置。而他刷新画布的方式是在循环内直接对部件GLViewWidget进行重置操作,并遇到了内存泄漏的问题。
这个问题我考虑了一下:对GLViewWidget进行初始化,会直接把该部件内的所有内容(画布、坐标轴等)直接删除。若想继续更新点的位置,需要重新添加新的画布和坐标轴等,而这一块是需要占用内存和时间的。若在循环内一直做这个操作,不仅容易造成内存泄漏,也可能会造成窗口卡顿(多线程QThread情况下)。
抓住问题关键,我们想要一直更新点的位置,并提高帧数。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)# 本步即画图,更新点显示
希望能帮助到你。若有问题,欢迎留言交流学习!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。