added Copy to Clipboard (PNG) and context menu for matplotlib canvas (PNG and SVG)
This commit is contained in:
@@ -2312,6 +2312,9 @@ class MonitorWidgets:
|
|||||||
# Matplot in einen GTK-Rahmen stopfen
|
# Matplot in einen GTK-Rahmen stopfen
|
||||||
self.matplot_canvas = FigureCanvas( self.matplot_figure )
|
self.matplot_canvas = FigureCanvas( self.matplot_figure )
|
||||||
|
|
||||||
|
# Add right-click context menu to canvas
|
||||||
|
self.matplot_canvas.connect("button-press-event", self.on_canvas_button_press)
|
||||||
|
|
||||||
self.display_table = self.xml_gui.get_object( "display_table" )
|
self.display_table = self.xml_gui.get_object( "display_table" )
|
||||||
self.display_table.attach( self.matplot_canvas, 0, 6, 0, 1, gtk.AttachOptions.EXPAND | gtk.AttachOptions.FILL, gtk.AttachOptions.EXPAND | gtk.AttachOptions.FILL, 0, 0 )
|
self.display_table.attach( self.matplot_canvas, 0, 6, 0, 1, gtk.AttachOptions.EXPAND | gtk.AttachOptions.FILL, gtk.AttachOptions.EXPAND | gtk.AttachOptions.FILL, 0, 0 )
|
||||||
self.matplot_canvas.show( )
|
self.matplot_canvas.show( )
|
||||||
@@ -2740,7 +2743,102 @@ class MonitorWidgets:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def on_canvas_button_press(self, widget, event):
|
||||||
|
"""Handle button press events on matplotlib canvas"""
|
||||||
|
if event.button == 3: # Right click
|
||||||
|
self.show_canvas_context_menu(event)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def show_canvas_context_menu(self, event):
|
||||||
|
"""Show context menu for matplotlib canvas"""
|
||||||
|
menu = gtk.Menu()
|
||||||
|
|
||||||
|
# Copy as PNG
|
||||||
|
item_copy_png = gtk.MenuItem(label="Copy as PNG")
|
||||||
|
item_copy_png.connect("activate", self.copy_canvas_as_png)
|
||||||
|
menu.append(item_copy_png)
|
||||||
|
|
||||||
|
# Copy as SVG
|
||||||
|
item_copy_svg = gtk.MenuItem(label="Copy as SVG")
|
||||||
|
item_copy_svg.connect("activate", self.copy_canvas_as_svg)
|
||||||
|
menu.append(item_copy_svg)
|
||||||
|
|
||||||
|
menu.show_all()
|
||||||
|
menu.popup(None, None, None, None, event.button, event.time)
|
||||||
|
|
||||||
|
def copy_canvas_as_png(self, widget):
|
||||||
|
"""Copy canvas to clipboard as PNG"""
|
||||||
|
self.copy_display_data_to_clipboard(widget)
|
||||||
|
|
||||||
|
def copy_canvas_as_svg(self, widget):
|
||||||
|
"""Copy canvas as SVG to clipboard"""
|
||||||
|
if self.matplot_figure is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Save the original figure size
|
||||||
|
original_size = self.matplot_figure.get_size_inches()
|
||||||
|
# Save figure to a buffer as SVG
|
||||||
|
import io as iomodule
|
||||||
|
buf = iomodule.StringIO()
|
||||||
|
self.matplot_figure.set_size_inches(6, 4)
|
||||||
|
self.matplot_figure.savefig(buf, format='svg', bbox_inches='tight')
|
||||||
|
buf.seek(0)
|
||||||
|
|
||||||
|
# Copy SVG text to clipboard
|
||||||
|
clipboard = gtk.Clipboard.get(gdk.SELECTION_CLIPBOARD)
|
||||||
|
clipboard.set_text(buf.read(), -1)
|
||||||
|
clipboard.store()
|
||||||
|
self.matplot_figure.set_size_inches(original_size)
|
||||||
|
|
||||||
|
log("Figure copied to clipboard as SVG")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log(f"Error copying figure as SVG: {e}")
|
||||||
|
|
||||||
def copy_display_data_to_clipboard( self, widget, data=None ):
|
def copy_display_data_to_clipboard( self, widget, data=None ):
|
||||||
|
"""
|
||||||
|
Copy matplotlib figure as PNG image to clipboard
|
||||||
|
Also keep text data copy functionality as fallback
|
||||||
|
"""
|
||||||
|
# First, try to copy the matplotlib figure as image
|
||||||
|
# Save the original figure size
|
||||||
|
original_size = self.matplot_figure.get_size_inches()
|
||||||
|
if self.matplot_figure is not None and self.matplot_canvas is not None:
|
||||||
|
try:
|
||||||
|
# Save figure to a temporary buffer as PNG
|
||||||
|
import io as iomodule
|
||||||
|
buf = iomodule.BytesIO()
|
||||||
|
self.matplot_figure.set_size_inches(6, 4)
|
||||||
|
self.matplot_figure.savefig(buf, format='png', dpi=300, bbox_inches='tight')
|
||||||
|
buf.seek(0)
|
||||||
|
|
||||||
|
# Load the PNG data into a GdkPixbuf
|
||||||
|
from gi.repository import GdkPixbuf
|
||||||
|
loader = GdkPixbuf.PixbufLoader.new_with_type('png')
|
||||||
|
loader.write(buf.read())
|
||||||
|
loader.close()
|
||||||
|
pixbuf = loader.get_pixbuf()
|
||||||
|
|
||||||
|
# Copy to clipboard
|
||||||
|
clipboard = gtk.Clipboard.get(gdk.SELECTION_CLIPBOARD)
|
||||||
|
clipboard.set_image(pixbuf)
|
||||||
|
clipboard.store()
|
||||||
|
# Restore original figure size
|
||||||
|
self.matplot_figure.set_size_inches(original_size)
|
||||||
|
# Redraw the canvas to ensure it stays visible
|
||||||
|
self.matplot_canvas.draw()
|
||||||
|
|
||||||
|
log("Figure copied to clipboard as PNG image")
|
||||||
|
return
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
log("Error copying figure to clipboard: %s" % str(e))
|
||||||
|
# Fall through to text data copy
|
||||||
|
|
||||||
|
# Fallback: copy data as text (original functionality)
|
||||||
|
# can be removed after thorough testing
|
||||||
data_to_save = self.displayed_data[ : ]
|
data_to_save = self.displayed_data[ : ]
|
||||||
if self.displayed_data[ 1 ] is None:
|
if self.displayed_data[ 1 ] is None:
|
||||||
# nothing to save
|
# nothing to save
|
||||||
|
|||||||
Reference in New Issue
Block a user