Expanded ref checks

Fixed ref cycle in ImageItem -> HistogramLutItem
This commit is contained in:
Luke Campagnola 2014-04-27 13:07:31 -04:00
parent d45eadc9a5
commit 0479507dbb
2 changed files with 36 additions and 47 deletions

View File

@ -17,6 +17,7 @@ from .. import functions as fn
import numpy as np
from .. import debug as debug
import weakref
__all__ = ['HistogramLUTItem']
@ -42,7 +43,7 @@ class HistogramLUTItem(GraphicsWidget):
"""
GraphicsWidget.__init__(self)
self.lut = None
self.imageItem = None
self.imageItem = lambda: None # fake a dead weakref
self.layout = QtGui.QGraphicsGridLayout()
self.setLayout(self.layout)
@ -138,7 +139,7 @@ class HistogramLUTItem(GraphicsWidget):
#self.region.setBounds([vr.top(), vr.bottom()])
def setImageItem(self, img):
self.imageItem = img
self.imageItem = weakref.ref(img)
img.sigImageChanged.connect(self.imageChanged)
img.setLookupTable(self.getLookupTable) ## send function pointer, not the result
#self.gradientChanged()
@ -150,11 +151,11 @@ class HistogramLUTItem(GraphicsWidget):
self.update()
def gradientChanged(self):
if self.imageItem is not None:
if self.imageItem() is not None:
if self.gradient.isLookupTrivial():
self.imageItem.setLookupTable(None) #lambda x: x.astype(np.uint8))
self.imageItem().setLookupTable(None) #lambda x: x.astype(np.uint8))
else:
self.imageItem.setLookupTable(self.getLookupTable) ## send function pointer, not the result
self.imageItem().setLookupTable(self.getLookupTable) ## send function pointer, not the result
self.lut = None
#if self.imageItem is not None:
@ -178,14 +179,14 @@ class HistogramLUTItem(GraphicsWidget):
#self.update()
def regionChanging(self):
if self.imageItem is not None:
self.imageItem.setLevels(self.region.getRegion())
if self.imageItem() is not None:
self.imageItem().setLevels(self.region.getRegion())
self.sigLevelsChanged.emit(self)
self.update()
def imageChanged(self, autoLevel=False, autoRange=False):
profiler = debug.Profiler()
h = self.imageItem.getHistogram()
h = self.imageItem().getHistogram()
profiler('get histogram')
if h[0] is None:
return

View File

@ -7,54 +7,42 @@ import numpy as np
import gc, weakref
app = pg.mkQApp()
def processEvents():
for i in range(3):
gc.collect()
app.processEvents()
# processEvents ignored DeferredDelete events; we must process these
# manually.
app.sendPostedEvents(None, pg.QtCore.QEvent.DeferredDelete)
def assert_alldead(refs):
for ref in refs:
assert ref() is None
#def test_PlotItem():
#for i in range(10):
#plt = pg.PlotItem()
#plt.plot(np.random.normal(size=10000))
#processEvents()
#ot = pg.debug.ObjTracker()
#plots = []
#for i in range(10):
#plt = pg.PlotItem()
#plt.plot(np.random.normal(size=10000))
#plots.append(plt)
#processEvents()
#ot.diff()
#del plots
#processEvents()
#ot.diff()
#return ot
def mkrefs(*objs):
return map(weakref.ref, objs)
def test_PlotWidget():
def mkref(*args, **kwds):
iv = pg.PlotWidget(*args, **kwds)
return weakref.ref(iv)
def mkobjs(*args, **kwds):
w = pg.PlotWidget(*args, **kwds)
data = pg.np.array([1,5,2,4,3])
c = w.plot(data, name='stuff')
w.addLegend()
# test that connections do not keep objects alive
w.plotItem.vb.sigRangeChanged.connect(mkrefs)
app.focusChanged.connect(w.plotItem.vb.invertY)
# return weakrefs to a bunch of objects that should die when the scope exits.
return mkrefs(w, c, data, w.plotItem, w.plotItem.vb, w.plotItem.getMenu(), w.plotItem.getAxis('left'))
for i in range(5):
assert mkref()() is None
assert_alldead(mkobjs())
def test_ImageView():
def mkref(*args, **kwds):
iv = pg.ImageView(*args, **kwds)
return weakref.ref(iv)
def mkobjs():
iv = pg.ImageView()
data = np.zeros((10,10,5))
iv.setImage(data)
return mkrefs(iv, iv.imageItem, iv.view, iv.ui.histogram, data)
for i in range(5):
assert mkref()() is None
assert_alldead(mkobjs())
if __name__ == '__main__':
ot = test_PlotItem()