Added TextItem and example

This commit is contained in:
Luke Campagnola 2012-03-17 23:10:00 -04:00
parent cd24530eb1
commit 66dd6f974e
4 changed files with 161 additions and 7 deletions

View File

@ -17,6 +17,7 @@ examples = OrderedDict([
('Region-of-Interest', 'ROItypes.py'), ('Region-of-Interest', 'ROItypes.py'),
('GraphicsLayout', 'GraphicsLayout.py'), ('GraphicsLayout', 'GraphicsLayout.py'),
('Scatter Plot', 'ScatterPlot.py'), ('Scatter Plot', 'ScatterPlot.py'),
('Text Item', 'text.py'),
('ViewBox', 'ViewBox.py'), ('ViewBox', 'ViewBox.py'),
('Arrow', 'Arrow.py'), ('Arrow', 'Arrow.py'),
])), ])),

View File

@ -9,15 +9,44 @@ from pyqtgraph.Qt import QtCore, QtGui
import numpy as np import numpy as np
x = np.linspace(-100, 100, 1000) x = np.linspace(-20, 20, 1000)
y = np.sin(x) / x y = np.sin(x) / x
plot = pg.plot(x, y) plot = pg.plot() ## create an empty plot widget
plot.setYRange(-1, 2)
curve = plot.plot(x,y) ## add a single curve
## Create text object, use HTML tags to specify color (default is black; won't be visible) ## Create text object, use HTML tags to specify color/size
text = pg.TextItem(html='<div style="text-align: center"><span style="color: #FFF;">This is the</span><br><span style="color: #FF0;">PEAK</span></div>') text = pg.TextItem(html='<div style="text-align: center"><span style="color: #FFF;">This is the</span><br><span style="color: #FF0; font-size: 16pt;">PEAK</span></div>', anchor=(-0.3,1.3), border='w', fill=(0, 0, 255, 100))
plot.addItem(text) plot.addItem(text)
text.setPos(0, y.max()) text.setPos(0, y.max())
## Draw an arrowhead next to the text box
arrow = pg.ArrowItem(pos=(0, y.max()), angle=-45)
plot.addItem(arrow)
## Set up an animated arrow and text that track the curve
curvePoint = pg.CurvePoint(curve)
plot.addItem(curvePoint)
text2 = pg.TextItem("test", anchor=(0.5, -1.0))
text2.setParentItem(curvePoint)
arrow2 = pg.ArrowItem(angle=90)
arrow2.setParentItem(curvePoint)
## update position every 10ms
index = 0
def update():
global curvePoint, index
index = (index + 1) % len(x)
curvePoint.setPos(float(index)/(len(x)-1))
#text2.viewRangeChanged()
text2.setText('[%0.1f, %0.1f]' % (x[index], y[index]))
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(10)
## Start Qt event loop unless running in interactive mode or using pyside. ## Start Qt event loop unless running in interactive mode or using pyside.
import sys import sys

View File

@ -14,12 +14,15 @@ class CurvePoint(GraphicsObject):
Note: This class does not display anything; see CurveArrow for an applied example Note: This class does not display anything; see CurveArrow for an applied example
""" """
def __init__(self, curve, index=0, pos=None): def __init__(self, curve, index=0, pos=None, rotate=True):
"""Position can be set either as an index referring to the sample number or """Position can be set either as an index referring to the sample number or
the position 0.0 - 1.0""" the position 0.0 - 1.0
If *rotate* is True, then the item rotates to match the tangent of the curve.
"""
GraphicsObject.__init__(self) GraphicsObject.__init__(self)
#QObjectWorkaround.__init__(self) #QObjectWorkaround.__init__(self)
self._rotate = rotate
self.curve = weakref.ref(curve) self.curve = weakref.ref(curve)
self.setParentItem(curve) self.setParentItem(curve)
self.setProperty('position', 0.0) self.setProperty('position', 0.0)
@ -76,6 +79,7 @@ class CurvePoint(GraphicsObject):
p2 = self.parentItem().mapToScene(QtCore.QPointF(x[i2], y[i2])) p2 = self.parentItem().mapToScene(QtCore.QPointF(x[i2], y[i2]))
ang = np.arctan2(p2.y()-p1.y(), p2.x()-p1.x()) ## returns radians ang = np.arctan2(p2.y()-p1.y(), p2.x()-p1.x()) ## returns radians
self.resetTransform() self.resetTransform()
if self._rotate:
self.rotate(180+ ang * 180 / np.pi) ## takes degrees self.rotate(180+ ang * 180 / np.pi) ## takes degrees
QtGui.QGraphicsItem.setPos(self, *newPos) QtGui.QGraphicsItem.setPos(self, *newPos)
return True return True

