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