from tkinter import * from tkinter import filedialog from zipfile import ZipFile as zf from PIL import Image, ImageTk import io, os, pickle class MangaReader: def __init__(self, master): self.master = master self.page = 0 self.total = 0 self.file = 'None' self.img = '' self.dir = 'None' self.nextKey = '' self.backKey = '' self.quitKey = 'q' self.openKey = 'o' master.title("Manga Reader") #Load settings try: settingLoad = pickle.load(open('manga.p', 'rb')) self.dir = settingLoad['directory'] self.nextKey = settingLoad['nextKey'] self.backKey = settingLoad['backKey'] self.quitKey = settingLoad['quitKey'] self.openKey = settingLoad['openKey'] except: pass # tk window size and allow resize master.geometry("700x900") master.resizable(width=True, height=True) # Menu Bar self.menu = Menu(master) item = Menu(self.menu) item.add_command(label="Open", command=self.open_menu) item.add_separator() item.add_command(label="Exit", command=self.shutdown) self.menu.add_cascade(label="File", menu=item) root.config(menu=self.menu) self.buttonFrame = Frame(master) # forward/back buttons self.nextPg = Button(self.buttonFrame, text='>') self.nextPg.bind('', self.nextPage) self.nextPg.grid(row=1, column=2) self.buttonFrame.pack(side=BOTTOM) self.backPg = Button(self.buttonFrame, text='<') self.backPg.bind('', self.backPage) self.backPg.grid(row=1, column=0) # page counter self.pgcount = Label(self.buttonFrame, text= str(self.page) + " of " + str(self.total)) self.pgcount.grid(row=1, column=1, columnspan=2, pady=(20,20)) self.mangaTitle = Label(self.buttonFrame, text=os.path.basename(self.file)) self.mangaTitle.grid(row=0, column=1) # display image self.panel = Label(self.master, image=self.img) self.panel.pack() self.panel.bind('', self.redraw) # key bindings self.master.bind(self.nextKey, self.nextPage) self.master.bind(self.backKey, self.backPage) self.master.bind(self.quitKey, self.shutdown) self.master.bind(self.openKey, self.open_menu) #watch the 'x' button for window close master.protocol('WM_DELETE_WINDOW', self.shutdown) def open_menu(self, *event): # file dialog. reset page counts, call display Maanga passing in starting values if self.dir == 'None': mangaFile = filedialog.askopenfilename(initialdir = "/home/dan/Desktop/") else: mangaFile = filedialog.askopenfilename(initialdir = self.dir) if mangaFile != '': self.file = mangaFile else : self.panel.focus_force() if self.file != '': self.page = 0 self.total = 0 self.mangaTitle.configure(text=os.path.basename(self.file)) self.dir = os.path.dirname(self.file) self.displayManga(self.file, 0) def displayManga(self, file, pg): #basewidth = 500 hsize = self.master.winfo_height() - self.buttonFrame.winfo_height() - self.menu.winfo_height() wsize = 500 with zf(file, 'r') as zip: # grab all the manga pages from the cbz file and sort them to put them in the correct order fl = zip.namelist() fl.sort() self.total = len(fl)-1 # grab the current page out of the array. treat it as byte data since it's still zipped. data = zip.read(fl[pg]) im = Image.open(io.BytesIO(data)) # I found the below code to maintain image ratios at https://stackoverflow.com/questions/273946/how-do-i-resize-an-image-using-pil-and-maintain-its-aspect-ratio # wpercent = (basewidth / float(im.size[0])) # hsize = int((float(im.size[1]) * float(wpercent))) #Modified above code to maintain height and scale width hpercent = (hsize / float(im.size[1])) widthsize = int((float(im.size[0] * float(hpercent)))) if widthsize > self.master.winfo_width(): widthsize = self.master.winfo_width() #widthsize = im.size[0] wpercent = (widthsize / float(im.size[0])) hsize = int((float(im.size[1]) * float(wpercent))) # self.master.config(width=widthsize) im = im.resize((widthsize, hsize), Image.ANTIALIAS) #convert to tkImage and update the on screen image. self.img = ImageTk.PhotoImage(im) self.panel.config(image=self.img) #finally update the current page count self.pgcount.configure(text=str(pg+1) + " of " + str(self.total)) self.panel.focus_force() def nextPage(self, event): self.page = self.page + 1 if self.page < self.total: self.displayManga(self.file, self.page) else: #reset self.page and open file selection self.page = self.page - 1 self.open_menu() def backPage(self, event): self.page = self.page - 1 if self.page >= 0: self.displayManga(self.file, self.page) else: #reset self.page and doNothing self.page = self.page + 1 def redraw(self, event): if self.file != 'None': self.displayManga(self.file, self.page) def shutdown(self,*event): # Collect settings and pickle them. Then quit. settingSave = {'directory': os.path.dirname(self.file), 'nextKey': self.nextKey, 'backKey': self.backKey, 'quitKey': self.quitKey, 'openKey':self.openKey} pickle.dump(settingSave, open('manga.p', 'wb')) quit() #initalize tk root=Tk() app = MangaReader(root) root.mainloop()