#+TITLE: Printing with Cairo GTK3 and python #+DATE: 2015-12-05 12:00:00 UTC #+DESCRIPTION: Example demonstrating how to draw a graphic and position it on a page for printing complete with preview and printer settings dialog. #+FILETAGS: GTK-3:python:widgets #+CATEGORY: python #+SLUG: printing-with-cairo-gtk3-python #+BEGIN_COMMENT .. title: Printing with Cairo GTK3 and python .. slug: printing-with-cairo-gtk3-python .. date: 2015-12-05 12:00:00 UTC .. tags: GTK-3, python, widgets .. category: python .. description: Example demonstrating how to draw a graphic and position it on a page for printing complete with preview and printer settings dialog. .. type: text #+END_COMMENT #+CAPTION: You can download image used in the example below. [[../../../images/gtk/gtk_print_example_01.png]] #+CAPTION: You can download image used in the example below. [[../../../images/misc/testing-256px.png]] This example uses the gtk3 toolkit the same toolkit used by popular software like gimp and inkscape, it should be quite easy to convert to gtk2 if required the advantage of using gtk is that the libraries are cross platform so you should be able to print on all platform however i have only tested this on ubuntu 15.04 so far. #+BEGIN_SRC python #!/usr/bin/python # -*- coding: utf8 -*- from gi.repository import Gtk, Pango, PangoCairo#, cairo import cairo # a4 = 210 x 297 page_width = 210 page_height = 297 page_margin_top = 20 dpi = 600 _mm_dpi = 72 / 25.4 class PrintExample(Gtk.Window): def __init__(self): self.print_image() def print_image(self): """setup the paper size, print settings and kick of the print operation""" ps = Gtk.PaperSize.new_custom("cc", "cc", page_width, page_height, Gtk.Unit.MM) print_settings = Gtk.PrintSettings() print_settings.set_resolution(dpi) page_setup = Gtk.PageSetup() page_setup.set_paper_size(ps) page_setup.set_bottom_margin(10.0, Gtk.Unit.MM) page_setup.set_left_margin(5.0, Gtk.Unit.MM) page_setup.set_right_margin(4.5, Gtk.Unit.MM) page_setup.set_top_margin(10.0, Gtk.Unit.MM) page_setup.set_orientation(Gtk.PageOrientation.PORTRAIT) print_operation = Gtk.PrintOperation() print_operation.set_n_pages(1) print_operation.set_default_page_setup(page_setup) print_operation.set_print_settings(print_settings) print_operation.connect("draw_page", self.draw_page) print_operation.set_export_filename("example.pdf") result = print_operation.run(Gtk.PrintOperationAction.PREVIEW, None) print(result) def draw_page (self, operation, print_context, page_number): """draw with cairo to the print context layout for printing on sticky labels on an a4 sheet""" cr = print_context.get_cairo_context() cr.set_source_rgb(0, 0, 0) ims=cairo.ImageSurface.create_from_png("test.png") cr.set_line_width(1) desc = Pango.FontDescription("sans 5") layou_title_text = PangoCairo.create_layout(cr) layou_title_text.set_text("Title Text", -1) layou_title_text.set_font_description(desc) layou_title_text.set_width(100 * Pango.SCALE) layou_title_text.set_wrap(Pango.WrapMode.WORD) layou_desc_text = PangoCairo.create_layout(cr) layou_desc_text.set_text("Lorem ipsum .....", -1) layou_desc_text.set_font_description(desc) layou_desc_text.set_width(50 * Pango.SCALE) layou_desc_text.set_wrap(Pango.WrapMode.CHAR) #offset is the distance from the start of one box to the next including blank space rectangle_x_offset = 40.5 * _mm_dpi rectangle_y_offset = 21.5 * _mm_dpi #actual size of the box rectangle_width = 38 * _mm_dpi rectangle_height = 21.5 * _mm_dpi columns = int(page_width / 38) rows = int((page_height-page_margin_top) / 21) for column in range(0, columns): for row in range(0, rows): #qr code cr.set_line_width(0.1) cr.save() cr.translate(column * rectangle_x_offset, row * rectangle_y_offset + 15) cr.scale(0.15, 0.15) cr.set_source_surface(ims, 0, 0) cr.paint() cr.restore() #rectangle cr.rectangle(column * rectangle_x_offset , row * rectangle_y_offset, rectangle_width , rectangle_height ) cr.stroke() #title text cr.save() cr.move_to(column * rectangle_x_offset + 4, row * rectangle_y_offset + 4) PangoCairo.update_layout(cr, layou_title_text) PangoCairo.show_layout (cr, layou_title_text) cr.restore() #description text cr.save() cr.move_to(column * rectangle_x_offset + 50, row * rectangle_y_offset + 14) PangoCairo.update_layout(cr, layou_desc_text) PangoCairo.show_layout (cr, layou_desc_text) cr.restore() win = PrintExample() Gtk.main() #+END_SRC