GraphicsLayout.py 4.92 KB
Newer Older
1 2
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph.functions as fn
3
from .GraphicsWidget import GraphicsWidget
Luke Campagnola's avatar
Luke Campagnola committed
4 5 6 7
## Must be imported at the end to avoid cyclic-dependency hell:
from .ViewBox import ViewBox
from .PlotItem import PlotItem
from .LabelItem import LabelItem
8 9 10 11 12

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


    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
        
34
    def nextColumn(self, colspan=1):
35 36 37 38 39
        """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
        
40
    def nextCol(self, *args, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
41
        """Alias of nextColumn"""
42 43
        return self.nextColumn(*args, **kargs)
        
44
    def addPlot(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
45 46 47 48 49
        """
        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.
        """
50 51 52 53 54
        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
55 56 57 58 59
        """
        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.
        """
60 61 62 63
        vb = ViewBox(**kargs)
        self.addItem(vb, row, col, rowspan, colspan)
        return vb
        
64
    def addLabel(self, text=' ', row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
65 66 67 68 69
        """
        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.
        """
70 71 72 73
        text = LabelItem(text, **kargs)
        self.addItem(text, row, col, rowspan, colspan)
        return text
        
74
    def addLayout(self, row=None, col=None, rowspan=1, colspan=1, **kargs):
Luke Campagnola's avatar
Luke Campagnola committed
75 76 77 78 79
        """
        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.
        """
80 81 82 83
        layout = GraphicsLayout(**kargs)
        self.addItem(layout, row, col, rowspan, colspan)
        return layout
        
84
    def addItem(self, item, row=None, col=None, rowspan=1, colspan=1):
Luke Campagnola's avatar
Luke Campagnola committed
85 86 87 88
        """
        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.
        """
89 90 91 92 93 94 95 96 97 98 99 100 101
        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
102
        """Return the item in (*row*, *col*)"""
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
        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
123
        """Remove *item* from the layout."""
124 125 126 127 128 129 130 131 132 133
        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 = []
134
        for i in list(self.items.keys()):
135 136 137
            self.removeItem(i)