120
graphicsItems/TextItem.py Normal file
View File

@ -0,0 +1,120 @@
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
from UIGraphicsItem import *
class TextItem(UIGraphicsItem):
"""
GraphicsItem displaying unscaled text (the text will always appear normal even inside a scaled ViewBox).
"""
def __init__(self, text='', color=(200,200,200), html=None, anchor=(0,0), border=None, fill=None):
"""
Arguments:
*text* The text to display
*color* The color of the text (any format accepted by pg.mkColor)
*html* If specified, this overrides both *text* and *color*
*anchor* A QPointF or (x,y) sequence indicating what region of the text box will
be anchored to the item's position. A value of (0,0) sets the upper-left corner
of the text box to be at the position specified by setPos(), while a value of (1,1)
sets the lower-right corner.
*border* A pen to use when drawing the border
*fill* A brush to use when filling within the border
"""
UIGraphicsItem.__init__(self)
self.textItem = QtGui.QGraphicsTextItem()
self.lastTransform = None
self._bounds = QtCore.QRectF()
if html is None:
self.setText(text, color)
else:
self.setHtml(html)
self.anchor = pg.Point(anchor)
self.fill = pg.mkBrush(fill)
self.border = pg.mkPen(border)
#self.setFlag(self.ItemIgnoresTransformations) ## This is required to keep the text unscaled inside the viewport
def setText(self, text, color=(200,200,200)):
color = pg.mkColor(color)
self.textItem.setDefaultTextColor(color)
self.textItem.setPlainText(text)
#html = '<span style="color: #%s; text-align: center;">%s</span>' % (color, text)
#self.setHtml(html)
def updateAnchor(self):
pass
#self.resetTransform()
#self.translate(0, 20)
def setPlainText(self, *args):
self.textItem.setPlainText(*args)
self.updateText()
def setHtml(self, *args):
self.textItem.setHtml(*args)
self.updateText()
def setTextWidth(self, *args):
self.textItem.setTextWidth(*args)
self.updateText()
def setFont(self, *args):
self.textItem.setFont(*args)
self.updateText()
def updateText(self):
self.viewRangeChanged()
#def getImage(self):
#if self.img is None:
#br = self.textItem.boundingRect()
#img = QtGui.QImage(int(br.width()), int(br.height()), QtGui.QImage.Format_ARGB32)
#p = QtGui.QPainter(img)
#self.textItem.paint(p, QtGui.QStyleOptionGraphicsItem(), None)
#p.end()
#self.img = img
#return self.img
def textBoundingRect(self):
## return the bounds of the text box in device coordinates
pos = self.mapToDevice(QtCore.QPointF(0,0))
if pos is None:
return None
tbr = self.textItem.boundingRect()
return QtCore.QRectF(pos.x() - tbr.width()*self.anchor.x(), pos.y() - tbr.height()*self.anchor.y(), tbr.width(), tbr.height())
def viewRangeChanged(self):
br = self.textBoundingRect()
if br is None:
return
self.prepareGeometryChange()
self._bounds = self.deviceTransform().inverted()[0].mapRect(br)
#print self._bounds
def boundingRect(self):
return self._bounds
def paint(self, p, *args):
tr = p.transform()
if self.lastTransform is not None:
if tr != self.lastTransform:
self.viewRangeChanged()
self.lastTransform = tr
tbr = self.textBoundingRect()
#p.setPen(pg.mkPen('r'))
#p.drawRect(self.boundingRect())
p.setPen(self.border)
p.setBrush(self.fill)
#p.fillRect(tbr)
p.resetTransform()
p.drawRect(tbr)
p.translate(tbr.left(), tbr.top())
self.textItem.paint(p, QtGui.QStyleOptionGraphicsItem(), None)