GraphicsLayout.py 4.94 KB
Newer Older
1 2 3 4 5 6 7 8
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph.functions as fn
from GraphicsWidget import GraphicsWidget

__all__ = ['GraphicsLayout']
class GraphicsLayout(GraphicsWidget):
    """
    Used for laying out GraphicsWidgets in a grid.
Luke Campagnola's avatar
Luke Campagnola committed
9
    This is usually created automatically as part of a :class:`GraphicsWindow <pyqtgraph.GraphicsWindow>` or :class:`GraphicsLayoutWidget <pyqtgraph.GraphicsLayoutWidget>`.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
    """


    def __init__(self, parent=None, border=None):
        GraphicsWidget.__init__(self, parent)
        if border is True:
            border = (100,100,100)
        self.border = border
        self.layout = QtGui.QGraphicsGridLayout()
        self.setLayout(self.layout)
        self.items = {}
        self.rows = {}
        self.currentRow = 0
        self.currentCol = 0
    
    def nextRow(self):
        """Advance to next row for automatic item placement"""
        self.currentRow += 1
        self.currentCol = 0
        
30
    def nextColumn(self, colspan=1):
31 32 33 34 35
        """Advance to next column, while returning the current column number 
        (generally only for internal use--called by addItem)"""
        self.currentCol += colspan
        return self.currentCol-colspan
        
36
    def nextCol(self, *args, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
37
        """Advance to next column for automatic item placement"""
38 39
        return self.nextColumn(*args, **kargs)
        
40
    def addPlot(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
41 42 43 44 45
        """
        Create a PlotItem and place it in the next available cell (or in the cell specified)
        All extra keyword arguments are passed to :func:`PlotItem.__init__ <pyqtgraph.PlotItem.__init__>`
        Returns the created item.
        """
46 47 48 49 50
        plot = PlotItem(**kargs)
        self.addItem(plot, row, col, rowspan, colspan)
        return plot
        
    def addViewBox(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
51 52 53 54 55
        """
        Create a ViewBox and place it in the next available cell (or in the cell specified)
        All extra keyword arguments are passed to :func:`ViewBox.__init__ <pyqtgraph.ViewBox.__init__>`
        Returns the created item.
        """
56 57 58 59
        vb = ViewBox(**kargs)
        self.addItem(vb, row, col, rowspan, colspan)
        return vb
        
60
    def addLabel(self, text=' ', row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
61 62 63 64 65
        """
        Create a LabelItem with *text* and place it in the next available cell (or in the cell specified)
        All extra keyword arguments are passed to :func:`LabelItem.__init__ <pyqtgraph.LabelItem.__init__>`
        Returns the created item.
        """
66 67 68 69
        text = LabelItem(text, **kargs)
        self.addItem(text, row, col, rowspan, colspan)
        return text
        
70
    def addLayout(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
71 72 73 74 75
        """
        Create an empty GraphicsLayout and place it in the next available cell (or in the cell specified)
        All extra keyword arguments are passed to :func:`GraphicsLayout.__init__ <pyqtgraph.GraphicsLayout.__init__>`
        Returns the created item.
        """
76 77 78 79
        layout = GraphicsLayout(**kargs)
        self.addItem(layout, row, col, rowspan, colspan)
        return layout
        
80
    def addItem(self, item, row=None, col=None, rowspan=1, colspan=1):
Luke Campagnola's avatar
Luke Campagnola committed
81 82 83 84
        """
        Add an item to the layout and place it in the next available cell (or in the cell specified).
        The item must be an instance of a QGraphicsWidget subclass.
        """
85 86 87 88 89 90 91 92 93 94 95 96 97
        if row is None:
            row = self.currentRow
        if col is None:
            col = self.nextCol(colspan)
            
        if row not in self.rows:
            self.rows[row] = {}
        self.rows[row][col] = item
        self.items[item] = (row, col)
        
        self.layout.addItem(item, row, col, rowspan, colspan)

    def getItem(self, row, col):
Luke Campagnola's avatar
Luke Campagnola committed
98
        """Return the item in (*row*, *col*)"""
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
        return self.row[row][col]

    def boundingRect(self):
        return self.rect()
        
    def paint(self, p, *args):
        if self.border is None:
            return
        p.setPen(fn.mkPen(self.border))
        for i in self.items:
            r = i.mapRectToParent(i.boundingRect())
            p.drawRect(r)
    
    def itemIndex(self, item):
        for i in range(self.layout.count()):
            if self.layout.itemAt(i).graphicsItem() is item:
                return i
        raise Exception("Could not determine index of item " + str(item))
    
    def removeItem(self, item):
Luke Campagnola's avatar
Luke Campagnola committed
119
        """Remove *item* from the layout."""
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
        ind = self.itemIndex(item)
        self.layout.removeAt(ind)
        self.scene().removeItem(item)
        r,c = self.items[item]
        del self.items[item]
        del self.rows[r][c]
        self.update()
    
    def clear(self):
        items = []
        for i in self.items.keys():
            self.removeItem(i)


## Must be imported at the end to avoid cyclic-dependency hell:
from ViewBox import ViewBox
from PlotItem import PlotItem
137
from LabelItem import LabelItem