rss_feed

Printing with Cairo GTK3 and python

homeHome
pagesGTK-3
pagespython
pageswidgets

You can download image used in the example below.

You can download image used in the example below.

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.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
#!/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()