textview のバッファを pdf 形式で保存したい。単純なテキストであれば、reportlab を使用して実行できます。しかし、タグ付きのテキストから画像まで、すべてを保存したい場合はどうすればよいでしょうか?
from gi.repository import Gtk, GdkPixbuf
import pango
from reportlab.pdfgen import canvas
class gui():
def __init__(self):
self.window = Gtk.Window()
self.window.connect('delete-event', Gtk.main_quit)
self.box = Gtk.Box()
self.window.add(self.box)
self.textview = Gtk.TextView()
self.textbuffer = self.textview.get_buffer()
self.tag_bold = self.textbuffer.create_tag("bold",
weight=pango.WEIGHT_BOLD)
self.tag_italic = self.textbuffer.create_tag("italic",
style=pango.STYLE_ITALIC)
pix = GdkPixbuf.Pixbuf.new_from_file_at_size('baby.jpg', 50, 50)
tag = [self.tag_bold,
self.tag_italic]
self.textbuffer.insert_pixbuf(self.textbuffer.get_end_iter(), pix)
for i in range(20):
self.textbuffer.insert_with_tags(self.textbuffer.get_end_iter(),
'line%d\n' % (i+1),
tag[i % 2])
self.box.pack_start(self.textview, True, True, 0)
self.button = Gtk.Button(label='Start')
self.button.connect('clicked', self.on_button_clicked)
self.box.pack_start(self.button, True, True, 0)
self.window.show_all()
Gtk.main()
def on_button_clicked(self, widget):
canv = canvas.Canvas('tes.pdf')
for i in range(self.textbuffer.get_line_count()):
a = self.textbuffer.get_iter_at_line(i)
b = self.textbuffer.get_iter_at_line(i+1).get_offset()
c = self.textbuffer.get_iter_at_offset(b - 1)
t = self.textbuffer.get_text(a, b, True)
line = 750 - (15 * l)
canv.drawString(40, line, t)
canv.save()
if __name__ == '__main__':
gui = gui()
編集: drahnr は、代わりに cairo を使用することを提案します。reportlab 座標は左下から開始し、cairo 座標は左上から開始するので、より良いアイデアだと思います。以下は、カイロを使用した私のコードです。
from gi.repository import Gtk, GdkPixbuf, Gdk
import pango
import cairo
class gui():
def __init__(self):
self.window = Gtk.Window()
self.window.connect('delete-event', Gtk.main_quit)
self.textview = Gtk.TextView()
self.window.add(self.textview)
self.initText()
self.createPDF()
self.window.show_all()
Gtk.main()
def initText(self):
self.tag_bold = self.textview.get_buffer().create_tag("bold", weight=pango.WEIGHT_BOLD)
self.tag_italic = self.textview.get_buffer().create_tag("italic", style=pango.STYLE_ITALIC)
pix = GdkPixbuf.Pixbuf.new_from_file_at_size('baby.png', 50, 50)
tag = [self.tag_bold, self.tag_italic]
self.textview.get_buffer().insert_pixbuf(self.textview.get_buffer().get_end_iter(), pix)
self.textview.get_buffer().insert(self.textview.get_buffer().get_end_iter(), '\n')
for i in range(20):
self.textview.get_buffer().insert_with_tags(self.textview.get_buffer().get_end_iter(), 'line%d' % (i+1), tag[i % 2])
self.textview.get_buffer().insert(self.textview.get_buffer().get_end_iter(), '\n')
def createPDF(self):
line = 30
row = 5
pos = 0
ps = cairo.PDFSurface('tes.pdf', 600, 770)
cr = cairo.Context(ps)
while pos != self.textview.get_buffer().get_end_iter().get_offset():
if self.textview.get_buffer().get_iter_at_offset(pos).has_tag(self.tag_bold):
cr.select_font_face('Times', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
elif self.textview.get_buffer().get_iter_at_offset(pos).has_tag(self.tag_italic):
cr.select_font_face('Times', cairo.FONT_SLANT_ITALIC, cairo.FONT_WEIGHT_NORMAL)
else:
cr.select_font_face('Times', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
t = self.textview.get_buffer().get_slice(self.textview.get_buffer().get_iter_at_offset(pos), self.textview.get_buffer().get_iter_at_offset(pos+1), False)
if t == '\n':
line += 12
row = 5
elif t == unichr(0xFFFC):
pix = self.textview.get_buffer().get_iter_at_offset(pos).get_pixbuf()
Gdk.cairo_set_source_pixbuf(cr, pix, 8 * row, line)
line += pix.get_width()
cr.paint()
else:
cr.move_to(8 * row, line)
cr.show_text(t)
pos=pos+1
row += 1
if __name__ == '__main__':
gui()
文字通り、それはまだ同じです。すべてを描画するには、ハードコードする必要があります。と drahnr は、gtk_widget_draw を使用して cairo サーフェスにレンダリングすることを提案しています。