summaryrefslogtreecommitdiff
path: root/silx/gui/plot/PlotToolButtons.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/gui/plot/PlotToolButtons.py')
-rw-r--r--silx/gui/plot/PlotToolButtons.py95
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)