How to add PDF in Tkinter GUI Python?

This article will teach us how to display PDF files in the Tkinter GUI. We will be using the PyMuPDF library to read the PDF files and convert them into images which will then be displayed using Tkinter.

For our task, we will do the following steps ?

  • Read the PDF file

  • Define a transformation matrix to apply on the pages of PDF to get their images

  • Count the total number of pages for error checking

  • Define the screen (the canvas) for our GUI

  • Define a helper function for converting a PDF page to a PIL image

  • Define a function to show the image of a page in our GUI

  • Add buttons, labels, scrollbars etc and configure them

Installing Required Libraries

To get started, let's first install the PyMuPDF package by running the following command in our terminal ?

python -m pip install --upgrade pip
python -m pip install --upgrade pymupdf

Importing Libraries

Now we need to import the libraries we will be working with ?

import fitz
from tkinter import *
from PIL import Image, ImageTk

Here fitz is a utility library that comes along with the PyMuPDF library and is used to get PDF pages as images.

Opening the PDF File

We first open the PDF file we want to display in our GUI by using the fitz.open() function. This returns a document object which can be used to access pages ?

# open pdf file
file_name = "sample.pdf"
doc = fitz.open(file_name)

Setting Up Transformation Matrix

Now we need to specify how we would like to view the pages. By defining the below matrix function we tell fitz to keep a 1x zoom ?

# transformation matrix we can apply on pages
zoom = 1
mat = fitz.Matrix(zoom, zoom)

Counting Pages

Let us also count the number of pages ?

# count number of pages
num_pages = 0
for p in doc:
    num_pages += 1

Creating the GUI Components

Now we will define a screen, add a scroll bar and a canvas to our code ?

# initialize and set screen size
root = Tk()
root.geometry('750x700')

# add scroll bar
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)

# add canvas
canvas = Canvas(root, yscrollcommand=scrollbar.set)
canvas.pack(side=LEFT, fill=BOTH, expand=1)

Here our screen is represented by the name "root" and is of dimensions 750x700. We have also added a scroll bar and specified it to be on the right side and fill the entire height. Similarly, we have added the canvas to the left side and fill the entire screen on both sides.

Adding Input Fields

In order to receive the page number the user wants to read, we need to take the page number as an input. We can do it as follows ?

# define entry point (field for taking inputs)
entry = Entry(root)

# add a label for the entry point
label = Label(root, text="Enter page number to display:")

The arguments 'root' tell us that the objects will be associated with the screen "root".

Helper Function for PDF to Image Conversion

Now we will define a helper function to get the image of the PDF file from a page number ?

def pdf_to_img(page_num):
    page = doc.load_page(page_num)
    pix = page.get_pixmap(matrix=mat)
    return Image.frombytes("RGB", [pix.width, pix.height], pix.samples)

Here we first load the page using doc.load_page and passing the page number as an argument. Then we convert the PDF page to get pixel representation of that page in the second line. Finally, we convert the pixel representation into the PIL Image format.

Function to Display Images

Now we define a function show_image to display the image in our Tkinter GUI ?

def show_image():
    try:
        page_num = int(entry.get()) - 1
        assert page_num >= 0 and page_num < num_pages
        im = pdf_to_img(page_num)
        img_tk = ImageTk.PhotoImage(im)
        frame = Frame(canvas)
        panel = Label(frame, image=img_tk)
        panel.pack(side="bottom", fill="both", expand="yes")
        frame.image = img_tk
        canvas.create_window(0, 0, anchor='nw', window=frame)
        frame.update_idletasks()
        canvas.config(scrollregion=canvas.bbox("all"))
    except:
        pass

Here first we read the page number from the entry point we defined earlier and convert it to an integer. If it's not a valid integer, an exception occurs and the exception block handles it. We then check if the page number is between 0 or the number of pages since that is the only valid range of pages we can display. Then using our previously defined helper function, we get a PIL Image of the user specified page. We then set the frame, panel and the canvas to appropriately display this image.

Adding Button and Configuring Layout

Next we add a button to display the page. We pass the function show_image as a command. Hence whenever the button is pressed the show_image function will be called ?

# add button to display pages
button = Button(root, text="Show Page", command=show_image)

Now we set the visual locations of the various components we defined previously ?

# set visual locations
label.pack(side=TOP, fill=None)
entry.pack(side=TOP, fill=BOTH)
button.pack(side=TOP, fill=None)

Final Configuration

We also set the initial page as the first page of the PDF as follows ?

entry.insert(0, '1')
show_image()

We configure the scroll bar and start the main loop ?

scrollbar.config(command=canvas.yview)
root.mainloop()

Finally we close the PDF so it doesn't get corrupted ?

doc.close()

Complete Example

Here's the complete working code ?

import fitz
from tkinter import *
from PIL import Image, ImageTk

# open pdf file
file_name = "sample.pdf"
doc = fitz.open(file_name)

# transformation matrix
zoom = 1
mat = fitz.Matrix(zoom, zoom)

# count number of pages
num_pages = len(doc)

# initialize GUI
root = Tk()
root.geometry('750x700')
root.title('PDF Viewer')

# add scroll bar
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT, fill=Y)

# add canvas
canvas = Canvas(root, yscrollcommand=scrollbar.set)
canvas.pack(side=LEFT, fill=BOTH, expand=1)

# input components
label = Label(root, text="Enter page number to display:")
entry = Entry(root)

def pdf_to_img(page_num):
    page = doc.load_page(page_num)
    pix = page.get_pixmap(matrix=mat)
    return Image.frombytes("RGB", [pix.width, pix.height], pix.samples)

def show_image():
    try:
        page_num = int(entry.get()) - 1
        assert 0 <= page_num < num_pages
        im = pdf_to_img(page_num)
        img_tk = ImageTk.PhotoImage(im)
        frame = Frame(canvas)
        panel = Label(frame, image=img_tk)
        panel.pack(side="bottom", fill="both", expand="yes")
        frame.image = img_tk
        canvas.create_window(0, 0, anchor='nw', window=frame)
        frame.update_idletasks()
        canvas.config(scrollregion=canvas.bbox("all"))
    except:
        pass

# add button
button = Button(root, text="Show Page", command=show_image)

# layout configuration
label.pack(side=TOP, fill=None)
entry.pack(side=TOP, fill=BOTH)
button.pack(side=TOP, fill=None)

# initialize with first page
entry.insert(0, '1')
show_image()

# configure scrollbar and start
scrollbar.config(command=canvas.yview)
root.mainloop()

# cleanup
doc.close()

Output

After running the program we see the following output ?

PDF Viewer GUI showing a PDF page with navigation controls

Conclusion

This article taught us how to use the PyMuPDF library along with Pillow and Tkinter to display PDF files in a GUI. We learned how to convert PDF pages to images, create interactive navigation, and handle user input for page selection.

Updated on: 2026-03-27T00:36:04+05:30

6K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements