diff options
Diffstat (limited to 'silx/gui/plot/PlotToolButtons.py')
-rw-r--r-- | silx/gui/plot/PlotToolButtons.py | 95 |
1 files changed, 87 insertions, 8 deletions
diff --git a/silx/gui/plot/PlotToolButtons.py b/silx/gui/plot/PlotToolButtons.py index fc5fcf4..e354877 100644 --- a/silx/gui/plot/PlotToolButtons.py +++ b/silx/gui/plot/PlotToolButtons.py @@ -30,6 +30,7 @@ The following QToolButton are available: - :class:`.AspectToolButton` - :class:`.YAxisOriginToolButton` - :class:`.ProfileToolButton` +- :class:`.SymbolToolButton` """ @@ -38,10 +39,15 @@ __license__ = "MIT" __date__ = "27/06/2017" +import functools import logging +import weakref + from .. import icons from .. import qt +from .items import SymbolMixIn + _logger = logging.getLogger(__name__) @@ -52,7 +58,7 @@ class PlotToolButton(qt.QToolButton): def __init__(self, parent=None, plot=None): super(PlotToolButton, self).__init__(parent) - self._plot = None + self._plotRef = None if plot is not None: self.setPlot(plot) @@ -60,7 +66,7 @@ class PlotToolButton(qt.QToolButton): """ Returns the plot connected to the widget. """ - return self._plot + return None if self._plotRef is None else self._plotRef() def setPlot(self, plot): """ @@ -68,13 +74,18 @@ class PlotToolButton(qt.QToolButton): :param plot: :class:`.PlotWidget` instance on which to operate. """ - if self._plot is plot: + previousPlot = self.plot() + + if previousPlot is plot: return - if self._plot is not None: - self._disconnectPlot(self._plot) - self._plot = plot - if self._plot is not None: - self._connectPlot(self._plot) + if previousPlot is not None: + self._disconnectPlot(previousPlot) + + if plot is None: + self._plotRef = None + else: + self._plotRef = weakref.ref(plot) + self._connectPlot(plot) def _connectPlot(self, plot): """ @@ -282,3 +293,71 @@ class ProfileToolButton(PlotToolButton): def computeProfileIn2D(self): self._profileDimensionChanged(2) + + +class SymbolToolButton(PlotToolButton): + """A tool button with a drop-down menu to control symbol size and marker. + + :param parent: See QWidget + :param plot: The `~silx.gui.plot.PlotWidget` to control + """ + + def __init__(self, parent=None, plot=None): + super(SymbolToolButton, self).__init__(parent=parent, plot=plot) + + self.setToolTip('Set symbol size and marker') + self.setIcon(icons.getQIcon('plot-symbols')) + + menu = qt.QMenu(self) + + # Size slider + + slider = qt.QSlider(qt.Qt.Horizontal) + slider.setRange(1, 20) + slider.setValue(SymbolMixIn._DEFAULT_SYMBOL_SIZE) + slider.setTracking(False) + slider.valueChanged.connect(self._sizeChanged) + widgetAction = qt.QWidgetAction(menu) + widgetAction.setDefaultWidget(slider) + menu.addAction(widgetAction) + + menu.addSeparator() + + # Marker actions + + for marker, name in zip(SymbolMixIn.getSupportedSymbols(), + SymbolMixIn.getSupportedSymbolNames()): + action = qt.QAction(name, menu) + action.setCheckable(False) + action.triggered.connect( + functools.partial(self._markerChanged, marker)) + menu.addAction(action) + + self.setMenu(menu) + self.setPopupMode(qt.QToolButton.InstantPopup) + + def _sizeChanged(self, value): + """Manage slider value changed + + :param int value: Marker size + """ + plot = self.plot() + if plot is None: + return + + for item in plot._getItems(withhidden=True): + if isinstance(item, SymbolMixIn): + item.setSymbolSize(value) + + def _markerChanged(self, marker): + """Manage change of marker. + + :param str marker: Letter describing the marker + """ + plot = self.plot() + if plot is None: + return + + for item in plot._getItems(withhidden=True): + if isinstance(item, SymbolMixIn): + item.setSymbol(marker) |