我正在学习使用Sentdex教程的tkinter,并且在尝试更改页面时遇到问题。我的编译器会抛出一些关于KeyError的内容,每当我将起始页面上的按钮更改为自身而不是PageOne时,它都没有给出:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Jason\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/Jason/PycharmProjects/gui/main.py", line 43, in <lambda>
button1 = tk.Button(self, text="Visit Page 1",command=lambda: controller.show_frame(PageOne))
File "C:/Users/Jason/PycharmProjects/gui/main.py", line 29, in show_frame
frame = self.frames[cont]
KeyError: <class '__main__.PageOne'>
和我的代码:
import tkinter as tk
LARGE_FONT=("Verdana", 12)
class SeaofBTCapp(tk.Tk):
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 = {}
frame = StartPage(container, self)
self.frames[StartPage] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def qf(param):
print(param)
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
#command within button cant throw args to funcs. Use lambda to throw those args to the func instead
button1 = tk.Button(self, text="Visit Page 1",command=lambda: controller.show_frame(PageOne))
button1.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
#command within button cant throw args to funcs. Use lambda to throw those args to the func instead
button1 = tk.Button(self, text="Visit Page 1",command=lambda: controller.show_frame(StartPage))
button1.pack()
app = SeaofBTCapp()
app.mainloop()
答案 0 :(得分:1)
您的按钮正在调用show_frame(PageOne)
,但您从未创建过PageOne
的实例。所以,当然,self.frames
中没有与该页面匹配的键。
也许您打算在初始代码中创建PageOne
的实例?
def __init__(self, *args, **kwargs):
...
frame = PageOne(container, self)
self.frames[PageOne] = frame
...
如果您不想在需要之前创建页面,可以在show_frame
中添加该代码。首先,您需要将container
设为实例变量(即:self.container
),然后将show_frame
修改为如下所示:
def show_frame(self, cont):
if cont not in self.frames:
self.frames[cont] = cont(self.container, self)
frame = self.frames[cont]
frame.tkraise()
答案 1 :(得分:0)
您的代码包含几个问题。您没有将<class '__main__.PageOne'>
映射到某些内容而导致的密钥代码。
如果您更改以下代码,则不会再出现任何关键错误。
# .....
frame = StartPage(container, self)
frame_ = PageOne(container, self)
self.frames[StartPage] = frame
self.frames[PageOne] = frame_
# ......
以下是完整代码:
import tkinter as tk
LARGE_FONT=("Verdana", 12)
class SeaofBTCapp(tk.Tk):
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 = {}
frame = StartPage(container, self)
frame_ = PageOne(container, self)
self.frames[StartPage] = frame
self.frames[PageOne] = frame_
frame.grid(row=0, column=0, sticky="nsew")
frame_.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def qf(param):
print(param)
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
#command within button cant throw args to funcs. Use lambda to throw those args to the func instead
button1 = tk.Button(self, text="Visit Page 1",command=lambda: controller.show_frame(PageOne))
button1.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Page One", font=LARGE_FONT)
label.pack(pady=10,padx=10)
#command within button cant throw args to funcs. Use lambda to throw those args to the func instead
button1 = tk.Button(self, text="Start Page",command=lambda: controller.show_frame(StartPage))
button1.pack()
app = SeaofBTCapp()
app.mainloop()