Home » Tutorials » How to Create a Simple PDF File Viewer in Python

How to Create a Simple PDF File Viewer in Python

Today, we’re diving into a cool project where we’ll build our own PDF viewer using Python. Imagine having a little app on your computer that lets you open and read PDF documents, just like Adobe Reader, but you made it yourself!

In today’s article, we are going to create a PDF viewer in Python using the tkinter and PyMuPDF libraries, that will allow us to open a PDF file, display its content, and scroll through it using a scrollbar.

Learn also: How to Extract Tables from PDF in Python

Let’s get started!

Table of Contents

Necessary Libraries

For the code to function properly, make sure to install these libraries via your terminal or command prompt:

$ pip install PyMuPDF

The PyMuPDF library allows us to work with PDF files in our Python program.

$ pip install tk

The tkinter library allows the creation of a graphical user interface (GUI).

Imports

import fitz # PyMuPDF
from tkinter import *
from tkinter import filedialog

We start by importing the PyMuPDF library, a Python module for working with PDF files. Additionally, we import all classes and functions from the tkinter library, along with the filedialog module from tkinter, which is used for opening and saving files via a file dialog.

PDF File Viewer Functions

def open_pdf():
    file_path = filedialog.askopenfilename(initialdir="/",    title="Select a PDF file",
filetypes=(("PDF Files", "*.pdf"), ("All Files", "*.*")))

Next, we create a function designed to handle the opening and selection of a PDF file by launching a file dialog. This dialog allows the user to select a file to open, with the initial directory set to the root directory (‘/’).

The file dialog is named and presented to the user with a prompt, specifying the file types that can be selected. In this case, it permits the selection of PDF files with the extension ‘.pdf’ and files of any type with ‘.’. Essentially, this function enables the choice of any file from the directory.

Loading and Displaying the PDF

if file_path:
        pdf_viewer = fitz.open(file_path)
        page = pdf_viewer.load_page(0) # Load the first page

        img = page.get_pixmap()
        img.save("temp.png") # Convert the page to a temporary image file

This part of the code checks if the file_path variable, obtained from filedialog in the previous part of the code, contains a valid file path. If a file is selected (in other words, file_path is not an empty string), the code proceeds with further processing. It then opens the PDF file specified by file_path using the PyMuPDF (fitz) library, creating a pdf_viewer object. This object allows interaction with the contents of the PDF file. Subsequently, it loads the first page of the PDF document, obtaining a reference to the first page and storing it in the page variable.

The parameter 0 represents the page number (PDF pages are zero-indexed, so 0 refers to the first page) after that, it extracts the content of the loaded page as an image (pixmap). The content of the page is essentially converted into an image, which you can further manipulate or save.

Lastly, the last line of the code saves the extracted page as a temporary image file named temp.png. It effectively converts the first page of the PDF into a PNG image file. You can specify a different filename or format if needed. In simple terms, this function takes the first page of the PDF and saves it as a picture that you can view or use later after checking if you have selected a PDF file using filedialog.

Creating a Label For Displaying a PDF

        img_data = PhotoImage(file="temp.png")
        img_label = Label(canvas, image=img_data)
        img_label.image = img_data # Keep a reference

Now we create this code that displays the image “temp.png” within the specified canvas in your GUI. This is a common way to display images in tkinter-based applications. You can further position and customize the Label and canvas as needed within your GUI layout.

Handling Closing the Application

 # Delete the temporary image file when a new PDF is opened
        root.protocol("WM_DELETE_WINDOW",
                      lambda: [img_data.blank(), img_data, img_label, pdf_viewer.close(), root.destroy()])

Then, we set up a protocol for the application’s main window. This protocol specifies what should happen when the user tries to close the window. It’s configured to :

  • Clear image data.
  • Close the PDF viewer.
  • Destroy (close) the main application window.

Creating a Canvas and Scrollbar and Configuring the Scrollbars

# Add a canvas for scrolling and center it
        canvas.create_window((0, 0), window=img_label, anchor="center")
        canvas.config(scrollregion=canvas.bbox("all"))

Here we created a canvas, which is a scrollable area, within the main window. This canvas is used to display the PDF page then we also create a scrollbar for the canvas to allow scrolling.

Create the Main Window

# Create the main tkinter window
root = Tk()
root.title("Simple PDF Viewer - The Pycodes")
root.geometry("620x600")

After that, we create the main application window using tkinter and set its title and size.

Create the Open PDF Button

# Create an "Open PDF" button
open_button = Button(root, text="Open PDF", command=open_pdf, width=20, font="Arial 16", bd=4, relief=RAISED)
open_button.pack(pady=10)

Following that, we create a button labeled “Open PDF” that, when clicked, will execute the open_pdf() function. We set some properties for the button, like its size, font, and appearance.

Create a Canvas and Scrollbar For Scrolling

canvas = Canvas(root)
canvas.pack(fill=BOTH, expand=True)

scrollbar = Scrollbar(canvas, command=canvas.yview)
scrollbar.pack(side=RIGHT, fill=Y)

canvas.config(yscrollcommand=scrollbar.set)

Here, we configured the canvas to work with the scrollbar for vertical scrolling.

Starting the tkinter Main Loop

# Start the tkinter main loop
root.mainloop()

Finally, we start the main loop of the GUI application by calling root.mainloop(). This loop keeps the program running and responsive to user interactions.

Example

Full Code

import fitz # PyMuPDF
from tkinter import *
from tkinter import filedialog


def open_pdf():
    file_path = filedialog.askopenfilename(initialdir="/",    title="Select a PDF file",
filetypes=(("PDF Files", "*.pdf"), ("All Files", "*.*")))


    if file_path:
        pdf_viewer = fitz.open(file_path)
        page = pdf_viewer.load_page(0) # Load the first page


        img = page.get_pixmap()
        img.save("temp.png") # Convert the page to a temporary image file


        img_data = PhotoImage(file="temp.png")
        img_label = Label(canvas, image=img_data)
        img_label.image = img_data # Keep a reference


        # Delete the temporary image file when a new PDF is opened
        root.protocol("WM_DELETE_WINDOW",
                      lambda: [img_data.blank(), img_data, img_label, pdf_viewer.close(), root.destroy()])


        # Add a canvas for scrolling and center it
        canvas.create_window((0, 0), window=img_label, anchor="center")
        canvas.config(scrollregion=canvas.bbox("all"))


# Create the main tkinter window
root = Tk()
root.title("Simple PDF Viewer - The Pycodes")
root.geometry("620x600")


# Create an "Open PDF" button
open_button = Button(root, text="Open PDF", command=open_pdf, width=20, font="Arial 16", bd=4, relief=RAISED)
open_button.pack(pady=10)


# Create a canvas and scrollbar for scrolling
canvas = Canvas(root)
canvas.pack(fill=BOTH, expand=True)


scrollbar = Scrollbar(canvas, command=canvas.yview)
scrollbar.pack(side=RIGHT, fill=Y)


canvas.config(yscrollcommand=scrollbar.set)


# Start the tkinter main loop
root.mainloop()

Happy Coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top