TextItem.py 5.61 KB
Newer Older
1 2
from ..Qt import QtCore, QtGui
from ..Point import Point
3
from .UIGraphicsItem import *
4
from .. import functions as fn
Luke Campagnola's avatar
Luke Campagnola committed
5 6 7 8 9

class TextItem(UIGraphicsItem):
    """
    GraphicsItem displaying unscaled text (the text will always appear normal even inside a scaled ViewBox). 
    """
Luke Campagnola's avatar
Luke Campagnola committed
10
    def __init__(self, text='', color=(200,200,200), html=None, anchor=(0,0), border=None, fill=None, angle=0):
Luke Campagnola's avatar
Luke Campagnola committed
11
        """
tommy3001's avatar
tommy3001 committed
12
        ==============  =================================================================================
13
        **Arguments:**
tommy3001's avatar
tommy3001 committed
14 15 16 17 18 19 20 21 22
        *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
23
        ==============  =================================================================================
Luke Campagnola's avatar
Luke Campagnola committed
24
        """
Luke Campagnola's avatar
Luke Campagnola committed
25 26 27 28 29
        
        ## not working yet
        #*angle*      Angle in degrees to rotate text (note that the rotation assigned in this item's 
                     #transformation will be ignored)
                     
30
        self.anchor = Point(anchor)
31
        #self.angle = 0
Luke Campagnola's avatar
Luke Campagnola committed
32 33
        UIGraphicsItem.__init__(self)
        self.textItem = QtGui.QGraphicsTextItem()
34
        self.textItem.setParentItem(self)
Luke Campagnola's avatar
Luke Campagnola committed
35 36 37 38 39 40
        self.lastTransform = None
        self._bounds = QtCore.QRectF()
        if html is None:
            self.setText(text, color)
        else:
            self.setHtml(html)
41 42
        self.fill = fn.mkBrush(fill)
        self.border = fn.mkPen(border)
43 44
        self.rotate(angle)
        self.setFlag(self.ItemIgnoresTransformations)  ## This is required to keep the text unscaled inside the viewport
Luke Campagnola's avatar
Luke Campagnola committed
45 46

    def setText(self, text, color=(200,200,200)):
47 48 49 50 51
        """
        Set the text and color of this item. 
        
        This method sets the plain text of the item; see also setHtml().
        """
52
        color = fn.mkColor(color)
Luke Campagnola's avatar
Luke Campagnola committed
53 54
        self.textItem.setDefaultTextColor(color)
        self.textItem.setPlainText(text)
55
        self.updateText()
Luke Campagnola's avatar
Luke Campagnola committed
56 57 58 59 60 61 62 63 64
        #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):
65 66 67 68 69
        """
        Set the plain text to be rendered by this item. 
        
        See QtGui.QGraphicsTextItem.setPlainText().
        """
Luke Campagnola's avatar
Luke Campagnola committed
70 71 72 73
        self.textItem.setPlainText(*args)
        self.updateText()
        
    def setHtml(self, *args):
74 75 76 77 78
        """
        Set the HTML code to be rendered by this item. 
        
        See QtGui.QGraphicsTextItem.setHtml().
        """
Luke Campagnola's avatar
Luke Campagnola committed
79 80 81 82
        self.textItem.setHtml(*args)
        self.updateText()
        
    def setTextWidth(self, *args):
83 84 85 86 87 88 89 90
        """
        Set the width of the text.
        
        If the text requires more space than the width limit, then it will be
        wrapped into multiple lines.
        
        See QtGui.QGraphicsTextItem.setTextWidth().
        """
Luke Campagnola's avatar
Luke Campagnola committed
91 92 93 94
        self.textItem.setTextWidth(*args)
        self.updateText()
        
    def setFont(self, *args):
95 96 97 98 99
        """
        Set the font for this text. 
        
        See QtGui.QGraphicsTextItem.setFont().
        """
Luke Campagnola's avatar
Luke Campagnola committed
100 101 102
        self.textItem.setFont(*args)
        self.updateText()
        
103 104 105 106 107
    #def setAngle(self, angle):
        #self.angle = angle
        #self.updateText()
        
        
Luke Campagnola's avatar
Luke Campagnola committed
108 109
    def updateText(self):
        
110 111 112 113 114 115 116 117 118 119
        ## Needed to maintain font size when rendering to image with increased resolution
        self.textItem.resetTransform()
        #self.textItem.rotate(self.angle)
        if self._exportOpts is not False and 'resolutionScale' in self._exportOpts:
            s = self._exportOpts['resolutionScale']
            self.textItem.scale(s, s)
        
        #br = self.textItem.mapRectToParent(self.textItem.boundingRect())
        self.textItem.setPos(0,0)
        br = self.textItem.boundingRect()
120
        apos = self.textItem.mapToParent(Point(br.width()*self.anchor.x(), br.height()*self.anchor.y()))
121 122 123 124 125 126 127 128 129 130
        #print br, apos
        self.textItem.setPos(-apos.x(), -apos.y())
        
    #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())
Luke Campagnola's avatar
Luke Campagnola committed
131 132 133


    def viewRangeChanged(self):
134
        self.updateText()
Luke Campagnola's avatar
Luke Campagnola committed
135 136

    def boundingRect(self):
137
        return self.textItem.mapToParent(self.textItem.boundingRect()).boundingRect()
Luke Campagnola's avatar
Luke Campagnola committed
138 139 140 141 142 143 144 145
        
    def paint(self, p, *args):
        tr = p.transform()
        if self.lastTransform is not None:
            if tr != self.lastTransform:
                self.viewRangeChanged()
        self.lastTransform = tr
        
Luke Campagnola's avatar
Luke Campagnola committed
146 147 148 149 150
        if self.border.style() != QtCore.Qt.NoPen or self.fill.style() != QtCore.Qt.NoBrush:
            p.setPen(self.border)
            p.setBrush(self.fill)
            p.setRenderHint(p.Antialiasing, True)
            p.drawPolygon(self.textItem.mapToParent(self.textItem.boundingRect()))
Luke Campagnola's avatar
Luke Campagnola committed
151 152