在gtk3/python中创建打印作业 [英] Creating print job in gtk3/python

查看:95
本文介绍了在gtk3/python中创建打印作业的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些想要轻松打印的信息(活动参与者列表).无需花哨的布局,只需一个带有多列的表格,并在可能的情况下在文本行之间绘制一条线以提高可读性.将需要打印风景以使其完全适合(可以通过GtkPageSetup完成).

I have some information (a list of participants to an event) which I want to print out easily. No need for fancy layout, just a table with several columns, and if possible a drawn line in between the lines of text for better readability. Will need to print landscape to make it all fit (can be done via a GtkPageSetup).

我正在使用Python,而我在Linux上,因此必须使用GtkPrintUnixDialog接口.我一直在Internet上进行搜索,但找不到有关如何实现此目标的任何示例.

I'm using Python, and I'm on Linux so will have to use the GtkPrintUnixDialog interface. I've been searching on Internet but can't find any example on how this could possibly be achieved.

为简化此问题:它仅供我自己使用,所以已知的纸张尺寸(A4).

To simplify the problem: it's for my own use only, so known paper size (A4).

我遇到的问题基本上有两个:1)创建适合打印的格式正确的文本,2)将其发送给打印机.

The problem that I have is basically two-fold: 1) create a properly formatted text, suitable for printing, and 2) send this to the printer.

关于从哪里开始的任何建议?还是更好的完整示例?

Any suggestions on where to start? Or better, complete examples?

推荐答案

我搜索我的旧印刷示例,但需要一个开始:

I search for my old print examples, but for a start:

您可以写到pdf表面,然后打印pdf,或者 将绘图代码放在on_print函数上.请注意,它不会打印您看到的内容,而是在打印面上绘制的内容.像普通的cairo上下文一样绘制上下文,但是一些方法不可用(不适合打印上下文),而其他方法(例如新页面)已添加.如果找到示例,我将给出一个更加不言自明的答案. 找到一个ex:

