1+ # importing everything from tkinter
2+ from tkinter import *
3+ # importing ttk for styling widgets from tkinter
4+ from tkinter import ttk
5+ # importing filedialog from tkinter
6+ from tkinter import filedialog as fd
7+ # importing os module
8+ import os
9+ # importing the PDFMiner class from the miner file
10+ from miner import PDFMiner
11+
12+
13+
14+ # creating a class called PDFViewer
15+ class PDFViewer :
16+ # initializing the __init__ / special method
17+ def __init__ (self , master ):
18+ # path for the pdf doc
19+ self .path = None
20+ # state of the pdf doc, open or closed
21+ self .fileisopen = None
22+ # author of the pdf doc
23+ self .author = None
24+ # name for the pdf doc
25+ self .name = None
26+ # the current page for the pdf
27+ self .current_page = 0
28+ # total number of pages for the pdf doc
29+ self .numPages = None
30+ # creating the window
31+ self .master = master
32+ # gives title to the main window
33+ self .master .title ('PDF Viewer' )
34+ # gives dimensions to main window
35+ self .master .geometry ('580x520+440+180' )
36+ # this disables the minimize/maximize button on the main window
37+ self .master .resizable (width = 0 , height = 0 )
38+ # loads the icon and adds it to the main window
39+ self .master .iconbitmap (self .master , 'pdf_file_icon.ico' )
40+ # creating the menu
41+ self .menu = Menu (self .master )
42+ # adding it to the main window
43+ self .master .config (menu = self .menu )
44+ # creating a sub menu
45+ self .filemenu = Menu (self .menu )
46+ # giving the sub menu a label
47+ self .menu .add_cascade (label = "File" , menu = self .filemenu )
48+ # adding a two buttons to the sub menus
49+ self .filemenu .add_command (label = "Open File" , command = self .open_file )
50+ self .filemenu .add_command (label = "Exit" , command = self .master .destroy )
51+ # creating the top frame
52+ self .top_frame = ttk .Frame (self .master , width = 580 , height = 460 )
53+ # placing the frame using inside main window using grid()
54+ self .top_frame .grid (row = 0 , column = 0 )
55+ # the frame will not propagate
56+ self .top_frame .grid_propagate (False )
57+ # creating the bottom frame
58+ self .bottom_frame = ttk .Frame (self .master , width = 580 , height = 50 )
59+ # placing the frame using inside main window using grid()
60+ self .bottom_frame .grid (row = 1 , column = 0 )
61+ # the frame will not propagate
62+ self .bottom_frame .grid_propagate (False )
63+ # creating a vertical scrollbar
64+ self .scrolly = Scrollbar (self .top_frame , orient = VERTICAL )
65+ # adding the scrollbar
66+ self .scrolly .grid (row = 0 , column = 1 , sticky = (N ,S ))
67+ # creating a horizontal scrollbar
68+ self .scrollx = Scrollbar (self .top_frame , orient = HORIZONTAL )
69+ # adding the scrollbar
70+ self .scrollx .grid (row = 1 , column = 0 , sticky = (W , E ))
71+ # creating the canvas for display the PDF pages
72+ self .output = Canvas (self .top_frame , bg = '#ECE8F3' , width = 560 , height = 435 )
73+ # inserting both vertical and horizontal scrollbars to the canvas
74+ self .output .configure (yscrollcommand = self .scrolly .set , xscrollcommand = self .scrollx .set )
75+ # adding the canvas
76+ self .output .grid (row = 0 , column = 0 )
77+ # configuring the horizontal scrollbar to the canvas
78+ self .scrolly .configure (command = self .output .yview )
79+ # configuring the vertical scrollbar to the canvas
80+ self .scrollx .configure (command = self .output .xview )
81+ # loading the button icons
82+ self .uparrow_icon = PhotoImage (file = 'uparrow.png' )
83+ self .downarrow_icon = PhotoImage (file = 'downarrow.png' )
84+ # resizing the icons to fit on buttons
85+ self .uparrow = self .uparrow_icon .subsample (3 , 3 )
86+ self .downarrow = self .downarrow_icon .subsample (3 , 3 )
87+ # creating an up button with an icon
88+ self .upbutton = ttk .Button (self .bottom_frame , image = self .uparrow , command = self .previous_page )
89+ # adding the button
90+ self .upbutton .grid (row = 0 , column = 1 , padx = (270 , 5 ), pady = 8 )
91+ # creating a down button with an icon
92+ self .downbutton = ttk .Button (self .bottom_frame , image = self .downarrow , command = self .next_page )
93+ # adding the button
94+ self .downbutton .grid (row = 0 , column = 3 , pady = 8 )
95+ # label for displaying page numbers
96+ self .page_label = ttk .Label (self .bottom_frame , text = 'page' )
97+ # adding the label
98+ self .page_label .grid (row = 0 , column = 4 , padx = 5 )
99+
100+ # function for opening pdf files
101+ def open_file (self ):
102+ # open the file dialog
103+ filepath = fd .askopenfilename (title = 'Select a PDF file' , initialdir = os .getcwd (), filetypes = (('PDF' , '*.pdf' ), ))
104+ # checking if the file exists
105+ if filepath :
106+ # declaring the path
107+ self .path = filepath
108+ # extracting the pdf file from the path
109+ filename = os .path .basename (self .path )
110+ # passing the path to PDFMiner
111+ self .miner = PDFMiner (self .path )
112+ # getting data and numPages
113+ data , numPages = self .miner .get_metadata ()
114+ # setting the current page to 0
115+ self .current_page = 0
116+ # checking if numPages exists
117+ if numPages :
118+ # getting the title
119+ self .name = data .get ('title' , filename [:- 4 ])
120+ # getting the author
121+ self .author = data .get ('author' , None )
122+ self .numPages = numPages
123+ # setting fileopen to True
124+ self .fileisopen = True
125+ # calling the display_page() function
126+ self .display_page ()
127+ # replacing the window title with the PDF document name
128+ self .master .title (self .name )
129+
130+ # the function to display the page
131+ def display_page (self ):
132+ # checking if numPages is less than current_page and if current_page is less than
133+ # or equal to 0
134+ if 0 <= self .current_page < self .numPages :
135+ # getting the page using get_page() function from miner
136+ self .img_file = self .miner .get_page (self .current_page )
137+ # inserting the page image inside the Canvas
138+ self .output .create_image (0 , 0 , anchor = 'nw' , image = self .img_file )
139+ # the variable to be stringified
140+ self .stringified_current_page = self .current_page + 1
141+ # updating the page label with number of pages
142+ self .page_label ['text' ] = str (self .stringified_current_page ) + ' of ' + str (self .numPages )
143+ # creating a region for inserting the page inside the Canvas
144+ region = self .output .bbox (ALL )
145+ # making the region to be scrollable
146+ self .output .configure (scrollregion = region )
147+
148+ # function for displaying next page
149+ def next_page (self ):
150+ # checking if file is open
151+ if self .fileisopen :
152+ # checking if current_page is less than or equal to numPages-1
153+ if self .current_page <= self .numPages - 1 :
154+ # updating the page with value 1
155+ self .current_page += 1
156+ # displaying the new page
157+ self .display_page ()
158+
159+ # function for displaying the previous page
160+ def previous_page (self ):
161+ # checking if fileisopen
162+ if self .fileisopen :
163+ # checking if current_page is greater than 0
164+ if self .current_page > 0 :
165+ # decrementing the current_page by 1
166+ self .current_page -= 1
167+ # displaying the previous page
168+ self .display_page ()
169+
170+
171+
172+ # creating the root winding using Tk() class
173+ root = Tk ()
174+ # instantiating/creating object app for class PDFViewer
175+ app = PDFViewer (root )
176+ # calling the mainloop to run the app infinitely until user closes it
177+ root .mainloop ()
0 commit comments