Skip to content
Advertisement

How to make zoom in PDF viewer with Python tkinter and tkPDFViewer?

I have made a very simple PDF viewer for all PDF files contained in the folder where the executable is placed. Then, I am interested in adding some basic utilities to a buttons panel, such as with zoom + and zoom – button to increase the view of PDF file and allowing to improve the reading of the selected PDF file.

Here’s my code [ https://github.com/marco-rosso-m/GUI_simplePDFviewer ]:

import tkinter as tk
from tkPDFViewer import tkPDFViewer as pdf 
from os import path
from glob import glob
import sys
import os

# set global variable v2
global v2
v2 = None

def list_file_ext_current_folder(dr, ext, ig_case=False):
    if ig_case: # case sensitive
        ext =  "".join(["[{}]".format(ch + ch.swapcase()) for ch in ext])
    return glob(path.join(dr, "*." + ext))

def on_select(evt):
    global v2
    # Note here that Tkinter passes an event object to onselect()
    w = evt.widget
    index = int(w.curselection()[0])
    value = w.get(index)
    # print('You selected item %d: "%s"' % (index, value))
    if v2: # if old instance exists, destroy it first
        v2.destroy()
    # creating object of ShowPdf from tkPDFViewer. 
    v1 = pdf.ShowPdf() 
    # clear the image list # this corrects the bug inside tkPDFViewer module
    v1.img_object_li.clear()
    # Adding pdf location and width and height. 
    v2=v1.pdf_view(frame2,pdf_location = f"{value}",  width = 80, height = 100)
    # Placing Pdf inside gui
    v2.pack()

def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    base_path = getattr(
        sys,
        '_MEIPASS',
        os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, relative_path)

# tkinter root widnow
root = tk.Tk() 
root.geometry('800x600')
root.minsize(800, 600)
root.title('Simple PDF Viewer inside the current Folder')
root.wm_iconbitmap(resource_path('logo.ico'))

# tkinter frame for listbox
frame1=tk.Frame(root,width=40)
# tkinter frame for pdf viewer
frame2=tk.Frame(root)

frame1.pack(side="left",fill="both",expand=True)
frame2.pack(side="right",fill="both",expand=True)

# get list of pdf files inside the current folder
paths=list_file_ext_current_folder(".","pdf",True)

# vertical scrollbar
yscrollbar = tk.Scrollbar(frame1)
yscrollbar.pack(side = tk.RIGHT, fill = tk.Y)

# generate listbox
lb = tk.Listbox(frame1, selectmode = "SINGLE", name='lb', yscrollcommand = yscrollbar.set)

lb.pack(padx = 10, pady = 10, expand = tk.YES, fill = "both")

if paths: # if paths list is not empty
    for each_item in range(len(paths)):
        lb.insert(tk.END, paths[each_item])
        lb.itemconfig(each_item)
    lb.bind('<<ListboxSelect>>', on_select)
    lb.select_set(0) # This only sets focus on the first item.
    lb.event_generate("<<ListboxSelect>>") # This creates the even clicked
else:
    lb.insert(tk.END, "No PDF are present in this forlder!")

# Attach listbox to vertical scrollbar
yscrollbar.config(command = lb.yview)


root.mainloop()

Moreover, at present, the above-implemented PDF viewer seems to not be responsive with respect to the window dimension, is any way to make it responsive?

Advertisement

Answer

In order to manage the zooming with tkPDFViewer module, I have downloaded the source code here, then I modified the pdf_view function adding a zooming parameter that I called zoomDPI, setting its default value of 72dpi:

def pdf_view(self,master,width=1200,height=600,pdf_location="",bar=True,load="after",zoomDPI=72):

Thereafter, the new input parameter is used to modify the method getPixmap() inside the function add_img(). Inside this function I modified the following line inserting the new input parameter which govern the resolution of the image and thus the zooming level:

pix = page.getPixmap(dpi=zoomDPI)

Finally, inside the main code, when calling the pdf_view method I can adjust the image level by giving in input a dpi value higher of 72 in order to increase the zoom level (zooming in), or a lower value in order to decrease the zoom level (zooming out).

        if v2: # if old instance exists, destroy it first
            v2.destroy()
        # creating object of ShowPdf from tkPDFViewer. 
        v1 = pdf.ShowPdf() 
        # clear the image list # this corrects the bug inside tkPDFViewer module
        v1.img_object_li.clear()
        # Adding pdf location and width and height. 
        v2=v1.pdf_view(frame2,pdf_location = f"{value}",zoomDPI=zoomDPI) # default value for zoomDPI=72. Set higher dpi for zoom in, lower dpi for zoom out
        # Placing Pdf inside gui
        v2.pack()

The new complete code can be found here.

Advertisement