2015-05-27 16 views
-2

我有一个与四个选项和一个计时器的问题。现在我读了一个json文件内容,并将其列入问题列表。在设置GUI并将问题列入问题列表之后,现在我想更新按钮中的questionText和选项。所有这一切之后,我调用了loadQuestion()函数,但是之后我的程序突然停止。从Tkinter中的一个函数中的函数更新文本

from Tkinter import * 
import json 
from random import shuffle 
import tkMessageBox 
class ProgramGUI(Frame): 
def __init__(self, master=None): 
    master.title('QuizBox') 
    master.update() 
    master.minsize(350, 150) 
    Frame.__init__(self, master) 
    try: 
     with open('questions.txt') as data_file: 
      try: 
       questions=json.load(data_file) 
      except ValueError,e: 
       tkMessageBox.showerror("Invalid JSON","Invlid JSON Format") 
       master.destroy() 
       questions=[] 
      data_file.close() 
    except (OSError, IOError) as err: 
     tkMessageBox.showerror("File Not Found","File Not Found!!") 
     master.destroy() 
    questionText = StringVar() 

    Label(master,textvariable=questionText,justify=CENTER,wraplength=200).pack() 
    questionText.set("Question text goes here") 

    timer = IntVar() 
    Label(master,textvariable=timer,justify=CENTER,fg="blue").pack() 
    timer.set("10") 

    buttonList = ["Answer 1", "Answer 2", "Answer 3", "Answer 4"] 
    self.rowconfigure(0, pad=3) 
    for i, value in enumerate(buttonList): 
     self.columnconfigure(i, pad=3) 
     Button(self, text=value).grid(row=0, column=i) 

    self.pack() 

    score = IntVar() 
    Label(master,textvariable=score,justify=CENTER).pack() 
    score.set("Score: 0") 

    shuffle(questions) 
    #print questions 
    loadQuestion(self) 
    master.mainloop() 

def loadQuestion(self): 
    print questions 
    if len(questions) > 0: 
     # Modify the questionText StringVar with first question in question[] and delete it from questions[] 

root = Tk() 
gui = ProgramGUI(master=root) 
root.destroy() 

loadQuestion()方法负责在GUI中显示下一个问题并启动计时器。该方法必须首先从问题列表中选择一个问题(即包含问题和答案的字典),然后以随机顺序在适当的标签中显示问题的文本以及在GUI的按钮中显示答案。也不是试图随机选择答案的顺序,我需要随机调整buttonList列表以随机选择按钮的顺序,然后再将答案分配给它们。

该问题应该从问题列表中删除,以便它不再被选中。我们可以使用“pop()”列表方法删除列表中的最后一个元素。

定时器IntVar设置为11,然后调用“updateTimer()”来启动定时器。与其试图随机化答案的顺序,我试图在将按钮顺序分配给它们之前随机调整按钮顺序。由于定时器在设置后立即更新,用户看到的第一个数字为10.

updateTimer()方法将首先从定时器IntVar中减去一个,然后检查定时器是否为0.如果是,带有“游戏结束”消息的消息框和用户的分数,然后销毁主窗口以结束程序。否则(如果定时器不是0),我们需要在1秒内再次调用“updateTimer()”方法。我认为我们可以使用“after()”方法,并通过将即将发生的呼叫的ID存储在变量中,我们可以根据需要取消它。

注:questionList的类型为JSON格式:

[{   
    "question": "Example Question 1",     
    "wrong1": "Incorrect answer",   
    "wrong2": "Another wrong one",  
    "wrong3": "Nope, also wrong",  
    "answer": "Correct answer"  
} ] 

回答

1

有在你的代码涉及到您使用实例变量的一些问题,唯一的一个对象的实例,这些是变量。实例变量可以在同一个类的方法中访问,这就是您在loadQuestion()方法中访问问题列表所需要做的事情。例如:

questions = json.load(data_file) 

定义了__init__()方法命名questions一个本地变量,但是,该变量不存在,一旦__init__()功能终止。你需要做它的一个实例变量,self这样的:

self.questions = json.load(data_file) 

现在这个变量可以用self.questions在同一类,如loadQuestions(),这将是这样写的(注意使用self.)的方法来访问:

def loadQuestion(self): 
    print self.questions 
    if len(self.questions) > 0: 
     # Modify the questionText StringVar with first question in question[] and delete it from questions[] 
     pass 

现在,更新的问题标签的值需要类似的变化。内loadQuestions()

self.questionText = StringVar() 

和更新:声明questionText作为一个实例变量在__init__()

def loadQuestion(self): 
    print self.questions 
    if len(self.questions) > 0: 
     # just take the first question and answers from the pre-shuffled list 
     q_and_a = self.questions.pop() 
     self.questionText.set(q_and_a['question']) 
     # update answer buttons too.... 

你会发现,你需要使用类似的方法对每个答案按钮,即让这些实例变量并更新loadQuestions()中的按钮文本。

+0

我试过这个:http://pastebin.com/Qn2CeY1q但是得到错误。我是否以正确的方式调用函数? – ms8

+0

您需要将所有'questions'更新为'self.questions',例如修改过的代码中的第44行应该是'shuffle(self.questions)'。第25行和第26行也应该使用'self.questionText'。通过阅读和理解错误信息,任何其他人都应该很容易被发现。 – mhawke

+0

此代码运行良好,但未调用loadQueston函数http://pastebin.com/xi04UQ9g – ms8

相关问题