#!/usr/bin/env python3
#
'''
.. module:: printbutton
:synopsis: Select file or directory using a widget
.. moduleauthor:: Cor de Vries <c.p.de.vries@sron.nl>
'''
import os
import matplotlib
if __name__ == "__main__":
# matplotlib.use('GTK3Agg')
matplotlib.use('GTK3Cairo')
# Poppler needs debian package: gir1.2-poppler-0.18
import gi
gi.require_version('Poppler', '0.18')
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Poppler, GLib, GObject
[docs]class PrintPlot:
'''
Opens a Gtk.PrintOperation widget for sending the given plot and text to the printer.
Needs the debian package **gir1.2-poppler-0.18** (or higher version) to be installed.
Args:
* `canvas` = the canvas containing the plot
* `window` = not used
Kwargs:
* `text` = text to be with after the plot (only operational for 'portrait' mode)
* `orientation` = 'portrait' or 'landscape'
* `fontsize` = fontsize (pts) to be used for the text
* `font` = fonttype to be used
* `parent` = not used
'''
def __init__(self,canvas,window,text=None,orientation='portrait',fontsize=12,
font="Bitstream Vera Sans Mono",parent=None):
self.window=window
self.pts=fontsize # font heigth
self.font=font
self.text=text
self.operation = Gtk.PrintOperation()
# if parent is not None:
# self.operation.set_transient_for(parent)
self.operation.connect('begin-print', self.begin_print, None)
self.operation.connect('draw-page', self.draw_page, None)
self.operation.connect('end-print', self.end_print, None)
self.tmpfilename='/tmp/tmp_pyprint%d.pdf' % os.getpid()
# self.pheight=11.69
self.pheight=11.29
if text is not None:
self.pheight=self.pheight/2.0
orientation='portrait'
csize=canvas.figure.get_size_inches() # get original size
self.settings=Gtk.PrintSettings()
self.page_setup=Gtk.PageSetup()
if orientation == 'landscape':
self.settings.set_orientation(Gtk.PageOrientation.LANDSCAPE)
self.page_setup.set_orientation(Gtk.PageOrientation.LANDSCAPE)
self.page_setup.set_paper_size(Gtk.PaperSize("iso_a4"))
self.operation.set_print_settings(self.settings)
self.operation.set_default_page_setup(self.page_setup)
# canvas.figure.set_size_inches(11.69, 8.27)
canvas.figure.set_size_inches(11.0, 7.50)
else:
# canvas.figure.set_size_inches(8.27, self.pheight)
canvas.figure.set_size_inches(8.0, self.pheight)
canvas.figure.savefig(self.tmpfilename,format='pdf',papertype='a4',orientation=orientation)
canvas.figure.set_size_inches(csize[0],csize[1]) # set back to original size
file_uri = GLib.filename_to_uri(os.path.abspath(self.tmpfilename))
self.doc = Poppler.Document.new_from_file(file_uri)
try:
res = self.operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.window)
except GObject.GError as ex:
error_dialog = Gtk.MessageDialog(self.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.PrintOperationResult.APPLY:
settings = self.operation.get_print_settings()
def begin_print(self, operation, print_ctx, print_data):
operation.set_n_pages(self.doc.get_n_pages())
def end_print(self,context,print_ctx, print_data):
os.unlink(self.tmpfilename)
def draw_page(self, operation, print_ctx, page_num, print_data):
cr = print_ctx.get_cairo_context()
page = self.doc.get_page(page_num)
page.render(cr)
#
# the text
#
if self.text is not None:
cr.select_font_face(self.font)
cr.set_font_size(self.pts)
cr.set_line_width(132)
voffset=self.pheight*72 # convert inch to points
for i,line in enumerate(self.text):
cr.move_to(5,voffset+(i+1)*int(9./7.*self.pts))
if len(line) > 71:
cr.show_text(line[:71])
x_bearing, y_bearing, width, height, x_advance, y_advance=cr.text_extents(line[:71])
cr.move_to(x_advance+int(0.5*self.pts),0.0+(i+1)*int(9./7.*self.pts))
cr.show_text(line[71:])
else:
cr.show_text(line)
cr.set_line_width(0.1)
cr.stroke_preserve()
cr.set_source_rgb(0.0, 0.0, 0.0)
cr.fill()
class Pbutton:
def __init__(self,plot,toolbar,canvas,orientation='portrait',parent=None):
self.butt_print=Gtk.ToolButton()
self.butt_print.set_icon_name(Gtk.STOCK_PRINT)
self.butt_print.connect("clicked",self.pprint)
self.butt_print.set_tooltip_text('print plot')
self.butt_print.show()
nitems=toolbar.get_n_items()
toolbar.insert(self.butt_print,(nitems-3))
toolbar.show_all()
self.plot=plot
self.canvas=canvas
self.orientation=orientation
self.parent=parent
def pprint(self,widget):
try:
text=self.plot.caption
except:
text=None
self.ppp=PrintPlot(self.canvas,None,text=text,parent=self.parent,
orientation=self.orientation)
# ===============================================
if __name__ == "__main__":
import numpy
from matplotlib.figure import Figure
# from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar
def quit(event):
Gtk.main_quit()
# from printbutton import printbutton
window=Gtk.Window()
box=Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=1)
window.add(box)
window.connect("destroy",quit)
figure=Figure(figsize=(4,3),dpi=100)
canvas = FigureCanvas(figure)
canvas.set_size_request(600,400)
toolbar = NavigationToolbar(canvas,window)
box.pack_start(canvas,True,True,1)
box.pack_start(toolbar,False,False,1)
ax={}
ax[0]=figure.add_subplot(2,1,1)
ax[1]=figure.add_subplot(2,1,2)
pi=3.141592
xx=numpy.arange(100)/100.0*pi*2.0
yy=numpy.sin(xx)
y2=numpy.cos(xx)
# printb=Pbutton(figure,toolbar,canvas,orientation='landscape')
printb=Pbutton(figure,toolbar,canvas,orientation='portrait')
ax[0].set_xlabel('X')
ax[0].set_ylabel('Y')
ax[0].set_title('test')
ax[0].plot(xx,yy,'b-')
ax[1].set_xlabel('X')
ax[1].set_ylabel('Y')
ax[1].set_title('test')
ax[1].plot(xx,y2,'b-')
figure.caption=["test1 pp","test2 pp"]
canvas.draw()
window.show_all()
Gtk.main()