Tkinter 抛出异常,但代码仍然有效,为什么?

问题描述

我正在开发一个漫画书阅读器,到目前为止,我的代码似乎运行良好,除了当我更新画布以显示漫画书页面的 jpg 时发生的一个小结果。

代码

from tkinter import *
from tkinter import filedialog,Tcl
from PIL import ImageTk,Image
from pyunpack import Archive
import shutil
import tempfile
import os

def open_comic():
    os.mkdir('tmp/')
    text_file = filedialog.askopenfilename(title="Open Comic Book File",filetypes=(("CBR Files","*.cbr"),("CBZ Files","*.cbz"),))
    tempdir = tempfile.mkdtemp(suffix='.tmp',dir='tmp/')
    print('Created temp directory',tempdir)
    Archive(text_file).extractall(tempdir)
    file_list = os.listdir(tempdir)
    file_list.sort()
    img = ImageTk.PhotoImage(Image.open(tempdir + "/" + file_list[1]))
    my_image = comic_canvas.create_image(0,anchor=NW,image=img)
    canvas.update()

# Create the Main Window of the Application
mainWindow = Tk()
mainWindow.title("Comic Reader")
mainWindow.geometry("1200x1500")
buttonFrame = LabelFrame(mainWindow)
canvasFrame = LabelFrame(mainWindow,bg="light gray",border=2)
statusFrame = LabelFrame(mainWindow,bg="black",border=2)
comic_canvas = Canvas(canvasFrame,width="1100",height="1400",bg="light gray")

# Create the Menu Bar for the Application
main_menu = Menu(mainWindow)
mainWindow.config(menu=main_menu)

# The File Menu
file_menu = Menu(main_menu,tearoff=False)
main_menu.add_cascade(menu=file_menu,label="File")
file_menu.add_command(label="Open",command=open_comic)
file_menu.add_separator()
file_menu.add_command(label="Quit",command=quit_it)

# The Edit Menu
edit_menu = Menu(main_menu,tearoff=False)
main_menu.add_cascade(menu=edit_menu,label="Edit")
edit_menu.add_command(label="Cut",accelerator="(CTRL+X)")
edit_menu.add_command(label="copy",accelerator="(CTRL+C)") 
edit_menu.add_command(label="Paste",accelerator="(CTRL+V)")

button_back = Button(buttonFrame,text="<=",command=back)
button_exit = Button(buttonFrame,text="Exit",command=quit_it)
button_next = Button(buttonFrame,text="=>",command=lambda: forward(2))

buttonFrame.pack()
canvasFrame.pack()
statusFrame.pack()

button_back.grid(row=1,column=0)
button_exit.grid(row=1,column=1)
button_next.grid(row=1,column=2)
comic_canvas.grid(row=2,column=1)

# Start the Application Here
mainWindow.mainloop()  # Creates the GUI for the Application

现在就像上面一样,它可以更新画布,并让您看到图像,但会引发错误

> Exception in Tkinter callback Traceback (most recent call last):  
> File
> "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py",> line 1884,in __call__
>     return self.func(*args)   File "/Users/kb2mob/Python Projects/Comic Reader/comicreader.py",line 28,in open_comic
>     canvas.update() NameError: name 'canvas' is not defined

哪个,是的,应该是因为画布被命名为“comic_canvas”。但是后来我确实为 .update() 方法使用了正确的名称,它快速闪烁然后消失,当然不会抛出错误,因为它是正确的用法

有人知道这是为什么吗?

这是在最新的 Mac OS 上的 Python 3.9.1。

解决方法

发现问题:

没有在我的函数 open_comic() 的末尾保留图像引用

comic_canvas.img = img

把它放在最后,它起作用了。