2121from ..base import PlotWidget , PlotWidgetContainer
2222
2323
24+ class MPLNavBar (NavBar ):
25+ """
26+ Toolbar subclass that shows a hint when the mouse is outside the axes
27+ and can pin a clipboard confirmation message, so hovering won't overwrite it
28+ for a few seconds to make the message visible.
29+ """
30+
31+ def __init__ (self , canvas : FCanvas , parent : QtWidgets .QWidget ):
32+ self .clipboardMessageActive = False
33+ self .hintMessage = "Click on plot to copy coordinates"
34+ super ().__init__ (canvas , parent )
35+ self .clipboardResetTimer = QtCore .QTimer (self )
36+ self .clipboardResetTimer .setSingleShot (True )
37+ self .clipboardResetTimer .timeout .connect (self .clearClipboardMessage )
38+
39+ def set_message (self , s : str ) -> None :
40+ if self .clipboardMessageActive :
41+ return
42+ super ().set_message (s if s else self .hintMessage )
43+
44+ def showClipboardMessage (self , message : str ) -> None :
45+ self .clipboardMessageActive = True
46+ super ().set_message (message )
47+ self .clipboardResetTimer .start (1500 )
48+
49+ def clearClipboardMessage (self ) -> None :
50+ self .clipboardMessageActive = False
51+ super ().set_message (self .hintMessage )
52+
53+
2454class MPLPlot (FCanvas ):
2555 """
2656 This is the basic matplotlib canvas widget we are using for matplotlib
@@ -30,6 +60,9 @@ class MPLPlot(FCanvas):
3060 It can be used as any QT widget.
3161 """
3262
63+ #: Signal(str) -- emitted when content is copied to the clipboard, with a message describing what was copied.
64+ clipboardCopied = QtCore .Signal (str )
65+
3366 def __init__ (self , parent : Optional [QtWidgets .QWidget ] = None ,
3467 width : float = 4.0 , height : float = 3.0 , dpi : int = 150 ,
3568 constrainedLayout : bool = True ):
@@ -117,21 +150,22 @@ def toClipboard(self) -> None:
117150 clipboard = QtWidgets .QApplication .clipboard ()
118151 clipboard .setImage (QtGui .QImage .fromData (buf .getvalue ()))
119152 buf .close ()
153+ self .clipboardCopied .emit ("Figure copied to clipboard" )
120154
121155 def metaToClipboard (self ) -> None :
122156 clipboard = QtWidgets .QApplication .clipboard ()
123157 meta_info_string = "\n " .join (f"{ k } : { v } "
124158 for k , v in self ._meta_info .items ())
125159 clipboard .setText (meta_info_string )
160+ self .clipboardCopied .emit ("Meta copied to clipboard" )
126161
127162 def coordinateToClipboard (self , event : Event ) -> None :
128163 if isinstance (event , LocationEvent ):
129164 clipboard = QtWidgets .QApplication .clipboard ()
130165 if event .xdata is not None and event .ydata is not None :
131166 coord_info_string = '({:.8g}, {:.8g})' .format (event .xdata , event .ydata )
132167 clipboard .setText (coord_info_string )
133- else :
134- pass
168+ self .clipboardCopied .emit (f"Copied { coord_info_string } to clipboard" )
135169
136170 def setFigureTitle (self , title : str ) -> None :
137171 """Add a title to the figure."""
@@ -163,14 +197,15 @@ def __init__(self, parent: Optional[PlotWidgetContainer] = None):
163197 self .plot = MPLPlot ()
164198
165199 #: the matplotlib toolbar
166- self .mplBar = NavBar (self .plot , self )
200+ self .mplBar = MPLNavBar (self .plot , self )
167201
168202 self .addMplBarOptions ()
169203 defaultIconSize = int (16 * dpiScalingFactor (self ))
170204 self .mplBar .setIconSize (QtCore .QSize (defaultIconSize , defaultIconSize ))
171205 layout = QtWidgets .QVBoxLayout (self )
172206 layout .addWidget (self .plot )
173207 layout .addWidget (self .mplBar )
208+
174209 self .setLayout (layout )
175210 self .addPlotOptions ()
176211
@@ -206,10 +241,12 @@ def addMplBarOptions(self) -> None:
206241 self .mplBar .addSeparator ()
207242 self .mplBar .addAction ('Copy Figure' , self .plot .toClipboard )
208243 self .mplBar .addAction ('Copy Meta' , self .plot .metaToClipboard )
209-
244+
210245 def addPlotOptions (self ) -> None :
211246 """Add options for copying coordinates to the clipboard"""
212247 self .plot .mpl_connect ('button_press_event' , self .plot .coordinateToClipboard )
248+ self .plot .clipboardCopied .connect (self .mplBar .showClipboardMessage )
249+ self .mplBar .clearClipboardMessage ()
213250
214251
215252def figureDialog () -> Tuple [Figure , QtWidgets .QDialog ]:
@@ -218,5 +255,4 @@ def figureDialog() -> Tuple[Figure, QtWidgets.QDialog]:
218255 :return: The figure object of the plot, and the dialog window object.
219256 """
220257 widget = MPLPlotWidget ()
221- return widget .plot .fig , widgetDialog (widget )
222-
258+ return widget .plot .fig , widgetDialog (widget )
0 commit comments