Hi there!

I implemented a Print method with gtk-2.10 PrintOperations... It was not
easy, because of some transformations issues inside matplotlib...

My wish is: The plot window navigation bar should provide a print button
in future. I think many people are missing this button.

Here, I want to provide code for printing the screen, just like the save
button on the navigation bar.
It is the merge of the save button's code and the code in
pygtk-2.10.1/examples/pygtk-demo/demos/print_editor.py

Maybe, there is already a lot of print code available for other GUI
backends, if it will be shared, it could become part of matplotlib...

Yours, Achim

(Sorry, I could not provide a running program, because I am short in
time. The code is working in a bigger project
http://www.fkp.physik.tu-darmstadt.de/damaris/ )
class gtk_print_code:
    
    def __init__(self):
        # fill your gui code...
        
        self.matplot_figure = None
        self.toolbar_print_button=self.xml_gui.get_widget("toolbar_print_button")
        self.matplot_canvas = matplotlib.backends.backend_gtkagg.FigureCanvasGTKAgg(self.matplot_figure)


    def print_button_switch(self, widget):
        """
        decides what to print... and prints, layout is done by responsible class
        """
        if not hasattr(gtk, "PrintOperation"):
            return

        # copied and modified from pygtk-2.10.1/examples/pygtk-demo/demos/print_editor.py

        print_ = gtk.PrintOperation()

        # will come from config
        settings=None
        if settings is not None:
            print_.set_print_settings(settings)

        page_setup=None
        if page_setup is not None:
            print_.set_default_page_setup(page_setup)

        print_data = {} # Not really needed here
        print_.connect("begin_print", self.begin_print, print_data)
        print_.connect("draw_page", self.draw_page, print_data)
        
        try:
            res = print_.run(gtk.PRINT_OPERATION_ACTION_PRINT_DIALOG, self.main_window)
        except gobject.GError, ex:
            error_dialog = gtk.MessageDialog(self.main_window,
                                             gtk.DIALOG_DESTROY_WITH_PARENT,
                                             gtk._MESSAGE_ERROR,
                                             gtk.BUTTONS_CLOSE,
                                             ("Error printing file:\n%s" % str(ex)))
            error_dialog.connect("response", gtk.Widget.destroy)
            error_dialog.show()
        else:
            if res == gtk.PRINT_OPERATION_RESULT_APPLY:
                settings = print_.get_print_settings()

    def begin_print(self, operation, context, print_data):
        """
        layout of one page with matplotlib graph
        """
        operation.set_n_pages( 1 )


    def draw_page(self, operation, context, page_nr, print_data):
        """
        render a single page
        """
        # copied and modified from pygtk-2.10.1/examples/pygtk-demo/demos/print_editor.py

        if page_nr != 0:
            return

        # check page dimensions
        # all lengths in inch: name *_in
        page_setup=context.get_page_setup()
        dpi=context.get_dpi_x()
        if dpi!=context.get_dpi_y():
            print "draw_page: dpi_x!=dpi_y, I am not prepared for that"
        freewidth_in = float(context.get_width())/dpi
        freeheight_in = float(context.get_height())/dpi
        fc = self.matplot_canvas.switch_backends(matplotlib.backends.backend_cairo.FigureCanvasCairo)
        fc.figure.dpi.set(dpi)
        orig_w_in, orig_h_in = fc.figure.get_size_inches()
        orig_f_color=fc.figure.get_facecolor()
        orig_e_color=fc.figure.get_edgecolor()

        # scale to maximum
        fc.figure.set_facecolor("w")
        fc.figure.set_edgecolor("w")

        #  maximum scale with constant aspect
        scale=min(freewidth_in/orig_w_in, freeheight_in/orig_h_in)
        fc.figure.set_size_inches(orig_w_in*scale, orig_h_in*scale)
        width_in_points, height_in_points = orig_w_in * dpi * scale, orig_h_in * dpi * scale
        renderer = matplotlib.backends.backend_cairo.RendererCairo (fc.figure.dpi)
        renderer.width  = width_in_points
        renderer.height = height_in_points
        # centered picture
        renderer.matrix_flipy = cairo.Matrix (yy=-1,xx=1,
                                              y0=page_setup.get_top_margin(gtk.UNIT_POINTS)+(height_in_points+freeheight_in*dpi)/2.0,
                                              x0=page_setup.get_left_margin(gtk.UNIT_POINTS)+(freewidth_in*dpi-width_in_points)/2.0)
        
        renderer.set_ctx_from_surface (context.get_cairo_context().get_target())
        # unfortunateley there is need for extra treatment of text
        renderer.ctx.translate(page_setup.get_left_margin(gtk.UNIT_POINTS)+(freewidth_in*dpi-width_in_points)/2.0,
                               page_setup.get_top_margin(gtk.UNIT_POINTS)-height_in_points/2.0+freeheight_in*dpi/2.0)
        renderer.ctx.save() # important! there will be no effect of previous statement without save
        fc.figure.draw(renderer)

        # restore the figure's settings
        fc.figure.set_size_inches(orig_w_in, orig_h_in)
        fc.figure.set_facecolor(orig_f_color)
        fc.figure.set_edgecolor(orig_e_color)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to