0
我工作的一個簡單的應用程序來讀取和使用Python 3.4與Tkinter的一個zip文件內顯示的圖像文件序列,就像你可以使用閱讀.cbz漫畫書文件。理想情況下,我想綁定左右鍵分別顯示最後一張和下一張圖片。如果我在代碼中指定zip文件的名稱,這工作正常;但是,如果我使用filedialog.askopenfilename()對話框指定文件,那麼鍵盤鍵綁定不再起作用。鍵綁定不工作
我認爲這是由於焦點問題,我試着將焦點設置爲鍵綁定到的標籤(都使用label.focus_set()方法和askopenfilename()的父項選項)對話)沒有成功。
代碼如下。任何幫助,將不勝感激,因爲它開始讓我瘋了。
from tkinter import *
from tkinter import filedialog
import io
from PIL import Image, ImageTk
import zipfile
class ComicDisplay():
def __init__(self, master):
frame = Frame(master)
frame.pack(fill='both', expand=1)
self.parent = master
self.fname = ""
self.label = Label(frame, bg="brown", height=500)
self.current_zip_file = filedialog.askopenfilename(filetypes=[(zip, "*.zip")])
# self.current_zip_file = "C:\\Users\\Alexis\\Dropbox\\Photos.zip"
self.image_list = self.acquire_image_list(self.current_zip_file)
self.current_image_number = 0
self.pil_image = self.acquire_image(self.current_zip_file, self.image_list[self.current_image_number])
self.tk_image = ImageTk.PhotoImage(self.pil_image)
self.parent.title(self.fname)
self.label.configure(image=self.tk_image)
self.label.focus_set()
self.label.bind("<Configure>", self.image_resizing)
self.label.bind("<Left>", self.get_last_image)
self.label.bind("<Right>", self.get_next_image)
self.label.bind("<Button-1>", self.get_next_image)
self.label.pack(padx=5, pady=5, fill='both', expand=1)
def acquire_image_list(self, zip_file):
image_list = []
with zipfile.ZipFile(zip_file, "r") as myFile:
for filename in myFile.namelist():
image_list.append(filename)
image_list.sort()
return image_list
def acquire_image(self, zip_file, image_file):
with zipfile.ZipFile(zip_file, "r") as myFile:
self.fname = image_file
image_bytes = myFile.read(image_file)
data_stream = io.BytesIO(image_bytes)
pil_image = Image.open(data_stream)
pil_image = self.image_sizer(pil_image)
return pil_image
def image_sizer(self, image_file, window_size=500):
w, h = image_file.size
if w > h:
image_file_height = int(h*(window_size/w))
image_file = image_file.resize((window_size, image_file_height), Image.ANTIALIAS)
else:
image_file_width = int(w*(window_size/h))
image_file = image_file.resize((image_file_width, window_size), Image.ANTIALIAS)
return image_file
def image_resizing(self, event):
new_height = root.winfo_height() - 14
new_size_image = self.image_sizer(self.pil_image, new_height)
self.tk_image = ImageTk.PhotoImage(new_size_image)
self.label.configure(image=self.tk_image)
def get_next_image(self, event):
if self.current_image_number >= len(self.image_list)-1:
self.current_image_number = 0
else:
self.current_image_number += 1
self.update_image()
def get_last_image(self, event):
if self.current_image_number == 0:
self.current_image_number = len(self.image_list)-1
else:
self.current_image_number -= 1
self.update_image()
def update_image(self):
self.fname = self.image_list[self.current_image_number]
self.pil_image = self.acquire_image(self.current_zip_file, self.image_list[self.current_image_number])
self.tk_image = ImageTk.PhotoImage(self.pil_image)
self.parent.title(self.fname)
self.image_resizing(None)
root = Tk()
app = ComicDisplay(root)
root.mainloop()
您聲明image_list爲空列表每次acquire_image_list被稱爲所以只有在列表中的當前文件名。一個簡單的打印語句將會告訴你這是否是問題。將image_list傳遞給該函數,並將其從函數中返回或使用實例對象 - > self.image_list。 –
我隱約記得幾年前閱讀一個bug報告,主要涉及在主窗口出現之前在窗口上打開一個對話框。在使用文件對話框之前,您可能會嘗試等待UI初始化之後。 –
@CurlyJoe - 只有在選擇zip文件後才能調用acquire_image_list一次。它應該每次都清空,以便列表只包含來自一個文件的圖像。 –