Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
View PDF in python Gtk3
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import gi
gi.require_version('EvinceView', '3.0')
gi.require_version('EvinceDocument', '3.0')
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk, Gdk
from gi.repository import EvinceDocument
from gi.repository import EvinceView
import os,sys
settings = None
if (len(sys.argv) < 2):
print (f"Usage: {sys.argv[0]} filename.pdf")
sys.exit(0)
else:
docFile = os.path.abspath(sys.argv[1])
class PDFViewer:
def __init__(self):
self.window = Gtk.Window()
self.window.set_title("PDF Viewer")
self.window.set_icon_name("application-pdf")
self.window.set_default_size(800,800)
self.window.connect('destroy', Gtk.main_quit)
self.window.connect('delete-event',
Gtk.main_quit)
self.window.connect("key-press-event",
self.keypress)
### headerbar
self.header = Gtk.HeaderBar()
self.header.set_title('PDF Viewer')
self.header.set_show_close_button(True)
self.window.set_titlebar(self.header)
### open button
self.btn_open = Gtk.Button.new_from_icon_name("document-open", 3)
self.btn_open.set_tooltip_text("Open File")
self.btn_open.set_hexpand(False)
self.btn_open.set_relief(2)
self.btn_open.connect("clicked", self.on_open_file)
self.header.add(self.btn_open)
### open button
self.btn_print = Gtk.Button.new_from_icon_name("document-print", 3)
self.btn_print.set_tooltip_text("Print File")
self.btn_print.set_hexpand(False)
self.btn_print.set_relief(2)
self.header.add(self.btn_print)
### about button
self.btn_help = Gtk.Button.new_from_icon_name("help-about", 3)
self.btn_help.connect("clicked", self.show_help)
self.btn_help.set_relief(2)
self.btn_help.set_tooltip_text("Info / Shortcuts")
self.header.add(self.btn_help)
### search field
self.search_entry = Gtk.SearchEntry(placeholder_text = "find ...",
tooltip_text = "press Return to find next")
self.search_entry.connect("activate", self.refresh_filter)
self.search_entry.connect("search-changed", self.find_text)
self.header.pack_end(self.search_entry)
scroll = Gtk.ScrolledWindow()
self.window.add(scroll)
EvinceDocument.init()
self.doc = EvinceDocument.Document.factory_get_document('file://' + docFile)
self.view = EvinceView.View()
self.model = EvinceView.DocumentModel()
self.model.set_document(self.doc)
self.view.set_model(self.model)
try:
self.evprint = EvinceView.PrintOperation.new(self.doc)
self.btn_print.connect("clicked", self.on_print_file)
except:
pass
scroll.add(self.view)
self.window.show_all()
self.window.move(0, 0)
self.header.set_subtitle(docFile.rpartition("/")[2])
self.fullscreen = False
def show_help(self, *args):
about_dialog = Gtk.AboutDialog()
about_dialog.set_default_size(500, 500)
about_dialog.set_destroy_with_parent(True)
pixbuf = Gtk.IconTheme.get_default().load_icon("application-pdf", 64, 0)
about_dialog.set_logo(pixbuf)
about_dialog.set_program_name("PDF Viewer")
about_dialog.set_version("1.0")
about_dialog.set_authors(["Axel Schneider"])
about_dialog.set_website("https://github.com/Axel-Erfurt")
about_dialog.set_website_label("Github")
about_dialog.set_copyright("© 2022 Axel Schneider")
comment = """Shortcuts:
Ctrl+O -> open File
Ctrl+P -> print File
Ctrl+Q -> Quit
F11 -> toggle Fullscreen
Ctrl+Wheel -> Zoom In/Out"""
about_dialog.set_comments(comment)
about_dialog.run()
about_dialog.destroy()
def on_print_file(self, *args):
global settings
if not settings:
self.evprint.run(self.window)
settings = self.evprint.get_print_settings()
else:
self.evprint = EvinceView.PrintOperation.new(self.doc)
self.evprint.run(self.window)
def on_open_file(self, *args):
dlg = Gtk.FileChooserDialog(title="Please choose a file", parent=None, action = 0)
dlg.add_buttons("Cancel", Gtk.ResponseType.CANCEL,
"Open", Gtk.ResponseType.OK)
docs = f"{os.path.expanduser('~')}/PDF"
dlg.set_current_folder(docs)
filter = Gtk.FileFilter()
filter.set_name("PDF Files")
filter.add_pattern("*.pdf")
dlg.add_filter(filter)
response = dlg.run()
if response == Gtk.ResponseType.OK:
docFile = dlg.get_filename()
self.doc = EvinceDocument.Document.factory_get_document(
'file://' + docFile)
self.model.set_document(self.doc)
dlg.destroy()
def clear_search(self, *args):
if self.search_entry.get_text() == "":
self.view.find_set_highlight_search(False)
else:
self.find_text()
def refresh_filter(self, *args):
if not self.search_entry.get_text() == "":
self.view.find_next()
def find_text(self, *args):
stext = self.search_entry.get_text()
if stext != "":
evj = EvinceView.JobFind.new(document=self.doc, start_page = 0, n_pages=self.doc.get_n_pages(), text = stext, case_sensitive=False)
self.view.find_set_highlight_search(True)
self.view.find_started(evj)
EvinceView.Job.scheduler_push_job(
evj, EvinceView.JobPriority.PRIORITY_NONE)
else:
self.view.find_set_highlight_search(False)
def keypress(self,widget,event):
keyname = Gdk.keyval_name(event.keyval)
ctrl = event.state & \
Gdk.ModifierType.CONTROL_MASK
if ctrl:
if keyname == 'r':
self.view.reload()
elif keyname == 'o':
self.on_open_file()
elif keyname == 'p':
self.on_print_file()
elif keyname == 'q':
Gtk.main_quit()
else:
if keyname == 'F11':
if self.fullscreen == False:
self.fullscreen = True
self.window.fullscreen()
else:
self.fullscreen=False
self.window.unfullscreen()
def main(self):
Gtk.main()
if __name__ == "__main__":
evinceViewer = PDFViewer()
evinceViewer.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment