如何在tkinter中堆叠相同的帧而不复制和粘贴帧

时间:2018-04-20 12:55:50

标签: python user-interface tkinter

使用这里的方法Switch between two frames in tkinter我想叠加相同的帧10次来创建一个10个问题的测验,到目前为止,我通过复制和粘贴帧10次并更改名称来完成这项工作,但是我我希望有一种更简单有效的方法来使用某种循环来做到这一点。我已经在下面提供了代码的摘录,感谢您的帮助。

from tkinter import *




class secondaryActivity(Tk):
    def __init__(self, *args, **kwargs):
        Tk.__init__(self,*args,**kwargs)


        container=Frame(self)
        container.pack(side="top", fill="both", expand=True)

        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames={}

        for F in (quiz, quiz1):
            frame = F(container, self)
            pageName = F.__name__
            self.frames[pageName]=frame
            frame.grid(row=0, column=0, sticky="snew")
        self.showFrame("quiz")

    def showFrame(self, pageName):
        frame=self.frames[pageName]
        frame.tkraise()


class quiz(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller=controller



        self.label1= Label(self, text="this is quiz")
        self.label1.pack()

        self.submitBtn = Button(self, text="submit", command=self.submitBtnClicked)
        self.submitBtn.pack()

    def submitBtnClicked(self):
        self.controller.showFrame("quiz1")




class quiz1(Frame):
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.controller=controller

        self.label1= Label(self, text="this is quiz1")
        self.label1.pack()

        self.submitBtn = Button(self, text="submit", command=self.submitBtnClicked)
        self.submitBtn.pack()

    def submitBtnClicked(self):
       self.controller.showFrame("quiz")

app = secondaryActivity()
app.mainloop()

2 个答案:

答案 0 :(得分:1)

没有理由在循环中创建一堆类或框架。只需将您的问题和答案存储在一个简单的数组中,然后根据该数组中的数据刷新显示。您只需要一个框架就可以一次显示一个问题。

首先创建一个类来保存您的问题和其他数据。我假设这是一个多项选择测验,所以你需要一个选择列表和一个指向哪个是正确的指针。

class Question():
    def __init__(self, question, choices, answer_index):
        self.question = question
        self.choices=choices
        self.answer_index = answer_index

接下来,定义您的问题:

questions = (
    Question("Question 1?", choices=("A. ...", "B. ...", "C. ...", answer_index=0)),
    Question("Question 2?", choices=("A. ...", "B. ...", "C. ...", answer_index=3)),
    Question("Question 3?", choices=("A. ...", "B. ...", "C. ...", answer_index=2)),
    Question("Question 4?", choices=("A. ...", "B. ...", "C. ...", answer_index=2)),
}

最后,创建一个给定索引的函数将呈现该问题:

def show_question(index):
    """Show the question at the given index in 'questionFrame'"""
    # destroy old widgets
    # (you can skip if all questions have the same number of choices)
    for child in questionFrame.children():
        child.destroy()

    question - questions[index]
    # create widgets for current question
    # (or configure existing widgets if all questions have the same
    #  number of choices)
    question_label = tk.Label(questionFrame, text=question.question)
    for choice in question.choices:
        radiobutton = tk.Radiobutton(...)

答案 1 :(得分:0)

我个人会用字典来保存我的所有问题和答案。我会使用这本词典来产生每个问题并记录结果。

我已将帧创建移动到主类,然后创建了一个类方法,该方法将使用所需内容更新帧。这只是一种处理方法,如果你愿意,它可以转换为它的类。

然后我创建了一个方法,它将检查并保存每个答案的结果,并在提交的最后一个答案上,它将检查总分并将其显示为弹出消息。

看一下下面的例子:

import tkinter as tk
from tkinter import messagebox

questions_and_answers = {"Question 1":{"question":"What is 1+1","key":"2", "answer":""},
                         "Question 2":{"question":"What is 1+4","key":"5", "answer":""},
                         "Question 3":{"question":"What is 9 \\ 3","key":"3", "answer":""},
                         "Question 4":{"question":"What is 4-2","key":"2", "answer":""}}

list_questions = ["Question 1", "Question 2", "Question 3", "Question 4"]


class secondaryActivity(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self,*args,**kwargs)
        self.container=tk.Frame(self)
        self.container.pack(side="top", fill="both", expand=True)
        self.container.grid_rowconfigure(0, weight=1)
        self.container.grid_columnconfigure(0, weight=1)

        self.label1= tk.Label(self.container, text="Press the start button to begin quiz!")
        self.label1.grid(row=0, column=0)
        self.label2 = tk.Label(self.container, text="")
        self.entry1 = tk.Entry(self.container)

        self.submitBtn = tk.Button(self.container, text="start", command=lambda: self.quiz(self.list_questions[0]))
        self.submitBtn.grid(row=3, column=0)

    def quiz(self, question_name):
        self.label1.config(text=question_name)
        self.label1.grid(row=0, column=0)
        self.label2.grid(row=1, column=0)
        self.label2.config(text=questions_and_answers[question_name]["question"])
        self.entry1.delete(0, "end")
        self.entry1.grid(row=2, column=0)

        self.submitBtn.config(text="Submit", command=lambda x=question_name: self.check_and_continue(x))

    def check_and_continue(self, question_name):
        answer = self.entry1.get().strip()
        correct_answer = questions_and_answers[question_name]["key"]

        if answer == correct_answer:
            messagebox.showinfo("Result", "Correct the answer is {}".format(answer))
            questions_and_answers[question_name]["answer"] = "correct"
        else:
            messagebox.showinfo("Result", "Incorrect the answer is {}".format(correct_answer))
            questions_and_answers[question_name]["answer"] = "incorrect"

        for ndex, name in enumerate(list_questions):
            if name == question_name:
                try:
                    self.quiz(list_questions[(ndex+1)])
                except:
                    x = len(list_questions)
                    y = 0
                    for question in questions_and_answers:
                        if questions_and_answers[question]["answer"] == "correct":
                            y += 1
                    messagebox.showinfo("Quiz Info", "You have completed all of the questions in this quiz.\nFinal score is: {} out of {}".format(y, x))
                    self.label1.config(text="Press the start button to begin quiz!")
                    self.submitBtn.config(text="start", command=lambda: self.quiz(self.list_questions[0]))
                    self.entry1.grid_forget()
                    self.label2.grid_forget()


app = secondaryActivity()
app.mainloop()