You could write to pdf surface, and print pdf, or put the drawing code on on_print function. Note, it does not print what you see, but what you draw on print surface. Draw the context like a regular cairo context, but a few methods are not available(don't fit in print context) while others, like new page, are added. If I find the example, I will come with a answer more self-explanatory. find an ex:

def on_button_clicked(self, widget):
    ps = Gtk.PaperSize.new_custom("cc", "cc", 210, 297, Gtk.Unit.MM)
    st = Gtk.PrintSettings()
    s = Gtk.PageSetup()
    s.set_paper_size(ps)
    s.set_bottom_margin(4.3, Gtk.Unit.MM)
    s.set_left_margin(4.3, Gtk.Unit.MM)
    s.set_right_margin(4.3, Gtk.Unit.MM)
    s.set_top_margin(4.3, Gtk.Unit.MM)
    s.set_orientation(Gtk.PageOrientation.LANDSCAPE)
    # ret =  Gtk.print_run_page_setup_dialog(self, s, st)
    pd = Gtk.PrintOperation()
    pd.set_n_pages(1)
    pd.set_default_page_setup(s)
    pd.connect("begin_print", self.bg)
    pd.connect("draw_page", self.draw_page)
    # print(ret, s, st)
    pd.set_export_filename("test.pdf")
    result = pd.run(Gtk.PrintOperationAction.EXPORT, None) #play with action, but for test export first; if it's ok, then action.PRINT
    print (result)  # handle errors etc.
    # Gtk.PaperSize.free(ps) - not needed in py

以上内容可能是按下按钮或其他方式

the above may be on button press or whatever

def draw_page (self, operation, context, page_number):
    end = self.layout.get_line_count()
    cr = context.get_cairo_context()
    cr.set_source_rgb(0, 0, 0)
    i = 0
    start = 0
    start_pos = 0
    iter = self.layout.get_iter()
    while 1:
        if i >= start:
            line = iter.get_line()
            print(line)
            _, logical_rect = iter.get_line_extents()
            # x_bearing, y_bearing, lwidth, lheight = logical_rect
            baseline = iter.get_baseline()
            if i == start:
                start_pos = 12000 / 1024.0  # 1024.0 is float(pango.SCALE)
            cr.move_to(0 / 1024.0, baseline / 1024.0 - start_pos)
            PangoCairo.show_layout_line(cr, line)
        i += 1
        if not (i < end and iter.next_line()):
            break

那只是一个基本的例子.请注意,布局是一种Pa​​ngo布局:

That's just a basic example. Note that layout is a pango layout:

self.layout = cx.create_pango_layout()
    self.layout.set_width(int(w / 4 * Pango.SCALE))
    self.layout.set_text(text, len(text))
    num_lines = self.layout.get_line_count()
    page_height = 0
    self.layout.set_font_description(Pango.FontDescription("Georgia Bold 12"))
    k = 0
    for line in range(num_lines):
        if k == 4:
            self.layout.set_font_description(Pango.FontDescription("Georgia 10"))
        layout_line = self.layout.get_line(line)
        ink_rect, logical_rect = layout_line.get_extents()
        lheight = 1200
        line_height = lheight / 1024.0  # 1024.0 is float(pango.SCALE)
        page_height += line_height
        k += 1
        print ("page_height ", page_height)

复制/粘贴功能示例:

    #!/usr/bin/python
from gi.repository import Gtk, Pango, PangoCairo
import cairo

text = '''
Text.
I have some information (a list of participants to an event) which I 
want to print out easily.
No need for fancy layout,
just a table with several columns,
and if possible a drawn line in between the lines of
 text for better readability.
'''


class MyWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Hello World Printing")
        self.button = Gtk.Button(label="Print A Rectangle")
        self.button.connect("clicked", self.on_button_clicked)
        self.add(self.button)

    def on_button_clicked(self, widget):
        ps = Gtk.PaperSize.new_custom("cc", "cc", 210, 297, Gtk.Unit.MM)
        st = Gtk.PrintSettings()
        s = Gtk.PageSetup()
        s.set_paper_size(ps)
        s.set_bottom_margin(4.3, Gtk.Unit.MM)
        s.set_left_margin(4.3, Gtk.Unit.MM)
        s.set_right_margin(4.3, Gtk.Unit.MM)
        s.set_top_margin(4.3, Gtk.Unit.MM)
        s.set_orientation(Gtk.PageOrientation.LANDSCAPE)
        # ret =  Gtk.print_run_page_setup_dialog(self, s, st)
        pd = Gtk.PrintOperation()
        pd.set_n_pages(1)
        pd.set_default_page_setup(s)
        pd.connect("begin_print", self.bg)
        pd.connect("draw_page", self.draw_page)
        # print(ret, s, st)
        pd.set_export_filename("test.pdf")
        result = pd.run(Gtk.PrintOperationAction.EXPORT, None)
        print (result)  # handle errors etc.
        # Gtk.PaperSize.free(ps)

    def bg(self, op, cx):
        w = cx.get_width()
        h = cx.get_height()
        self.layout = cx.create_pango_layout()
        self.layout.set_width(int(w / 4 * Pango.SCALE))
        self.layout.set_text(text, len(text))
        num_lines = self.layout.get_line_count()
        page_height = 0
        self.layout.set_font_description(Pango.FontDescription("Georgia Bold 12"))
        k = 0
        for line in range(num_lines):
            if k == 4:
                self.layout.set_font_description(Pango.FontDescription("Georgia 10"))
            layout_line = self.layout.get_line(line)
            ink_rect, logical_rect = layout_line.get_extents()
            # print(logical_rect, ink_rect)
            # x_bearing, y_bearing, lwidth, lheight = logical_rect
            lheight = 1200
            line_height = lheight / 1024.0  # 1024.0 is float(pango.SCALE)
            page_height += line_height
            # page_height is the current location on a page.
            # It adds the the line height on each pass through the loop
            # Once it is greater then the height supplied by context.get_height
            # it marks the line and sets the current page height back to 0
            k += 1
            print ("page_height ", page_height)


    def box(self, w, h, x, y, cx):
        w, h = int(w), int(h)
        cx.set_font_size(100)
        cx.set_source_rgb(0, 0, 0)
        cx.rectangle(x, y, w, h)
        cx.stroke()
        yy = 120
        cx.select_font_face("Times", 0, 1)
        ex = cx.text_extents("TEGOLA ROMÂNIA SRL")[2]
        cx.move_to(w / 2 - ex / 2 + x, 105 + y)
        cx.show_text("TEGOLA ROMÂNIA SRL")
        ex = cx.text_extents("Str. Plevnei, nr. 5, Buzău")[2]
        cx.move_to(w / 2 - ex / 2 + x, 210 + y)
        cx.show_text("Str. Plevnei, nr. 5, Buzău")
        ex = cx.text_extents("Tel.: 0238/710.280")[2]
        cx.move_to(w / 2 - ex / 2 + x, 320 + y)
        cx.show_text("Tel.: 0238/710.280")
        ex = cx.text_extents("Fax : 0238/710021")[2]
        cx.move_to(w / 2 - ex / 2 + x, 415 + y)
        cx.show_text("Fax : 0238/710021")
        cx.set_font_size(90)
        cx.move_to(x + 120, 520 + y)
        ex = cx.text_extents("Compoziție:")[2]
        cx.show_text("Compoziție:")
        cx.select_font_face("Times", 0, 0)
        cx.move_to(x + 125 + ex, 520 + y)
        cx.show_text("Polimer bituminos, liant și")
        cx.move_to(x + 5, 620 + y)
        cx.show_text("material de umplutură de înaltă calitate.")
        cx.move_to(x + 5, 720 + y)
        cx.show_text("Nu conține gudron.")
        cx.move_to(x + 5, 800 + y)
        cx.select_font_face("Times", 0, 1)
        ex = cx.text_extents("Instrucțiuni de utilizare:")[2]
        cx.show_text("Instrucțiuni de utilizare:")
        cx.select_font_face("Times", 0, 0)
        cx.move_to(x + 10 + ex, 800 + y)
        cx.show_text("Suprafețele se")


    def draw_page1(self, operation, context, page_nr=None):
        ctx = context.get_cairo_context()
        w = context.get_width()
        h = context.get_height()
        ww, hh = int(w / 4), int(h / 2)
        self.k = 0
        for x in range(2):
            for y in range(4):
                self.box(ww, hh, y * ww, x * hh, ctx)
                self.k += 1
        print(ctx.get_font_matrix())

    def draw_page (self, operation, context, page_number):
        end = self.layout.get_line_count()
        cr = context.get_cairo_context()
        cr.set_source_rgb(0, 0, 0)
        i = 0
        start = 0
        start_pos = 0
        iter = self.layout.get_iter()
        while 1:
            if i >= start:
                line = iter.get_line()
                print(line)
                _, logical_rect = iter.get_line_extents()
                # x_bearing, y_bearing, lwidth, lheight = logical_rect
                baseline = iter.get_baseline()
                if i == start:
                    start_pos = 12000 / 1024.0  # 1024.0 is float(pango.SCALE)
                cr.move_to(0 / 1024.0, baseline / 1024.0 - start_pos)
                PangoCairo.show_layout_line(cr, line)
            i += 1
            if not (i < end and iter.next_line()):
                break



win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

别忘了将动作更改为Gtk.PrintOperationAction.PRINT进行真实打印.

Don't forget to change action to Gtk.PrintOperationAction.PRINT for real printing.

这篇关于在gtk3/python中创建打印作业的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