LegendItem: Make ItemSample customizable (#1404)

* LegendItem: Introduce itemStyles and provide ToggleItem

Show example

* Minor cleanup of the legend item and test

* Make ItemSample customizable

* Remove example modifications

* Changes for sampleType according to review
This commit is contained in:
Dennis Göries 2021-01-05 06:02:08 +01:00 committed by GitHub
parent e209be20e5
commit b622e22877
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 12 deletions

View File

@ -39,7 +39,6 @@ legend.addItem(c1, 'curve1')
legend.addItem(c2, 'curve2') legend.addItem(c2, 'curve2')
legend.addItem(s1, 'scatter') legend.addItem(s1, 'scatter')
## Start Qt event loop unless running in interactive mode or using pyside. ## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys

View File

@ -9,7 +9,7 @@ from .PlotDataItem import PlotDataItem
from .GraphicsWidgetAnchor import GraphicsWidgetAnchor from .GraphicsWidgetAnchor import GraphicsWidgetAnchor
from .BarGraphItem import BarGraphItem from .BarGraphItem import BarGraphItem
__all__ = ['LegendItem'] __all__ = ['LegendItem', 'ItemSample']
class LegendItem(GraphicsWidget, GraphicsWidgetAnchor): class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
@ -29,7 +29,8 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
def __init__(self, size=None, offset=None, horSpacing=25, verSpacing=0, def __init__(self, size=None, offset=None, horSpacing=25, verSpacing=0,
pen=None, brush=None, labelTextColor=None, frame=True, pen=None, brush=None, labelTextColor=None, frame=True,
labelTextSize='9pt', rowCount=1, colCount=1, **kwargs): labelTextSize='9pt', rowCount=1, colCount=1,
sampleType=None, **kwargs):
""" """
============== =============================================================== ============== ===============================================================
**Arguments:** **Arguments:**
@ -52,6 +53,7 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
accepted by :func:`mkPen <pyqtgraph.mkPen>` is allowed. accepted by :func:`mkPen <pyqtgraph.mkPen>` is allowed.
labelTextSize Size to use when drawing legend text. Accepts CSS style labelTextSize Size to use when drawing legend text. Accepts CSS style
string arguments, e.g. '9pt'. string arguments, e.g. '9pt'.
sampleType Customizes the item sample class of the `LegendItem`.
============== =============================================================== ============== ===============================================================
""" """
@ -73,6 +75,14 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
if size is not None: if size is not None:
self.setGeometry(QtCore.QRectF(0, 0, self.size[0], self.size[1])) self.setGeometry(QtCore.QRectF(0, 0, self.size[0], self.size[1]))
if sampleType is not None:
if not issubclass(sampleType, GraphicsWidget):
raise RuntimeError("Only classes of type `GraphicsWidgets` "
"are allowed as `sampleType`")
self.sampleType = sampleType
else:
self.sampleType = ItemSample
self.opts = { self.opts = {
'pen': fn.mkPen(pen), 'pen': fn.mkPen(pen),
'brush': fn.mkBrush(brush), 'brush': fn.mkBrush(brush),
@ -80,9 +90,26 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
'labelTextSize': labelTextSize, 'labelTextSize': labelTextSize,
'offset': offset, 'offset': offset,
} }
self.opts.update(kwargs) self.opts.update(kwargs)
def setSampleType(self, sample):
"""Set the new sample item claspes"""
if sample is self.sampleType:
return
# Clear the legend, but before create a list of items
items = list(self.items)
self.sampleType = sample
self.clear()
# Refill the legend with the item list and new sample item
for sample, label in items:
plot_item = sample.item
plot_name = label.text
self.addItem(plot_item, plot_name)
self.updateSize()
def offset(self): def offset(self):
"""Get the offset position relative to the parent.""" """Get the offset position relative to the parent."""
return self.opts['offset'] return self.opts['offset']
@ -183,10 +210,10 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
""" """
label = LabelItem(name, color=self.opts['labelTextColor'], label = LabelItem(name, color=self.opts['labelTextColor'],
justify='left', size=self.opts['labelTextSize']) justify='left', size=self.opts['labelTextSize'])
if isinstance(item, ItemSample): if isinstance(item, self.sampleType):
sample = item sample = item
else: else:
sample = ItemSample(item) sample = self.sampleType(item)
self.items.append((sample, label)) self.items.append((sample, label))
self._addItemToLayout(sample, label) self._addItemToLayout(sample, label)
self.updateSize() self.updateSize()
@ -301,11 +328,8 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
class ItemSample(GraphicsWidget): class ItemSample(GraphicsWidget):
"""Class responsible for drawing a single item in a LegendItem (sans label) """Class responsible for drawing a single item in a LegendItem (sans label)
This may be subclassed to draw custom graphics in a Legend.
""" """
# TODO: make this more generic; let items decide how it should be look.
def __init__(self, item): def __init__(self, item):
GraphicsWidget.__init__(self) GraphicsWidget.__init__(self)
self.item = item self.item = item

View File

@ -1,9 +1,7 @@
import pytest
import pyqtgraph as pg import pyqtgraph as pg
def test_legend_item_basics(): def test_legend_item_basics():
app = pg.mkQApp() pg.mkQApp()
legend = pg.LegendItem() legend = pg.LegendItem()
@ -21,6 +19,7 @@ def test_legend_item_basics():
assert legend.labelTextSize() == '9pt' assert legend.labelTextSize() == '9pt'
assert legend.brush() == pg.mkBrush(None) assert legend.brush() == pg.mkBrush(None)
assert legend.pen() == pg.mkPen(None) assert legend.pen() == pg.mkPen(None)
assert legend.sampleType is pg.ItemSample
# Set brush # Set brush
# ---------------------------------------------------- # ----------------------------------------------------