2017-04-26 33 views
-2

下面的代碼顯示了包含一系列頁面的化學測驗應用程序,用戶可以在這些頁面之間切換這些頁面。KeyError:<class'__main __。STAGE1'>

class STARTPAGE(tk.Frame): 
    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     Instructions1 = tk.Label(self, text=("You will obtain a Desired Product that is chosen randomly from a Starting Reactant."))              
     Instructions2 = tk.Label(self, text=("You get 3 Attempts to complete the question in which Points will be added to your score ")) 
     Instructions3 = tk.Label(self, text=("After 3 attempts you will be moved onto next stage or question")) 
     Instructions4 = tk.Label(self, text=("You need to select one Reagent and 1 or 2 Conditions to complete stage")) 
     Instructions5 = tk.Label(self, text=("Your score will be ranked among others in your same class in a leaderboard")) 

     Instructions1.grid(row=0, column=0) 
     Instructions2.grid(row=1, column=0) 
     Instructions3.grid(row=2, column=0) 
     Instructions4.grid(row=3, column=0) 
     Instructions5.grid(row=4, column=0) 

     StartQuiz = tk.Button(self, text="Start Quiz", command=lambda: controller.show_frame(STAGE1)) 
     StartQuiz.grid(row=8, column=1) 

class STAGE1(tk.Frame): 
    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 

     Stage1 = tk.Label(self, text="STAGE 1") 
     Stage1.grid(column=1, row=0)   
     #Explain the Main class and tk frame constructor in each class from stack overflow   
     self.ButtonData = BUTTONDATA(self, tk.Frame) 

     self.ButtonData.ReagentOption1.config(command=lambda: self.AllocatePointsStage(1)) 
     self.ButtonData.ReagentOption2.config(command=lambda: self.AllocatePointsStage(1)) 
     self.ButtonData.ReagentOption3.config(command=lambda: self.AllocatePointsStage(1)) 
     self.ButtonData.ReagentOption4.config(command=lambda: self.AllocatePointsStage(1)) 

     self.ButtonData.ConditionOption1.config(command=lambda: self.AllocatePointsStage(1)) 
     self.ButtonData.ConditionOption2.config(command=lambda: self.AllocatePointsStage(1)) 
     self.ButtonData.ConditionOption3.config(command=lambda: self.AllocatePointsStage(1)) 
     self.ButtonData.ConditionOption4.config(command=lambda: self.AllocatePointsStage(1)) 

     self.ButtonData.ReagentOption1.grid(column=2, row=5) 
     self.ButtonData.ReagentOption2.grid(column=2, row=6) 
     self.ButtonData.ReagentOption3.grid(column=2, row=7) 
     self.ButtonData.ReagentOption4.grid(column=2, row=8) 

     self.ButtonData.ConditionOption1.grid(column=10, row=5) 
     self.ButtonData.ConditionOption2.grid(column=10, row=6) 
     self.ButtonData.ConditionOption3.grid(column=10, row=7) 
     self.ButtonData.ConditionOption4.grid(column=10, row=8) 

     self.Continue = tk.Button(self, text="Continue", command=lambda: controller.show_frame(Stage2)) 
     self.Continue.grid(column=6) 

     self.QuestionStarter = QUESTIONSTARTER(self, tk.Frame) 
     self.QuestionStarter.PointsLabel.grid(row=0, column=6) 
     self.QuestionStarter.AttemptsDisplayed.grid(row=1, column=7) 
     self.QuestionStarter.WordedQuestion.grid(row=0, column=1) 
     self.QuestionStarter.AttemptsDisplayedText.grid(row=1, column=8) 
     DesiredProductLabel = tk.Label(self, command=lambda: ShowDesiredProduct(DesiredProduct)) 
     DesiredProductLabel.grid(row=5, column=0) 

    def ShowDesiredProduct(self, DesiredProduct): 
     DesiredProduct = GetDesiredProduct() 
     return DesiredProduct 

