Mid-way through overhaul. Proposed code path looks like:
setRange -> updateViewRange -> matrix dirty -> sigRangeChanged ... -> prepareForPaint -> updateAutoRange, updateMatrix if dirty
This commit is contained in:
parent
ab1b1c6adf
commit
a4103dd152
@ -12,6 +12,7 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
|
||||
"""
|
||||
_qtBaseClass = QtGui.QGraphicsObject
|
||||
def __init__(self, *args):
|
||||
self.__inform_view_on_changes = True
|
||||
QtGui.QGraphicsObject.__init__(self, *args)
|
||||
self.setFlag(self.ItemSendsGeometryChanges)
|
||||
GraphicsItem.__init__(self)
|
||||
@ -20,7 +21,7 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
|
||||
ret = QtGui.QGraphicsObject.itemChange(self, change, value)
|
||||
if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]:
|
||||
self.parentChanged()
|
||||
if change in [self.ItemPositionHasChanged, self.ItemTransformHasChanged]:
|
||||
if self.__inform_view_on_changes and change in [self.ItemPositionHasChanged, self.ItemTransformHasChanged]:
|
||||
self.informViewBoundsChanged()
|
||||
|
||||
## workaround for pyqt bug:
|
||||
|
@ -17,6 +17,10 @@ __all__ = ['ViewBox']
|
||||
class ChildGroup(ItemGroup):
|
||||
|
||||
sigItemsChanged = QtCore.Signal()
|
||||
def __init__(self, parent):
|
||||
ItemGroup.__init__(self, parent)
|
||||
# excempt from telling view when transform changes
|
||||
self._GraphicsObject__inform_view_on_change = False
|
||||
|
||||
def itemChange(self, change, value):
|
||||
ret = ItemGroup.itemChange(self, change, value)
|
||||
@ -195,6 +199,21 @@ class ViewBox(GraphicsWidget):
|
||||
def implements(self, interface):
|
||||
return interface == 'ViewBox'
|
||||
|
||||
def itemChange(self, change, value):
|
||||
ret = GraphicsWidget.itemChange(self, change, value)
|
||||
if change == self.ItemSceneChange:
|
||||
scene = self.scene()
|
||||
if scene is not None:
|
||||
scene.sigPrepareForPaint.disconnect(self.prepareForPaint)
|
||||
elif change == self.ItemSceneHasChanged:
|
||||
scene = self.scene()
|
||||
if scene is not None:
|
||||
scene.sigPrepareForPaint.connect(self.prepareForPaint)
|
||||
return ret
|
||||
|
||||
def prepareForPaint(self):
|
||||
#print "prepare"
|
||||
pass
|
||||
|
||||
def getState(self, copy=True):
|
||||
"""Return the current state of the ViewBox.
|
||||
@ -308,12 +327,14 @@ class ViewBox(GraphicsWidget):
|
||||
ch.setParentItem(None)
|
||||
|
||||
def resizeEvent(self, ev):
|
||||
#print self.name, "ViewBox.resizeEvent", self.size()
|
||||
print self.name, "ViewBox.resizeEvent", self.size()
|
||||
#self.setRange(self.range, padding=0)
|
||||
x,y = self.targetRange()
|
||||
self.setRange(xRange=x, yRange=y, padding=0)
|
||||
self.linkedXChanged()
|
||||
self.linkedYChanged()
|
||||
self.updateAutoRange()
|
||||
self.updateMatrix()
|
||||
#self.updateMatrix()
|
||||
self.sigStateChanged.emit(self)
|
||||
self.background.setRect(self.rect())
|
||||
#self._itemBoundsCache.clear()
|
||||
@ -357,7 +378,7 @@ class ViewBox(GraphicsWidget):
|
||||
Set the visible range of the ViewBox.
|
||||
Must specify at least one of *rect*, *xRange*, or *yRange*.
|
||||
|
||||
============= =====================================================================
|
||||
================== =====================================================================
|
||||
**Arguments**
|
||||
*rect* (QRectF) The full range that should be visible in the view box.
|
||||
*xRange* (min,max) The range that should be visible along the x-axis.
|
||||
@ -365,69 +386,89 @@ class ViewBox(GraphicsWidget):
|
||||
*padding* (float) Expand the view by a fraction of the requested range.
|
||||
By default, this value is set between 0.02 and 0.1 depending on
|
||||
the size of the ViewBox.
|
||||
============= =====================================================================
|
||||
*update* (bool) If True, update the range of the ViewBox immediately.
|
||||
Otherwise, the update is deferred until before the next render.
|
||||
*disableAutoRange* (bool) If True, auto-ranging is diabled. Otherwise, it is left
|
||||
unchanged.
|
||||
================== =====================================================================
|
||||
|
||||
"""
|
||||
#print self.name, "ViewBox.setRange", rect, xRange, yRange, padding
|
||||
print self.name, "ViewBox.setRange", rect, xRange, yRange, padding
|
||||
|
||||
changes = {}
|
||||
changes = {} # axes
|
||||
setRequested = [False, False]
|
||||
|
||||
if rect is not None:
|
||||
changes = {0: [rect.left(), rect.right()], 1: [rect.top(), rect.bottom()]}
|
||||
setRequested = [True, True]
|
||||
if xRange is not None:
|
||||
changes[0] = xRange
|
||||
setRequested[0] = True
|
||||
if yRange is not None:
|
||||
changes[1] = yRange
|
||||
setRequested[1] = True
|
||||
|
||||
if len(changes) == 0:
|
||||
print(rect)
|
||||
raise Exception("Must specify at least one of rect, xRange, or yRange. (gave rect=%s)" % str(type(rect)))
|
||||
|
||||
# Update axes one at a time
|
||||
changed = [False, False]
|
||||
for ax, range in changes.items():
|
||||
if padding is None:
|
||||
xpad = self.suggestPadding(ax)
|
||||
else:
|
||||
xpad = padding
|
||||
mn = min(range)
|
||||
mx = max(range)
|
||||
if mn == mx: ## If we requested 0 range, try to preserve previous scale. Otherwise just pick an arbitrary scale.
|
||||
|
||||
# If we requested 0 range, try to preserve previous scale.
|
||||
# Otherwise just pick an arbitrary scale.
|
||||
if mn == mx:
|
||||
dy = self.state['viewRange'][ax][1] - self.state['viewRange'][ax][0]
|
||||
if dy == 0:
|
||||
dy = 1
|
||||
mn -= dy*0.5
|
||||
mx += dy*0.5
|
||||
xpad = 0.0
|
||||
if any(np.isnan([mn, mx])) or any(np.isinf([mn, mx])):
|
||||
raise Exception("Not setting range [%s, %s]" % (str(mn), str(mx)))
|
||||
|
||||
# Make sure no nan/inf get through
|
||||
if not all(np.isfinite([mn, mx])):
|
||||
raise Exception("Cannot set range [%s, %s]" % (str(mn), str(mx)))
|
||||
|
||||
# Apply padding
|
||||
if padding is None:
|
||||
xpad = self.suggestPadding(ax)
|
||||
else:
|
||||
xpad = padding
|
||||
p = (mx-mn) * xpad
|
||||
mn -= p
|
||||
mx += p
|
||||
|
||||
# Set target range
|
||||
if self.state['targetRange'][ax] != [mn, mx]:
|
||||
self.state['targetRange'][ax] = [mn, mx]
|
||||
changed[ax] = True
|
||||
|
||||
aspect = self.state['aspectLocked'] # size ratio / view ratio
|
||||
if aspect is not False and len(changes) == 1:
|
||||
## need to adjust orthogonal target range to match
|
||||
size = [self.width(), self.height()]
|
||||
tr1 = self.state['targetRange'][ax]
|
||||
tr2 = self.state['targetRange'][1-ax]
|
||||
if size[1] == 0 or aspect == 0:
|
||||
ratio = 1.0
|
||||
else:
|
||||
ratio = (size[0] / float(size[1])) / aspect
|
||||
if ax == 0:
|
||||
ratio = 1.0 / ratio
|
||||
w = (tr1[1]-tr1[0]) * ratio
|
||||
d = 0.5 * (w - (tr2[1]-tr2[0]))
|
||||
self.state['targetRange'][1-ax] = [tr2[0]-d, tr2[1]+d]
|
||||
# Update viewRange to match targetRange as closely as possible while
|
||||
# accounting for aspect ratio constraint
|
||||
lockX, lockY = setRequested
|
||||
if lockX and lockY:
|
||||
lockX = False
|
||||
lockY = False
|
||||
self.updateViewRange(lockX, lockY)
|
||||
|
||||
# If ortho axes have auto-visible-only, update them now
|
||||
# Note that aspect ratio constraints and auto-visible probably do not work together..
|
||||
if changed[0] and self.state['autoVisibleOnly'][1]:
|
||||
self.updateAutoRange() ## Maybe just indicate that auto range needs to be updated?
|
||||
elif changed[1] and self.state['autoVisibleOnly'][0]:
|
||||
self.updateAutoRange()
|
||||
|
||||
# If nothing has changed, we are done.
|
||||
if not any(changed):
|
||||
#if update and self.matrixNeedsUpdate:
|
||||
#self.updateMatrix(changed)
|
||||
return
|
||||
|
||||
|
||||
if any(changed) and disableAutoRange:
|
||||
# Disable auto-range if needed
|
||||
if disableAutoRange:
|
||||
if all(changed):
|
||||
ax = ViewBox.XYAxes
|
||||
elif changed[0]:
|
||||
@ -436,26 +477,26 @@ class ViewBox(GraphicsWidget):
|
||||
ax = ViewBox.YAxis
|
||||
self.enableAutoRange(ax, False)
|
||||
|
||||
|
||||
self.sigStateChanged.emit(self)
|
||||
|
||||
# Update target rect for debugging
|
||||
if self.target.isVisible():
|
||||
self.target.setRect(self.mapRectFromItem(self.childGroup, self.targetRect()))
|
||||
|
||||
if update and (any(changed) or self.matrixNeedsUpdate):
|
||||
self.updateMatrix(changed)
|
||||
## Update view matrix only if requested
|
||||
#if update:
|
||||
#self.updateMatrix(changed)
|
||||
## Otherwise, indicate that the matrix needs to be updated
|
||||
#else:
|
||||
#self.matrixNeedsUpdate = True
|
||||
|
||||
if not update and any(changed):
|
||||
self.matrixNeedsUpdate = True
|
||||
## Inform linked views that the range has changed <<This should be moved>>
|
||||
#for ax, range in changes.items():
|
||||
#link = self.linkedView(ax)
|
||||
#if link is not None:
|
||||
#link.linkedViewChanged(self, ax)
|
||||
|
||||
for ax, range in changes.items():
|
||||
link = self.linkedView(ax)
|
||||
if link is not None:
|
||||
link.linkedViewChanged(self, ax)
|
||||
|
||||
if changed[0] and self.state['autoVisibleOnly'][1]:
|
||||
self.updateAutoRange()
|
||||
elif changed[1] and self.state['autoVisibleOnly'][0]:
|
||||
self.updateAutoRange()
|
||||
|
||||
def setYRange(self, min, max, padding=None, update=True):
|
||||
"""
|
||||
@ -572,7 +613,7 @@ class ViewBox(GraphicsWidget):
|
||||
|
||||
|
||||
|
||||
def enableAutoRange(self, axis=None, enable=True):
|
||||
def enableAutoRange(self, axis=None, enable=True, x=None, y=None):
|
||||
"""
|
||||
Enable (or disable) auto-range for *axis*, which may be ViewBox.XAxis, ViewBox.YAxis, or ViewBox.XYAxes for both
|
||||
(if *axis* is omitted, both axes will be changed).
|
||||
@ -585,24 +626,39 @@ class ViewBox(GraphicsWidget):
|
||||
#import traceback
|
||||
#traceback.print_stack()
|
||||
|
||||
# support simpler interface:
|
||||
if x is not None or y is not None:
|
||||
if x is not None:
|
||||
self.enableAutoRange(ViewBox.XAxis, x)
|
||||
if y is not None:
|
||||
self.enableAutoRange(ViewBox.YAxis, y)
|
||||
return
|
||||
|
||||
if enable is True:
|
||||
enable = 1.0
|
||||
|
||||
if axis is None:
|
||||
axis = ViewBox.XYAxes
|
||||
|
||||
needAutoRangeUpdate = False
|
||||
|
||||
if axis == ViewBox.XYAxes or axis == 'xy':
|
||||
self.state['autoRange'][0] = enable
|
||||
self.state['autoRange'][1] = enable
|
||||
axes = [0, 1]
|
||||
elif axis == ViewBox.XAxis or axis == 'x':
|
||||
self.state['autoRange'][0] = enable
|
||||
axes = [0]
|
||||
elif axis == ViewBox.YAxis or axis == 'y':
|
||||
self.state['autoRange'][1] = enable
|
||||
axes = [1]
|
||||
else:
|
||||
raise Exception('axis argument must be ViewBox.XAxis, ViewBox.YAxis, or ViewBox.XYAxes.')
|
||||
|
||||
if enable:
|
||||
for ax in axes:
|
||||
if self.state['autoRange'][ax] != enable:
|
||||
self.state['autoRange'][ax] = enable
|
||||
needAutoRangeUpdate |= (enable is not False)
|
||||
|
||||
if needAutoRangeUpdate:
|
||||
self.updateAutoRange()
|
||||
|
||||
self.sigStateChanged.emit(self)
|
||||
|
||||
def disableAutoRange(self, axis=None):
|
||||
@ -728,6 +784,7 @@ class ViewBox(GraphicsWidget):
|
||||
if oldLink is not None:
|
||||
try:
|
||||
getattr(oldLink, signal).disconnect(slot)
|
||||
oldLink.sigResized.disconnect(slot)
|
||||
except TypeError:
|
||||
## This can occur if the view has been deleted already
|
||||
pass
|
||||
@ -738,6 +795,7 @@ class ViewBox(GraphicsWidget):
|
||||
else:
|
||||
self.state['linkedViews'][axis] = weakref.ref(view)
|
||||
getattr(view, signal).connect(slot)
|
||||
view.sigResized.connect(slot)
|
||||
if view.autoRangeEnabled()[axis] is not False:
|
||||
self.enableAutoRange(axis, False)
|
||||
slot()
|
||||
@ -1233,47 +1291,126 @@ class ViewBox(GraphicsWidget):
|
||||
bounds = QtCore.QRectF(range[0][0], range[1][0], range[0][1]-range[0][0], range[1][1]-range[1][0])
|
||||
return bounds
|
||||
|
||||
def updateViewRange(self, forceX=False, forceY=False):
|
||||
## Update viewRange to match targetRange as closely as possible, given
|
||||
## aspect ratio constraints.
|
||||
|
||||
viewRange = [self.state['targetRange'][0][:], self.state['targetRange'][1][:]]
|
||||
|
||||
def updateMatrix(self, changed=None):
|
||||
## Make the childGroup's transform match the requested range.
|
||||
|
||||
if changed is None:
|
||||
changed = [False, False]
|
||||
changed = list(changed)
|
||||
# Make correction for aspect ratio constraint
|
||||
aspect = self.state['aspectLocked'] # size ratio / view ratio
|
||||
tr = self.targetRect()
|
||||
bounds = self.rect()
|
||||
|
||||
## set viewRect, given targetRect and possibly aspect ratio constraint
|
||||
aspect = self.state['aspectLocked']
|
||||
if aspect is False or bounds.height() == 0:
|
||||
self.state['viewRange'] = [self.state['targetRange'][0][:], self.state['targetRange'][1][:]]
|
||||
else:
|
||||
if aspect is not False and tr.width() != 0 and bounds.width() != 0:
|
||||
## aspect is (widget w/h) / (view range w/h)
|
||||
|
||||
|
||||
## This is the view range aspect ratio we have requested
|
||||
targetRatio = tr.width() / tr.height()
|
||||
## This is the view range aspect ratio we need to obey aspect constraint
|
||||
viewRatio = (bounds.width() / bounds.height()) / aspect
|
||||
|
||||
if targetRatio > viewRatio:
|
||||
# Decide which range to keep unchanged
|
||||
print self.name, "aspect:", aspect, "changed:", changed, "auto:", self.state['autoRange']
|
||||
if all(setRequested):
|
||||
ax = 0 if targetRatio > viewRatio else 1
|
||||
print "ax:", ax
|
||||
elif setRequested[0]:
|
||||
ax = 0
|
||||
else:
|
||||
ax = 1
|
||||
|
||||
#### these should affect viewRange, not targetRange!
|
||||
if ax == 0:
|
||||
## view range needs to be taller than target
|
||||
dy = 0.5 * (tr.width() / viewRatio - tr.height())
|
||||
if dy != 0:
|
||||
changed[1] = True
|
||||
self.state['viewRange'] = [
|
||||
self.state['targetRange'][0][:],
|
||||
[self.state['targetRange'][1][0] - dy, self.state['targetRange'][1][1] + dy]
|
||||
]
|
||||
self.state['targetRange'][1] = [self.state['targetRange'][1][0] - dy, self.state['targetRange'][1][1] + dy]
|
||||
changed[1] = True
|
||||
else:
|
||||
## view range needs to be wider than target
|
||||
dx = 0.5 * (tr.height() * viewRatio - tr.width())
|
||||
if dx != 0:
|
||||
changed[0] = True
|
||||
self.state['viewRange'] = [
|
||||
[self.state['targetRange'][0][0] - dx, self.state['targetRange'][0][1] + dx],
|
||||
self.state['targetRange'][1][:]
|
||||
]
|
||||
self.state['targetRange'][0] = [self.state['targetRange'][0][0] - dx, self.state['targetRange'][0][1] + dx]
|
||||
changed[0] = True
|
||||
|
||||
|
||||
## need to adjust orthogonal target range to match
|
||||
#size = [self.width(), self.height()]
|
||||
#tr1 = self.state['targetRange'][ax]
|
||||
#tr2 = self.state['targetRange'][1-ax]
|
||||
#if size[1] == 0 or aspect == 0:
|
||||
#ratio = 1.0
|
||||
#else:
|
||||
#ratio = (size[0] / float(size[1])) / aspect
|
||||
#if ax == 0:
|
||||
#ratio = 1.0 / ratio
|
||||
#w = (tr1[1]-tr1[0]) * ratio
|
||||
#d = 0.5 * (w - (tr2[1]-tr2[0]))
|
||||
#self.state['targetRange'][1-ax] = [tr2[0]-d, tr2[1]+d]
|
||||
#changed[1-ax] = True
|
||||
|
||||
self.state['viewRange'] = viewRange
|
||||
|
||||
# emit range change signals here!
|
||||
if changed[0]:
|
||||
self.sigXRangeChanged.emit(self, tuple(self.state['viewRange'][0]))
|
||||
if changed[1]:
|
||||
self.sigYRangeChanged.emit(self, tuple(self.state['viewRange'][1]))
|
||||
if any(changed):
|
||||
self.sigRangeChanged.emit(self, self.state['viewRange'])
|
||||
|
||||
# Inform linked views that the range has changed <<This should be moved>>
|
||||
for ax, range in changes.items():
|
||||
link = self.linkedView(ax)
|
||||
if link is not None:
|
||||
link.linkedViewChanged(self, ax)
|
||||
|
||||
self._matrixNeedsUpdate = True
|
||||
|
||||
def updateMatrix(self, changed=None):
|
||||
## Make the childGroup's transform match the requested viewRange.
|
||||
|
||||
#if changed is None:
|
||||
#changed = [False, False]
|
||||
#changed = list(changed)
|
||||
#tr = self.targetRect()
|
||||
#bounds = self.rect()
|
||||
|
||||
## set viewRect, given targetRect and possibly aspect ratio constraint
|
||||
#self.state['viewRange'] = [self.state['targetRange'][0][:], self.state['targetRange'][1][:]]
|
||||
|
||||
#aspect = self.state['aspectLocked']
|
||||
#if aspect is False or bounds.height() == 0:
|
||||
#self.state['viewRange'] = [self.state['targetRange'][0][:], self.state['targetRange'][1][:]]
|
||||
#else:
|
||||
### aspect is (widget w/h) / (view range w/h)
|
||||
|
||||
### This is the view range aspect ratio we have requested
|
||||
#targetRatio = tr.width() / tr.height()
|
||||
### This is the view range aspect ratio we need to obey aspect constraint
|
||||
#viewRatio = (bounds.width() / bounds.height()) / aspect
|
||||
|
||||
#if targetRatio > viewRatio:
|
||||
### view range needs to be taller than target
|
||||
#dy = 0.5 * (tr.width() / viewRatio - tr.height())
|
||||
#if dy != 0:
|
||||
#changed[1] = True
|
||||
#self.state['viewRange'] = [
|
||||
#self.state['targetRange'][0][:],
|
||||
#[self.state['targetRange'][1][0] - dy, self.state['targetRange'][1][1] + dy]
|
||||
#]
|
||||
#else:
|
||||
### view range needs to be wider than target
|
||||
#dx = 0.5 * (tr.height() * viewRatio - tr.width())
|
||||
#if dx != 0:
|
||||
#changed[0] = True
|
||||
#self.state['viewRange'] = [
|
||||
#[self.state['targetRange'][0][0] - dx, self.state['targetRange'][0][1] + dx],
|
||||
#self.state['targetRange'][1][:]
|
||||
#]
|
||||
|
||||
vr = self.viewRect()
|
||||
if vr.height() == 0 or vr.width() == 0:
|
||||
@ -1294,15 +1431,16 @@ class ViewBox(GraphicsWidget):
|
||||
|
||||
self.childGroup.setTransform(m)
|
||||
|
||||
if changed[0]:
|
||||
self.sigXRangeChanged.emit(self, tuple(self.state['viewRange'][0]))
|
||||
if changed[1]:
|
||||
self.sigYRangeChanged.emit(self, tuple(self.state['viewRange'][1]))
|
||||
if any(changed):
|
||||
self.sigRangeChanged.emit(self, self.state['viewRange'])
|
||||
# moved to viewRangeChanged
|
||||
#if changed[0]:
|
||||
#self.sigXRangeChanged.emit(self, tuple(self.state['viewRange'][0]))
|
||||
#if changed[1]:
|
||||
#self.sigYRangeChanged.emit(self, tuple(self.state['viewRange'][1]))
|
||||
#if any(changed):
|
||||
#self.sigRangeChanged.emit(self, self.state['viewRange'])
|
||||
|
||||
self.sigTransformChanged.emit(self) ## segfaults here: 1
|
||||
self.matrixNeedsUpdate = False
|
||||
self._matrixNeedsUpdate = False
|
||||
|
||||
def paint(self, p, opt, widget):
|
||||
if self.border is not None:
|
||||
|
@ -15,39 +15,56 @@ ViewBox test cases:
|
||||
|
||||
import pyqtgraph as pg
|
||||
app = pg.mkQApp()
|
||||
win = pg.GraphicsWindow()
|
||||
vb = win.addViewBox(name="image view")
|
||||
vb.setAspectLocked()
|
||||
p1 = win.addPlot(name="plot 1")
|
||||
p2 = win.addPlot(name="plot 2", row=1, col=0)
|
||||
win.ci.layout.setRowFixedHeight(1, 150)
|
||||
win.ci.layout.setColumnFixedWidth(1, 150)
|
||||
|
||||
def viewsMatch():
|
||||
imgData = pg.np.zeros((10, 10))
|
||||
imgData[0] = 3
|
||||
imgData[-1] = 3
|
||||
imgData[:,0] = 3
|
||||
imgData[:,-1] = 3
|
||||
|
||||
def testLinkWithAspectLock():
|
||||
global win, vb
|
||||
win = pg.GraphicsWindow()
|
||||
vb = win.addViewBox(name="image view")
|
||||
vb.setAspectLocked()
|
||||
vb.enableAutoRange(x=False, y=False)
|
||||
p1 = win.addPlot(name="plot 1")
|
||||
p2 = win.addPlot(name="plot 2", row=1, col=0)
|
||||
win.ci.layout.setRowFixedHeight(1, 150)
|
||||
win.ci.layout.setColumnFixedWidth(1, 150)
|
||||
|
||||
def viewsMatch():
|
||||
r0 = pg.np.array(vb.viewRange())
|
||||
r1 = pg.np.array(p1.vb.viewRange()[1])
|
||||
r2 = pg.np.array(p2.vb.viewRange()[1])
|
||||
match = (abs(r0[1]-r1) <= (abs(r1) * 0.001)).all() and (abs(r0[0]-r2) <= (abs(r2) * 0.001)).all()
|
||||
return match
|
||||
|
||||
p1.setYLink(vb)
|
||||
p2.setXLink(vb)
|
||||
print "link views match:", viewsMatch()
|
||||
win.show()
|
||||
print "show views match:", viewsMatch()
|
||||
imgData = pg.np.zeros((10, 10))
|
||||
imgData[0] = 1
|
||||
imgData[-1] = 1
|
||||
imgData[:,0] = 1
|
||||
imgData[:,-1] = 1
|
||||
img = pg.ImageItem(imgData)
|
||||
vb.addItem(img)
|
||||
p1.plot(x=imgData.sum(axis=0), y=range(10))
|
||||
p2.plot(x=range(10), y=imgData.sum(axis=1))
|
||||
print "add items views match:", viewsMatch()
|
||||
#p1.setAspectLocked()
|
||||
#grid = pg.GridItem()
|
||||
#vb.addItem(grid)
|
||||
p1.setYLink(vb)
|
||||
p2.setXLink(vb)
|
||||
print "link views match:", viewsMatch()
|
||||
win.show()
|
||||
print "show views match:", viewsMatch()
|
||||
img = pg.ImageItem(imgData)
|
||||
vb.addItem(img)
|
||||
vb.autoRange()
|
||||
p1.plot(x=imgData.sum(axis=0), y=range(10))
|
||||
p2.plot(x=range(10), y=imgData.sum(axis=1))
|
||||
print "add items views match:", viewsMatch()
|
||||
#p1.setAspectLocked()
|
||||
#grid = pg.GridItem()
|
||||
#vb.addItem(grid)
|
||||
pg.QtGui.QApplication.processEvents()
|
||||
pg.QtGui.QApplication.processEvents()
|
||||
#win.resize(801, 600)
|
||||
|
||||
def testAspectLock():
|
||||
global win, vb
|
||||
win = pg.GraphicsWindow()
|
||||
vb = win.addViewBox(name="image view")
|
||||
vb.setAspectLocked()
|
||||
img = pg.ImageItem(imgData)
|
||||
vb.addItem(img)
|
||||
|
||||
|
||||
#app.processEvents()
|
||||
@ -72,3 +89,7 @@ print "add items views match:", viewsMatch()
|
||||
#win.resize(600, 100)
|
||||
#app.processEvents()
|
||||
#print vb.viewRange()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
testLinkWithAspectLock()
|
||||
|
Loading…
Reference in New Issue
Block a user