Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Benjamin Jakimow
EO Time Series Viewer
Commits
841006b7
Commit
841006b7
authored
May 14, 2012
by
Luke Campagnola
Browse files
- Fixes to ScatterPlotItem bounding rect calculation
- Moved some functionality from UIGraphicsItem upstream to GraphicsItem
parent
8a9557cf
Changes
7
Hide whitespace changes
Inline
Side-by-side
graphicsItems/GraphicsItem.py
View file @
841006b7
...
...
@@ -13,6 +13,7 @@ class GraphicsItem(object):
def
__init__
(
self
,
register
=
True
):
self
.
_viewWidget
=
None
self
.
_viewBox
=
None
self
.
_connectedView
=
None
if
register
:
GraphicsScene
.
registerObject
(
self
)
## workaround for pyqt bug in graphicsscene.items()
...
...
@@ -132,12 +133,19 @@ class GraphicsItem(object):
return
vt
.
map
(
QtCore
.
QPointF
(
1
,
0
))
-
orig
,
vt
.
map
(
QtCore
.
QPointF
(
0
,
1
))
-
orig
def
pixelLength
(
self
,
direction
):
"""Return the length of one pixel in the direction indicated (in local coordinates)"""
"""
Return the length of one pixel in the direction indicated (in local coordinates)
If the result would be infinite (this happens if the device transform is not properly configured yet),
then return None instead.
"""
dt
=
self
.
deviceTransform
()
if
dt
is
None
:
return
None
viewDir
=
Point
(
dt
.
map
(
direction
)
-
dt
.
map
(
Point
(
0
,
0
)))
norm
=
viewDir
.
norm
()
try
:
norm
=
viewDir
.
norm
()
except
ZeroDivisionError
:
return
None
dti
=
dt
.
inverted
()[
0
]
return
Point
(
dti
.
map
(
norm
)
-
dti
.
map
(
Point
(
0
,
0
))).
length
()
...
...
@@ -235,23 +243,6 @@ class GraphicsItem(object):
def
viewPos
(
self
):
return
self
.
mapToView
(
self
.
mapFromParent
(
self
.
pos
()))
#def itemChange(self, change, value):
#ret = QtGui.QGraphicsObject.itemChange(self, change, value)
#if change == self.ItemParentHasChanged or change == self.ItemSceneHasChanged:
#print "Item scene changed:", self
#self.setChildScene(self) ## This is bizarre.
#return ret
#def setChildScene(self, ch):
#scene = self.scene()
#for ch2 in ch.childItems():
#if ch2.scene() is not scene:
#print "item", ch2, "has different scene:", ch2.scene(), scene
#scene.addItem(ch2)
#QtGui.QApplication.processEvents()
#print " --> ", ch2.scene()
#self.setChildScene(ch2)
def
parentItem
(
self
):
## PyQt bug -- some items are returned incorrectly.
return
GraphicsScene
.
translateGraphicsItem
(
QtGui
.
QGraphicsObject
.
parentItem
(
self
))
...
...
@@ -287,6 +278,57 @@ class GraphicsItem(object):
return
Point
(
vec
).
angle
(
Point
(
1
,
0
))
#def itemChange(self, change, value):
#ret = QtGui.QGraphicsObject.itemChange(self, change, value)
#if change == self.ItemParentHasChanged or change == self.ItemSceneHasChanged:
#print "Item scene changed:", self
#self.setChildScene(self) ## This is bizarre.
#return ret
#def setChildScene(self, ch):
#scene = self.scene()
#for ch2 in ch.childItems():
#if ch2.scene() is not scene:
#print "item", ch2, "has different scene:", ch2.scene(), scene
#scene.addItem(ch2)
#QtGui.QApplication.processEvents()
#print " --> ", ch2.scene()
#self.setChildScene(ch2)
def
_updateView
(
self
):
## called to see whether this item has a new view to connect to
## NOTE: This is called from GraphicsObject.itemChange or GraphicsWidget.itemChange.
## It is possible this item has moved to a different ViewBox or widget;
## clear out previously determined references to these.
self
.
forgetViewBox
()
self
.
forgetViewWidget
()
## check for this item's current viewbox or view widget
view
=
self
.
getViewBox
()
if
view
is
None
:
#print " no view"
return
if
self
.
_connectedView
is
not
None
and
view
is
self
.
_connectedView
():
#print " already have view", view
return
## disconnect from previous view
if
self
.
_connectedView
is
not
None
:
cv
=
self
.
_connectedView
()
if
cv
is
not
None
:
#print "disconnect:", self
cv
.
sigRangeChanged
.
disconnect
(
self
.
viewRangeChanged
)
## connect to new view
#print "connect:", self
view
.
sigRangeChanged
.
connect
(
self
.
viewRangeChanged
)
self
.
_connectedView
=
weakref
.
ref
(
view
)
self
.
viewRangeChanged
()
def
viewRangeChanged
(
self
):
"""
Called whenever the view coordinates of the ViewBox containing this item have changed.
"""
pass
graphicsItems/GraphicsObject.py
View file @
841006b7
...
...
@@ -12,4 +12,10 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
QtGui
.
QGraphicsObject
.
__init__
(
self
,
*
args
)
GraphicsItem
.
__init__
(
self
)
def
itemChange
(
self
,
change
,
value
):
ret
=
QtGui
.
QGraphicsObject
.
itemChange
(
self
,
change
,
value
)
if
change
in
[
self
.
ItemParentHasChanged
,
self
.
ItemSceneHasChanged
]:
self
.
_updateView
()
return
ret
graphicsItems/GraphicsWidget.py
View file @
841006b7
...
...
@@ -16,6 +16,12 @@ class GraphicsWidget(GraphicsItem, QtGui.QGraphicsWidget):
GraphicsItem
.
__init__
(
self
)
GraphicsScene
.
registerObject
(
self
)
## workaround for pyqt bug in graphicsscene.items()
def
itemChange
(
self
,
change
,
value
):
ret
=
QtGui
.
QGraphicsWidget
.
itemChange
(
self
,
change
,
value
)
if
change
in
[
self
.
ItemParentHasChanged
,
self
.
ItemSceneHasChanged
]:
self
.
_updateView
()
return
ret
#def getMenu(self):
#pass
...
...
graphicsItems/GridItem.py
View file @
841006b7
...
...
@@ -21,7 +21,8 @@ class GridItem(UIGraphicsItem):
self
.
picture
=
None
def
viewChangedEvent
(
self
):
def
viewRangeChanged
(
self
):
GraphicsObject
.
viewRangeChanged
(
self
)
self
.
picture
=
None
#UIGraphicsItem.viewRangeChanged(self)
#self.update()
...
...
graphicsItems/ROI.py
View file @
841006b7
...
...
@@ -1068,7 +1068,8 @@ class Handle(UIGraphicsItem):
return
dti
.
map
(
tr
.
map
(
self
.
path
))
def
viewChangedEvent
(
self
):
def
viewRangeChanged
(
self
):
GraphicsObject
.
viewRangeChanged
(
self
)
self
.
_shape
=
None
## invalidate shape, recompute later if requested.
#self.updateShape()
...
...
graphicsItems/ScatterPlotItem.py
View file @
841006b7
...
...
@@ -35,11 +35,12 @@ for k, c in coords.items():
def
makeSymbolPixmap
(
size
,
pen
,
brush
,
symbol
):
## Render a spot with the given parameters to a pixmap
image
=
QtGui
.
QImage
(
size
+
2
,
size
+
2
,
QtGui
.
QImage
.
Format_ARGB32_Premultiplied
)
penPxWidth
=
np
.
ceil
(
pen
.
width
())
image
=
QtGui
.
QImage
(
size
+
penPxWidth
,
size
+
penPxWidth
,
QtGui
.
QImage
.
Format_ARGB32_Premultiplied
)
image
.
fill
(
0
)
p
=
QtGui
.
QPainter
(
image
)
p
.
setRenderHint
(
p
.
Antialiasing
)
p
.
translate
(
size
*
0.5
+
1
,
size
*
0.5
+
1
)
p
.
translate
(
image
.
width
()
*
0.5
,
image
.
height
()
*
0.5
)
p
.
scale
(
size
,
size
)
p
.
setPen
(
pen
)
p
.
setBrush
(
brush
)
...
...
@@ -79,19 +80,16 @@ class ScatterPlotItem(GraphicsObject):
GraphicsObject
.
__init__
(
self
)
self
.
setFlag
(
self
.
ItemHasNoContents
,
True
)
self
.
data
=
np
.
empty
(
0
,
dtype
=
[(
'x'
,
float
),
(
'y'
,
float
),
(
'size'
,
float
),
(
'symbol'
,
'S1'
),
(
'pen'
,
object
),
(
'brush'
,
object
),
(
'item'
,
object
),
(
'data'
,
object
)])
#self.spots = []
#self.fragments = None
self
.
bounds
=
[
None
,
None
]
self
.
opts
=
{
'pxMode'
:
True
}
#self.spotsValid = False
#self.itemsValid = False
self
.
bounds
=
[
None
,
None
]
## caches data bounds
self
.
_maxSpotWidth
=
0
## maximum size of the scale-variant portion of all spots
self
.
_maxSpotPxWidth
=
0
## maximum size of the scale-invariant portion of all spots
self
.
_spotPixmap
=
None
self
.
opts
=
{
'pxMode'
:
True
}
self
.
setPen
(
200
,
200
,
200
,
update
=
False
)
self
.
setBrush
(
100
,
100
,
150
,
update
=
False
)
self
.
setSymbol
(
'o'
,
update
=
False
)
self
.
setSize
(
7
,
update
=
False
)
#self.setIdentical(False, update=False)
prof
.
mark
(
'1'
)
self
.
setData
(
*
args
,
**
kargs
)
prof
.
mark
(
'setData'
)
...
...
@@ -228,6 +226,7 @@ class ScatterPlotItem(GraphicsObject):
self
.
setPointData
(
kargs
[
'data'
],
dataSet
=
newData
)
#self.updateSpots()
self
.
bounds
=
[
None
,
None
]
self
.
generateSpotItems
()
self
.
sigPlotChanged
.
emit
(
self
)
...
...
@@ -345,9 +344,30 @@ class ScatterPlotItem(GraphicsObject):
def
updateSpots
(
self
,
dataSet
=
None
):
if
dataSet
is
None
:
dataSet
=
self
.
data
self
.
_maxSpotWidth
=
0
self
.
_maxSpotPxWidth
=
0
for
spot
in
dataSet
[
'item'
]:
spot
.
updateItem
()
self
.
measureSpotSizes
(
dataSet
)
def
measureSpotSizes
(
self
,
dataSet
):
for
spot
in
dataSet
[
'item'
]:
## keep track of the maximum spot size and pixel size
width
=
0
pxWidth
=
0
if
self
.
opts
[
'pxMode'
]:
pxWidth
+=
spot
.
size
()
else
:
width
+=
spot
.
size
()
pen
=
spot
.
pen
()
if
pen
.
isCosmetic
():
pxWidth
+=
pen
.
width
()
*
2
else
:
width
+=
pen
.
width
()
*
2
self
.
_maxSpotWidth
=
max
(
self
.
_maxSpotWidth
,
width
)
self
.
_maxSpotPxWidth
=
max
(
self
.
_maxSpotPxWidth
,
pxWidth
)
def
clear
(
self
):
"""Remove all spots from the scatter plot"""
self
.
clearItems
()
...
...
@@ -384,14 +404,16 @@ class ScatterPlotItem(GraphicsObject):
d2
=
d2
[
mask
]
if
frac
>=
1.0
:
## increase size of bounds based on spot size and pen width
px
=
self
.
pixelLength
(
Point
(
1
,
0
)
if
ax
==
0
else
Point
(
0
,
1
))
## determine length of pixel along this axis
if
px
is
None
:
px
=
0
minIndex
=
np
.
argmin
(
d
)
maxIndex
=
np
.
argmax
(
d
)
minVal
=
d
[
minIndex
]
maxVal
=
d
[
maxIndex
]
if
not
self
.
opts
[
'pxMode'
]:
minVal
-=
self
.
data
[
minIndex
][
'size'
]
maxVal
+=
self
.
data
[
maxIndex
][
'size'
]
self
.
bounds
[
ax
]
=
(
minVal
,
maxVal
)
spotSize
=
0.5
*
(
self
.
_maxSpotWidth
+
px
*
self
.
_maxSpotPxWidth
)
self
.
bounds
[
ax
]
=
(
minVal
-
spotSize
,
maxVal
+
spotSize
)
return
self
.
bounds
[
ax
]
elif
frac
<=
0.0
:
raise
Exception
(
"Value for parameter 'frac' must be > 0. (got %s)"
%
str
(
frac
))
...
...
@@ -412,6 +434,7 @@ class ScatterPlotItem(GraphicsObject):
for
rec
in
self
.
data
:
if
rec
[
'item'
]
is
None
:
rec
[
'item'
]
=
PathSpotItem
(
rec
,
self
)
self
.
measureSpotSizes
(
self
.
data
)
self
.
sigPlotChanged
.
emit
(
self
)
def
defaultSpotPixmap
(
self
):
...
...
@@ -430,6 +453,17 @@ class ScatterPlotItem(GraphicsObject):
ymn
=
0
ymx
=
0
return
QtCore
.
QRectF
(
xmn
,
ymn
,
xmx
-
xmn
,
ymx
-
ymn
)
def
viewRangeChanged
(
self
):
GraphicsObject
.
viewRangeChanged
(
self
)
self
.
bounds
=
[
None
,
None
]
def
paint
(
self
,
p
,
*
args
):
## NOTE: self.paint is disabled by this line in __init__:
## self.setFlag(self.ItemHasNoContents, True)
p
.
setPen
(
fn
.
mkPen
(
'r'
))
p
.
drawRect
(
self
.
boundingRect
())
def
points
(
self
):
return
self
.
data
[
'item'
]
...
...
graphicsItems/UIGraphicsItem.py
View file @
841006b7
...
...
@@ -28,7 +28,6 @@ class UIGraphicsItem(GraphicsObject):
"""
GraphicsObject
.
__init__
(
self
,
parent
)
self
.
setFlag
(
self
.
ItemSendsScenePositionChanges
)
self
.
_connectedView
=
None
if
bounds
is
None
:
self
.
_bounds
=
QtCore
.
QRectF
(
0
,
0
,
1
,
1
)
...
...
@@ -36,7 +35,7 @@ class UIGraphicsItem(GraphicsObject):
self
.
_bounds
=
bounds
self
.
_boundingRect
=
None
self
.
updateView
()
self
.
_
updateView
()
def
paint
(
self
,
*
args
):
## check for a new view object every time we paint.
...
...
@@ -45,39 +44,39 @@ class UIGraphicsItem(GraphicsObject):
def
itemChange
(
self
,
change
,
value
):
ret
=
GraphicsObject
.
itemChange
(
self
,
change
,
value
)
if
change
==
self
.
ItemParentHasChanged
or
change
==
self
.
ItemSceneHasChanged
:
#print "caught parent/scene change:", self.parentItem(), self.scene()
self
.
updateView
()
el
if
change
==
self
.
ItemScenePositionHasChanged
:
#
if change == self.ItemParentHasChanged or change == self.ItemSceneHasChanged:
## handled by GraphicsItem now.
#
#print "caught parent/scene change:", self.parentItem(), self.scene()
#
self.updateView()
if
change
==
self
.
ItemScenePositionHasChanged
:
self
.
setNewBounds
()
return
ret
def
updateView
(
self
):
## called to see whether this item has a new view to connect to
#
def updateView(self):
##
#
called to see whether this item has a new view to connect to
## check for this item's current viewbox or view widget
view
=
self
.
getViewBox
()
if
view
is
None
:
#print " no view"
return
##
#
check for this item's current viewbox or view widget
#
view = self.getViewBox()
#
if view is None:
#
#print " no view"
#
return
if
self
.
_connectedView
is
not
None
and
view
is
self
.
_connectedView
():
#print " already have view", view
return
#
if self._connectedView is not None and view is self._connectedView():
#
#print " already have view", view
#
return
## disconnect from previous view
if
self
.
_connectedView
is
not
None
:
cv
=
self
.
_connectedView
()
if
cv
is
not
None
:
#print "disconnect:", self
cv
.
sigRangeChanged
.
disconnect
(
self
.
viewRangeChanged
)
##
#
disconnect from previous view
#
if self._connectedView is not None:
#
cv = self._connectedView()
#
if cv is not None:
#
#print "disconnect:", self
#
cv.sigRangeChanged.disconnect(self.viewRangeChanged)
## connect to new view
#print "connect:", self
view
.
sigRangeChanged
.
connect
(
self
.
viewRangeChanged
)
self
.
_connectedView
=
weakref
.
ref
(
view
)
self
.
setNewBounds
()
##
#
connect to new view
#
#print "connect:", self
#
view.sigRangeChanged.connect(self.viewRangeChanged)
#
self._connectedView = weakref.ref(view)
#
self.setNewBounds()
def
boundingRect
(
self
):
if
self
.
_boundingRect
is
None
:
br
=
self
.
viewRect
()
...
...
@@ -101,15 +100,6 @@ class UIGraphicsItem(GraphicsObject):
"""Update the item's bounding rect to match the viewport"""
self
.
_boundingRect
=
None
## invalidate bounding rect, regenerate later if needed.
self
.
prepareGeometryChange
()
self
.
viewChangedEvent
()
def
viewChangedEvent
(
self
):
"""
Called whenever the view coordinates have changed.
This is a good method to override if you want to respond to change of coordinates.
"""
pass
def
setPos
(
self
,
*
args
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment