来自Tkinter中Label中的函数的文本更新

时间:2015-05-27 12:18:10

标签: python tkinter

我有一个问题,有四个选项和一个计时器。现在我已经阅读了一个json文件内容并将其放入问题列表中。在设置GUI并对问题列表中的问题进行混洗之后,现在我想更新按钮中的questionText和选项。在所有这些之后我调用了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的按钮中显示答案。此外,我不需要尝试随机化答案的顺序,而是需要随机按下buttonList列表,以便在为其分配答案之前随机按下按钮的顺序。

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

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

updateTimer()方法将首先从计时器IntVar中减去一个,然后检查计时器是否为0.如果是,带有“Game Over”消息的消息框和用户的分数,则销毁主窗口结束该计划。否则(如果计时器不为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 个答案:

答案 0 :(得分:1)

您的代码中存在一些与使用实例变量相关的问题,这些问题是对象实例的唯一变量。实例变量可以在同一个类的方法中访问,这是您在loadQuestion()方法中访问问题列表时需要执行的操作。例如:

questions = json.load(data_file)

questions方法中定义名为__init__() local 变量,但是,__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

现在,要更新问题标签的值,需要进行类似的更改。在questionText

中将__init__()声明为实例变量
self.questionText = StringVar()

并在loadQuestions()内更新:

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()中的按钮文字。