Python Tkinter中标签中函数的文本更新

Python Tkinter中标签中函数的文本更新,python,tkinter,Python,Tkinter,我有一个关于四个选项和一个计时器的问题。现在我已经阅读了一个json文件内容,并将其放入问题列表中。在设置GUI并在问题列表中洗牌问题之后,现在我想更新按钮中的问题文本和选项。在这一切之后,我调用了loadQuestion()函数,但此后我的程序突然停止 from Tkinter import * import json from random import shuffle import tkMessageBox class ProgramGUI(Frame): def __init__(sel

我有一个关于四个选项和一个计时器的问题。现在我已经阅读了一个json文件内容,并将其放入问题列表中。在设置GUI并在问题列表中洗牌问题之后,现在我想更新按钮中的问题文本和选项。在这一切之后,我调用了loadQuestion()函数,但此后我的程序突然停止

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的按钮中以随机顺序显示答案。另外,在给按钮分配答案之前,我不需要尝试随机化答案的顺序,而是需要将按钮列表洗牌以随机化按钮的顺序

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

计时器IntVar设置为11,然后调用“updateTimer()”启动计时器。我没有尝试随机排列答案的顺序,而是尝试在给按钮分配答案之前随机排列按钮列表以随机排列按钮的顺序。由于计时器在设置后会立即更新,因此用户看到的第一个数字是10

updateTimer()方法将首先从计时器IntVar中减去一,然后检查计时器是否为0。如果是,则显示带有“游戏结束”消息和用户分数的messagebox,然后销毁主窗口以结束程序。否则(如果计时器不是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"     
} ]

代码中有一些问题与实例变量的使用有关,这些变量是对象实例特有的变量。实例变量可以在同一类的方法中访问,这是访问
loadQuestion()
方法中的问题列表所需的操作。例如:

questions = json.load(data_file)
方法中定义名为
的局部变量questions
,但是,一旦
函数终止,该变量就不存在了。您需要将其设置为带有
self
的实例变量,如下所示:

self.questions = json.load(data_file)
现在,可以在同一类的方法中使用
self.questions
访问此变量,例如
loadQuestions()
,其编写方式如下(注意
self.
的用法):

现在,更新问题标签的值需要进行类似的更改。将
questionText
声明为
中的实例变量

并在
loadQuestions()中更新:


您会发现,您需要对每个答案按钮使用类似的方法,即在
loadQuestions()

中生成这些实例变量并更新按钮的文本。我尝试了这个方法:但出现了错误。我调用函数的方式是否正确?您需要将所有
问题更新为
self.questions
,例如,修改后的代码中的第44行应为
shuffle(self.questions)
。第25行和第26行也应使用
self.questionText
。通过阅读和理解错误消息,应该很容易发现任何其他错误。此代码运行正常,但没有调用loadQueston函数
ProgramGUI。loadQuestion
不是调用函数,它只是引用它-您需要使用
()
来实现调用。另外,要从同一类的另一个方法调用方法,只需像对待变量那样使用
self
,即
self.loadQuestion()
就可以了。为什么self.buttonList=[q_and_a['error 1'],q_and_a['error 2'],q_and_a['error 3'],q_and_a['answer']不起作用?
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
self.questionText = StringVar()
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....