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

标签 python python-3.x tkinter

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

问题是,单击“继续”按钮后如何刷新问题?

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

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

最佳答案

编辑

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

你仍然不需要写那么多代码,主要是移动一些部分。

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

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

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

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

  • 问题标签的文本
  • 单选按钮的文本。我对改变这些的循环并不感到自豪,但这就可以了。 (我们保留为索引创建的值以匹配新的值,我不太确定 SQL 查询的逻辑,我遵循您的第一个实现 text=self.tumu[i][1])

如果有人能告诉我如何更轻松地获取单选按钮值,我很感兴趣

这是完整的代码:

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()

关于python - 单击按钮后如何更改标签和单选按钮?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44846783/

相关文章:

带有 Tkinter 的 Python 聊天机器人

python - genfromtxt 加载按行排列的数据

python - 我如何在 python unittest 中创建测试套件

python - 遍历子文件夹文件?

python - 如何在 GitHub 中安装适用于 python 的 GEM 包?

python - 覆盖 Python Tkinter 中的默认选项卡行为

Python/MySQL - 将csv文件导入mysql

python - python pandas 中的等效 R "findcorrelation(corr,cutoff = 0.75)"

python - 如何在Python中加入Pandas数据框

python - 如何删除对 "HTTP For Humans"Requests 库的依赖并使用 urllib 代替?