class Main(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 
     tk.Tk.wm_title(self, "Chemistry Quiz") 
     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 (STUDENTLOGINPAGE, STAFFLOGINPAGE, STARTPAGE, ASSIGNMENTPAGE, STAGE1, STAGE2, STAGE3, STAGE4, STAGE5, LEADERBOARDPAGE): 

      frame = F(container, self) 

      self.frames[F] = frame 

      frame.grid(row=0, column=0, sticky="nsew") 

      self.show_frame(STUDENTLOGINPAGE) 
      if self.frames == []: 
       print ("Error in loading program") 
      #This class inherits from Tk class within module of Tk Inter 
      #This basically displays each page in turn from the List 

    def show_frame(self, cont): 
     frame = self.frames[cont] 
     frame.tkraise() 

    def get_page(self, page_class): 
     return self.frames[page_class] 

出於某種原因,我得到以下錯誤,其中我的節目框架內發生的第1階段:

Error -Traceback (most recent call last): 
    File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1549, in __call__ 
    return self.func(*args) 
    File "/Users/ammarhusain/Desktop/Computing Project/Ammar Chemistry Program FINAL.py", line 316, in <lambda> 
    StartQuiz = tk.Button(self, text = "Start Quiz", command=lambda: controller.show_frame(STAGE1)) 
    File "/Users/ammarhusain/Desktop/Computing Project/Ammar Chemistry Program FINAL.py", line 3152, in show_frame 
    frame = self.frames[cont] 
KeyError: <class '__main__.STAGE1'> 
+0

什麼是STUDENTLOGINPAGE? – VMAtm

+0

這是另一個類,它是學生登錄的頁面,我無法將它放在空間原因@VMAtm – Ammar

+0

調試KeyError的第一步是在引發錯誤的代碼之前立即從字典中打印出鍵,驗證您_think_中的鍵在字典中是否真的在詞典中。您還應該驗證「cont」包含您認爲它包含的內容。 –

回答

0

這裏的問題是,你正在使用的類定義爲一個關鍵:

# add the frame 
self.frames[F] = frame 
# show the frame 
self.show_frame(STUDENTLOGINPAGE) 

我建議你使用字符串作爲字典的關鍵,並移動這些線條勾勒出循環:

self.show_frame(STUDENTLOGINPAGE) 

現在回到你的堆棧跟蹤,你有這一行有:

controller.show_frame(STAGE1) 

因此,控制器不包含該按鈕被點擊時STAGE1屏幕。如果顯示正在創建的STUDENTLOGINPAGE所有屏幕,這個問題應該走出去:

# create all the screens 
for F in (STUDENTLOGINPAGE, STAFFLOGINPAGE, STARTPAGE, ASSIGNMENTPAGE, STAGE1, STAGE2, STAGE3, STAGE4, STAGE5, LEADERBOARDPAGE): 
    frame = F(container, self) 
    self.frames[F] = frame 
    frame.grid(row=0, column=0, sticky="nsew") 

# check the sreens availability 
if self.frames == []: 
    print ("Error in loading program") 

# now show the login form 
self.show_frame(STUDENTLOGINPAGE) 
+0

嗨,感謝您的幫助,但我仍然不理解當你說把鑰匙放入字符串並在所有屏幕@VMAtm後顯示STUDENTLOGINPAGE時,你的意思是什麼我也可以聯繫你關於我的程序中的其他問題,這將是驚人的! – Ammar

+0

關於字符串 - 這只是一個建議,因爲做字典鍵作爲類不是一個很好的可讀性練習。關於'STUDENTLOGINPAGE' - 您在循環中顯示它:'self.show_frame(STUDENTLOGINPAGE)',然後創建所有屏幕。將它從'for'移出。我已經更新了答案。 – VMAtm

+0

Ahh ok我明白了,但是現在當我運行我的程序時,它會首先顯示Assignment Page屏幕,而不是StudentLogin頁面?當我使用控制器從作業頁面移動到階段1時,它會帶來相同的錯誤。我可以與你聯繫嗎?這會對你非常有幫助@VMAtm – Ammar