請尋求一些幫助,了解為什么我在 JSON 加載中遇到密鑰錯誤。
錯誤是:
Exception in Tkinter callback
Traceback (most recent call last):
File "...\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "...\test22.py", line 108, in <lambda>
command=lambda: controller.show_frame(TestClass.saved_frame))
File "...\test22.py", line 77, in show_frame
frame = self.frames[cont]
KeyError: "<class '__main__.PageTwo'>"
目標和步驟:讓檔案選單(保存)保留類變數,如果程式退出并重新啟動,則可以加載這些變數,以恢復啟動保存的程式。
這將由 PageOne 類使用 TestClass.saved_frame 來完成,該框架以 JSON 格式存盤/加載,并使用“加載保存”按鈕打開指定的框架以及相關的存盤變數。
我有類變數可以正常保存和加載(可以在單個實體中使用檔案選單保存 GUI 中的“加載保存”主選單按鈕來完成)。問題是檢索類變數以加載到程式的新實體中。
如果有更好的可用方式,我不會以這種方式實施保存/加載。如果我可以讓它與這兩個類變數(num 和 frame)一起作業,我確實計劃用更多的類變數來擴展這個方法。
導致問題的相關代碼在TestClass 類的函式 **def load_game()** 中 以及可能與def show_frame()的JSON 互動
我已經嘗試過剝離引號的變體,在 JSON 中迭代鍵/值并選擇相關值,literal_eval,但每次我得到 KeyError。
要復制問題,請打開 GUI > 選擇數字 > 下一頁 > 檔案選單并保存 > 退出程式,然后再次打開 GUI > 檔案選單加載 > 加載保存按鈕
import tkinter as tk
import json
from pathlib import Path
def generated_savegame_folder():
path = Path.cwd() / 'Save Games'
path.mkdir(parents=True, exist_ok=True)
generated_savegame_folder()
class TestClass(tk.Tk):
num = None
active_frame = None
saved_frame = None
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Game")
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 (PageOne, PageTwo, LoadPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def save_game(): # JSON METHOD
TestClass.saved_frame = TestClass.active_frame
print("Saved as", TestClass.saved_frame)
data = {
"Saved Frame": str(TestClass.saved_frame),
"Num": TestClass.num.get()
}
save_folder = Path.cwd() / 'Save Games'
save_file = "saveJSON.txt"
file_path = save_folder / save_file
with file_path.open("w", encoding="utf-8") as f:
json.dump(data, f)
def load_game(): # JSON METHOD
path = Path.cwd() / 'Save Games' / 'saveJSON.txt'
with path.open('r') as f:
data = json.load(f)
print("loading", data)
for k, v in data.items():
print(k, v)
TestClass.saved_frame = data["Saved Frame"]
def menu():
menu_bar = tk.Menu(container)
file_menu = tk.Menu(menu_bar, tearoff=0)
file_menu.add_command(label="Save Game", command=save_game)
file_menu.add_command(label="Load Game", command=load_game)
file_menu.add_separator()
file_menu.add_command(label="Exit", command=quit)
menu_bar.add_cascade(label="File", menu=file_menu)
tk.Tk.config(self, menu=menu_bar)
menu()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
TestClass.active_frame = cont
print("prints container(active_frame) on page change:", TestClass.active_frame) # testing
print("prints frame(frame.tkraise) on page change", frame) # testing
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.label = tk.Label(self,
text="Make a selection",
wraplength=450, justify='center')
self.label.pack(padx=10, pady=10)
TestClass.num = tk.StringVar(value=' ')
command = lambda *args: PageTwo.label.config(text=PageTwo.text.format(TestClass.num.get()))
tk.Radiobutton(self, text="1", variable=TestClass.num, command=command, value="1", ).pack()
tk.Radiobutton(self, text="2", variable=TestClass.num, command=command, value="2", ).pack()
tk.Radiobutton(self, text="3", variable=TestClass.num, command=command, value="3", ).pack()
view_selection = tk.Button(self, text="test selection", command=lambda: print(TestClass.num.get()))
view_selection.pack()
next_page = tk.Button(self, text="Next Page",
command=lambda: controller.show_frame(PageTwo))
next_page.pack(pady=10, padx=10)
# meant to load the last open page. PageTwo, PageThree... PageTwenty, etc. Whichever was last open before (save)
# while also loading any saved variables
load_last = tk.Button(self, text="Load Instance Save",
command=lambda: controller.show_frame(TestClass.saved_frame))
load_last.pack(pady=10, padx=10)
# load_last2 = tk.Button(self, text="Load JSON Save",
# command=lambda: controller.show_frame(restore_game))
# load_last2.pack(pady=10, padx=10)
class PageTwo(tk.Frame):
label = ''
text = ''
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
PageTwo.text = "The number should show up here -> {} <- "
PageTwo.label = tk.Label(self, text=self.text.format(''))
PageTwo.label.pack()
text1 = tk.Text(self)
text1.pack()
see_num = tk.Button(self, text="View Number",
command=lambda: text1.insert('1.0', TestClass.num.get()))
see_num.pack(pady=10, padx=10)
home_button = tk.Button(self, text="Go Home",
command=lambda: controller.show_frame(PageOne))
home_button.pack(pady=10, padx=10)
class LoadPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
if __name__ == "__main__":
app = TestClass()
app.mainloop()
uj5u.com熱心網友回復:
從 JSON 檔案加載的資料是字串,輸入的鍵應該cont是self.frames[cont]對類的參考。
例如,您需要保存類名,"PageTwo"而不是保存"<class '__main__.PageTwo'>"到 JSON 檔案中。然后,您需要在"PageTwo"從 JSON 檔案加載字串后將其轉換為類的參考:
def save_game(): # JSON METHOD
TestClass.saved_frame = TestClass.active_frame
# use .__name__ to get the class name and save it to JSON file
print("Saved as", TestClass.saved_frame.__name__)
data = {
"Saved Frame": TestClass.saved_frame.__name__,
"Num": TestClass.num.get()
}
save_folder = Path.cwd() / 'Save Games'
save_file = "saveJSON.txt"
file_path = save_folder / save_file
with file_path.open("w", encoding="utf-8") as f:
json.dump(data, f)
def load_game(): # JSON METHOD
path = Path.cwd() / 'Save Games' / 'saveJSON.txt'
with path.open('r') as f:
data = json.load(f)
print("loading", data)
for k, v in data.items():
print(k, v)
# convert the class name to reference of class
TestClass.saved_frame = globals()[data["Saved Frame"]] # or eval(data["Saved Frame"])
print('loaded', TestClass.saved_frame)
uj5u.com熱心網友回復:
考慮這個小例子:
myList = [1, 2, 3, 4]
print(myList [10]) # This will cause a KeyError as there isn't a 10th index in the list
嘗試列印其中的值cont和條目數frames- 我想您會發現您正在嘗試訪問不存在的索引。列印類似這樣的內容/使用除錯器查看值
Consider this little example:
```python
myList = [1, 2, 3, 4]
print(myList [10]) # This will cause a KeyError as there isn't a 10th index in the list
print(f"幀數:{self.frames.len},續:{co??nt}") frame = self.frames[cont]
**I'm not sure what method / variabe / member variable is used to get the length, so I've just used {obj}.len here as a placeholder.**
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/420491.html
標籤:
下一篇:三陣列演算法錯誤
