我在使用 Python tkinter 创建了一个程序,它可以正常运行。
- 但是,当我添加一个新的类
HelpPage时,程序开始抛出KeyError异常,错误信息为"KeyError: <class __main__."。 - 我尝试删除
HelpPage类,但仍然会出现同样的错误,错误信息变为"KeyError: "main.PageTwo"。 - 我尝试了很多方法,但无法让程序正常运行。
解决方案
- 仔细检查代码后,发现问题出在
StartPage类中的button1按钮的command属性。 command属性的值是一个 lambda 表达式,它会在按钮被按下时调用controller.show_frame(HelpPage)函数。- 但是,在
StartPage类中,button1按钮的command属性的值是controller.show_frame(HelpPage),这会导致函数在按钮被按下之前就被调用,从而抛出KeyError异常。 - 将
command属性的值改为lambda: controller.show_frame(HelpPage)可以解决这个问题,因为这样函数只会在按钮被按下时才被调用。
修改后的代码如下:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Image Overlap Program V 1.0")
label.pack(pady=10, padx=10)
# 修改此处
button1 = tk.Button(self, text="Help", command=lambda: controller.show_frame(HelpPage))
button1.pack()
button2 = tk.Button(self, text="Select Folder", command=lambda: controller.selectfolder())
button2.pack()
代码例子
import Tkinter as tk
import tkFileDialog
import os
class Application(tk.Tk):
PixSize=0
cnt=1
height=0
width=0
NumPixX=0
NumPixY=0
NumImages=0
file='none'
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,*args,**kwargs)
container = tk.Frame(self)
container.pack(side="top",fill="both",expand = True)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
self.frames={}
for F in (StartPage,PageOne,PageTwo,PageThree,FinalPage,HelpPage):
frame = F(container,self)
self.frames[F]= frame
frame.grid(row=0,column=0,sticky="nsew")
self.show_frame(StartPage)
def selectfolder(self):
folder=tkFileDialog.asksaveasfile()
self.file=folder
self.show_frame(PageOne)
def show_frame(self,controller):
frame=self.frames[controller]
frame.tkraise()
def rescalc(self,argCamDist,argSenWidth,argFocLen,argNumPix,cont):
HFOV = float(argCamDist.get())*(float(argSenWidth.get())/float(argFocLen.get()))
self.PixSize = float(argNumPix.get())/HFOV
cont.show_frame(PageThree)
def GetNumbers(self,argNumImages,argNumPixX,argNumPixY,cont):
self.NumPixX=int(argNumPixX.get())
self.NumPixY=int(argNumPixY.get())
self.NumImages=int(argNumImages.get())
cont.file.write(str(self.NumImages))
cont.show_frame(PageTwo)
def ClipCalculator(self,argLabel,argtop,argleft,argbottom,argright,argNumPixX,argNumPixY,argNumImages,argLabel3,argLabel4,cont):
upper=int(self.PixSize*float(argtop.get()))+1
left=int(self.PixSize*float(argleft.get()))+1
if cont.cnt==1:
bottom=int(argNumPixY)-(int(self.PixSize*float(argbottom.get()))+1)
right=int(argNumPixX)-(int(self.PixSize*float(argright.get()))+1)
cont.width=right-left
cont.height=upper-bottom
else:
bottom=upper+cont.height
right=left+cont.width
cont.file.write('upper left: rows:{0}:columns:{1} \n'.format(upper,left))
cont.file.write('upper right: rows:{0}:columns:{1} \n'.format(upper,right))
cont.file.write('lower left: rows:{0}:columns:{1} \n'.format(bottom,left))
cont.file.write('lower right: rows:{0}:columns:{1} \n'.format(bottom,right))
cont.cnt+=1
argLabel['text']="Image Number {0}".format(cont.cnt)
argtop.delete(0,tk.END)
argtop.insert(0,"0.0")
argleft.delete(0,tk.END)
argleft.insert(0,"0.0")
argbottom.delete(0,tk.END)
argbottom.insert(0,"0.0")
argright.delete(0,tk.END)
argright.insert(0,"0.0")
cont.refresh(argbottom,argright,argLabel3,argLabel4,cont)
def refresh(self,Label3,Label4,entry3,entry4,cont):
if cont.cnt==1:
cont.show_frame(PageTwo)
if (cont.cnt > 1 and cont.cnt <= cont.NumImages):
Label3.forget()
Label4.forget()
entry3.forget()
entry4.forget()
cont.show_frame(PageTwo)
else:
cont.file.close()
cont.show_frame(FinalPage)
class StartPage(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
label=tk.Label(self,text="Image Overlap Program V 1.0")
label.pack(pady=10,padx=10)
# 修改处
button1 = tk.Button(self, text="Help", command=lambda: controller.show_frame(HelpPage))
button1.pack()
button2 = tk.Button(self, text="Select Folder", command=lambda: controller.selectfolder())
button2.pack()
class PageOne(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
label3=tk.Label(self,text="Camera Parameters")
label3.pack(pady=10,padx=10)
label1=tk.Label(self,text="Camera Distance").pack()
entry1=tk.Entry(self)
entry1.insert(0,"0.0")
entry1.pack()
label2=tk.Label(self,text="Sensor Width").pack()
entry2=tk.Entry(self)
entry2.insert(0,"0.0")
entry2.pack()
label3=tk.Label(self,text="Focal Length").pack()
entry3=tk.Entry(self)
entry3.insert(0,"0.0")
entry3.pack()
label4=tk.Label(self,text="Number Of Pixels").pack()
entry4=tk.Entry(self)
entry4.insert(0,"0.0")
entry4.pack()
button1=tk.Button(self,text='run',command = lambda: controller.rescalc(entry1,entry2,entry3,entry4,controller))
button1.pack()
button3 = tk.Button(self, text="Home", command=lambda: controller.show_frame(StartPage))
button3.pack()
class PageTwo(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
cont=controller
argNumPixX= cont.NumPixX
argNumPixY= cont.