How to create a PDF viewer using Python
In this tutorial we will learn how to create PDF viewer using python, this is a GUI toolkit which uses python Tkinter module, Pdf2img module, and Python Imaging Library (PIL).
As the increasing popularity and compatibility of PDFs in almost each and every document format, whether it is Invoices, Reports or other official documents, we need an onboard PDF viewer or renderer to seek out the information repeatedly.
- Tkinter – It is the most preferred GUI toolkit available in python, which posses the faster and easiest way of producing GUI software.
- pdf2img – It is an easy to use command line module that provides users with a batch conversion of PDF into Images.
- PIL/Pillow – It is a free library in python which supports opening, manipulating different image file formats.
Creating a PDF Viewer using Python
Before getting into the code you need to install the above-mentioned libraries.
Installation:
$ sudo apt-get install python3-tk $ pip3 install pdf2image $ pip3 install pillow
After installing the above modules and required dependencies you can get into actual code.
Source Code: Create a PDF viewer GUI in Python
# Importing required modules from tkinter import * from PIL import Image,ImageTk from pdf2image import convert_from_path # Creating Tk container root = Tk() # Creating the frame for PDF Viewer pdf_frame = Frame(root).pack(fill=BOTH,expand=1) # Adding Scrollbar to the PDF frame scrol_y = Scrollbar(pdf_frame,orient=VERTICAL) # Adding text widget for inserting images pdf = Text(pdf_frame,yscrollcommand=scrol_y.set,bg="grey") # Setting the scrollbar to the right side scrol_y.pack(side=RIGHT,fill=Y) scrol_y.config(command=pdf.yview) # Finally packing the text widget pdf.pack(fill=BOTH,expand=1) # Here the PDF is converted to list of images pages = convert_from_path('mypdf.pdf',size=(800,900)) # Empty list for storing images photos = [] # Storing the converted images into list for i in range(len(pages)): photos.append(ImageTk.PhotoImage(pages[i])) # Adding all the images to the text widget for photo in photos: pdf.image_create(END,image=photo) # For Seperating the pages pdf.insert(END,'\n\n') # Ending of mainloop mainloop()
Here you must be thinking why I have used two for loops one adding images to list and the second one for adding images to the text widget, I had actually used one loop but then it was only showing the last page in the PDF, this might be happening, because I was using a single variable to hold the image and store into text widget. The conclusion that I could arrive at is that every image needs the separate permanent storage until the PDF is rendered.
Output:
By looking at this task code it seems to be simple, but it took me around 8 hours to arrive at this solution because in this I had tried every possible solution I could have found and lastly I had found it, this was really a challenging and interesting task.
So in this way you can create a simple PDF viewer, I hope this article might be fruitful to you, thank you ‘Keep Learning Keep Coding’.
Also, learn:
Code doesnt work I get the following error :
PDFInfoNotInstalledError: Unable to get page count. Is poppler installed and in PATH?
Great work Man!! By the way I’m also working similar to this one but I wanna add dictionary to it which makes easier for reader to get info which he doesn’t know(Like we do Google search).
My design is to embed a block at left which helps for searching.
Your feedback for my idea would be helpful for me to improvize my work
Hey sir, ‘sudo’ in the very first line of the tutorial is not working for me, what should I do?
Assuming you are on linux, have you tried su?
eg.
su
(then type in root password)
then you should be in root, and then try to install
apt-get install python3-tk
more information on the error could be useful
Thank you for your solution. It works very well.
But i can`t it extend, to display more pdf-files
I started the loop at:
” before “frame=…” and
before “Here the PDF is converted…”
in both cases the pdf-document starts with grey-area at the beginning.
Have you any solution for me?
thx
=> ipt=input(nextPDF)
=> continue