单击按钮后如何更改标签和单选按钮?

时间:2017-06-30 12:43:15

标签: python python-3.x tkinter

我编写了一个脚本,它使用tkinterrandomsqlite3从表格和问题中随机抽取四个元素。目前,我可以问一个问题。使用radiobuttons实现四个选项。我还可以测试答案是否正确,并通过toplevel()向用户显示结果。

问题是,如何在点击继续按钮后刷新问题?

我的整个代码如下。我尝试刷新continue_asking下的随机数字和标签或def调用的其他continue_asking。但它根本不起作用。

from tkinter import *
from sqlite3 import *
from random import *


class Question(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.grid()
        self.prepare_question()

    def prepare_question(self):
        self.tumu = {0:['ask1','answer1'], # instead of SQL query
                     1:['ask2','answer2'],
                     2:['ask3','answer3'], 
                     3:['ask4','answer4']}
        self.create_widgets()

    def create_widgets(self):
        self.choiceFrame = Frame(self)
        self.choiceFrame.grid(row=2, column=0)
        self.choiceNum = IntVar()
        for i in range(4):
            Radiobutton(self.choiceFrame, text=self.tumu[i][1], variable=self.choiceNum, value=i) \
                        .grid(row=2, column=i, padx=5, pady=5)

        self.q_num = randrange(4)
        self.q_word = self.tumu[self.q_num][0]

        lbl_question = Label(self, text="Which one is the meaning of the word: " + self.q_word, font="Courier 12")
        lbl_question.grid(row=0, column=0, columnspan=4, padx=5, pady=5, sticky=W)

        txt_question = Text(self, height=1, font="Courier 12", pady=2)
        txt_question.tag_configure("myStyle", font="Courier 12 bold")
        txt_question.insert("end", "Please choose the answer and ")
        txt_question.insert("end", "click okay to see the results.", "myStyle")
        txt_question.configure(state="disabled")
        txt_question.grid(row=1, column=0, columnspan=4, padx=5, sticky=W)

        btn_okay = Button(self, text="Okay", font="12", command=self.a_control)
        btn_okay.grid(row=3, column=0, columnspan=2)

    def a_control(self):
        self.choosenWord = self.q_num
        self.frm_answer = Toplevel()
        self.frm_answer.title("Result")
        self.selectedWord = self.choiceNum.get()
        txt_result = Text(self.frm_answer, height=4, width = 40)

        if self.choosenWord == self.selectedWord:
            txt_result.insert("end", "Congrats! Your answer is correct.\n")
        else:
            txt_result.insert("end","Your answer is not correct.\n")
            txt_result.insert("end", "Correct answer is " + self.tumu[self.q_num][1] + '\n')

        txt_result.insert("end", "Please click Continue to continue.\n")
        txt_result.insert("end", "Click cancel to quit.")
        txt_result.grid(row=0, column=0, columnspan=2, padx = 5, pady=5)
        txt_result.configure(state="disabled")
        btn_continue = Button(self.frm_answer, text="Continue", command=lambda: self.continue_asking(self.frm_answer))
        btn_continue.grid(row=1, column=0, padx=5, pady=5, sticky = W)

        btn_quit = Button(self.frm_answer, text="Cancel", command=self.end_asking)
        btn_quit.grid(row=1, column=1, padx=5, pady=5, sticky = W)

    def continue_asking(self,frm_answer):
        frm_answer.destroy()

    def end_asking(self):
        root.destroy()

root = Tk()
app = Question(root)
root.mainloop()

我尝试将prepare_question添加到continue_asking。它一直在问问题,但小部件没有改变。它们只是重叠。enter image description here

1 个答案:

答案 0 :(得分:1)

修改

所以让我们从头开始重启,我完全错了,因为没有删除小部件,它们堆叠在主框架子列表中。

你仍然不需要编写如此多的代码,主要是移动一些部分。

首先,为了能够更新小部件并安静地准备新问题,请移动 在构造函数中self.create_widgets()并将随机索引self.q_numself.q_word放在prepare_question中,因为它属于问题创建的逻辑。

create_widgets()中,您只需要对标签问题进行一些控制,因此我们添加self.lbl_question ...

最后,我建议创建一个新函数update_widgets(),但您可以将逻辑放在continue_asking()中。

在此函数中,调用prepare_question来更新下一个问题(sql查询和随机内容)。由于我们移动随机索引,所以一切都准备好更新每个小部件:

  • 问题标签的文字
  • radiobuttons的文字。我没有为改变这些的循环感到骄傲,但那就是诀窍。 (我们保持为索引创建的值与新索引相匹配,我对SQL查询的逻辑不太确定,我跟随你的第一个实现text=self.tumu[i][1]

如果有人能告诉我如何更轻松地获得radiobutton值,我很感兴趣

以下是整个代码:

from tkinter import *
from sqlite3 import *
from random import *


class Question(Frame):
    def __init__(self, master):
        Frame.__init__(self, master)
        self.grid()
        self.prepare_question()
        self.create_widgets()

    def prepare_question(self):
        self.tumu = {0:['ask1','answer1'], # instead of SQL query
                     1:['ask2','answer2'],
                     2:['ask3','answer3'], 
                     3:['ask4','answer4']}

        self.q_num = randrange(4)
        self.q_word = self.tumu[self.q_num][0]

    def create_widgets(self):
        self.choiceFrame = Frame(self)
        self.choiceFrame.grid(row=2, column=0)
        self.choiceNum = IntVar()
        for i in range(4):
            Radiobutton(self.choiceFrame, text=self.tumu[i][1], variable=self.choiceNum, value=i) \
                        .grid(row=2, column=i, padx=5, pady=5)

        self.lbl_question = Label(self, text="Which one is the meaning of the word: " + self.q_word, font="Courier 12")
        self.lbl_question.grid(row=0, column=0, columnspan=4, padx=5, pady=5, sticky=W)

        txt_question = Text(self, height=1, font="Courier 12", pady=2)
        txt_question.tag_configure("myStyle", font="Courier 12 bold")
        txt_question.insert("end", "Please choose the answer and ")
        txt_question.insert("end", "click okay to see the results.", "myStyle")
        txt_question.configure(state="disabled")
        txt_question.grid(row=1, column=0, columnspan=4, padx=5, sticky=W)

        btn_okay = Button(self, text="Okay", font="12", command=self.a_control)
        btn_okay.grid(row=3, column=0, columnspan=2)

    def a_control(self):
        self.choosenWord = self.q_num
        self.frm_answer = Toplevel()
        self.frm_answer.title("Result")
        self.selectedWord = self.choiceNum.get()
        txt_result = Text(self.frm_answer, height=4, width = 40)

        if self.choosenWord == self.selectedWord:
            txt_result.insert("end", "Congrats! Your answer is correct.\n")
        else:
            txt_result.insert("end","Your answer is not correct.\n")
            txt_result.insert("end", "Correct answer is " + self.tumu[self.q_num][1] + '\n')

        txt_result.insert("end", "Please click Continue to continue.\n")
        txt_result.insert("end", "Click cancel to quit.")
        txt_result.grid(row=0, column=0, columnspan=2, padx = 5, pady=5)
        txt_result.configure(state="disabled")
        btn_continue = Button(self.frm_answer, text="Continue", command=self.continue_asking)
        btn_continue.grid(row=1, column=0, padx=5, pady=5, sticky = W)

        btn_quit = Button(self.frm_answer, text="Cancel", command=self.end_asking)
        btn_quit.grid(row=1, column=1, padx=5, pady=5, sticky = W)

    def continue_asking(self):
        self.frm_answer.destroy()
        self.update_widgets()

    def update_widgets(self):
        self.prepare_question()

        # change question text 
        self.lbl_question.configure(text = "Which one is the meaning of the word: " + self.q_word)

        # change Radiobutton
        for child in self.choiceFrame.children.values():
            index = child.config()['value'][4]                              
            child.configure(text = self.tumu[index][1])
            if index == 0: # reset the focus
                child.select()

    def end_asking(self):
        root.destroy()

root = Tk()
app = Question(root)
root.mainloop()

第一个废话贴:(不要做部分)

您不需要更改太多代码来解决当前问题,您是否尝试过以下操作?

def continue_asking(self,frm_answer):
    frm_answer.destroy()
    self.prepare_question()

我不会检查整个代码,还有另一个地方,但是当你调用continue_asking()时,你也可以避免使用lambda,因为你将框架存储在self.frm_answer

    btn_continue = Button(self.frm_answer, text="Continue", command=self.continue_asking)
    # [...]

def continue_asking(self):
    self.frm_answer.destroy()
    self.prepare_question()