0

My program is a maths quiz. It takes questions by randomly selecting them from a text file (questiontest.txt). I want my code to do generate a quiz more than one time, and it does do this except for the display. Even when the actual questions and required answers have changed, the question that is displayed doesn't change from the first questions selected, therefore not showing the new questions.

This is the code:

from tkinter import *
import tkinter as tk
import random

title_font= ("Microsoft Jhenghei UI Light", 35)


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

        container = tk.Frame(self)

        container.pack(side="top", fill="both", expand= True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.title("Maths Revision App")
        self.geometry("800x500")
        self.frames = {}
        for F in (StartPage, q1, q2, q3, q4, q5, resultPage):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(StartPage)

    def show_frame(self, cont):
        #funtion that displays different pages

        frame = self.frames[cont]
        frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)

        self.configure(bg ="white")
        lbl = tk.Label(self, text="Welcome!", font=title_font, bg="white", fg="#004d99")
        lbl.place(x=30, y=20)        
        rtbtn=tk.Button(self, text="Start", height=3, width=15, fg="white", bg="#004d99", command=lambda:[controller.show_frame(q1)])
        rtbtn.place(x=350, y=200)    

class q1(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.configure(bg="white")        
        lbl=Label(self, text="Question 1", font=("Microsoft Jhenghei UI Light", 35), bg="white", fg="#004d99")
        lbl.place(x=30, y=20)
        txt=Text(self, height=5, width=70)
        txt.config(state="normal")
        txt.insert(tk.INSERT,qlist[0][0])
        txt.config(state="disabled")
        txt.place(x=35,y=125)
        ans=Entry(self)
        ans.place(x=650, y=350,height=25)
        nxt=Button(self, text="Next", height=3, width=15, fg="white", bg="#004d99", command=lambda:[checkAns(ans.get(), 0),controller.show_frame(q2)])
        nxt.place(x=650, y=400)


class q2(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.configure(bg="white")        
        lbl=Label(self, text="Question 2", font=("Microsoft Jhenghei UI Light", 35), bg="white", fg="#004d99")
        lbl.place(x=30, y=20)
        txt=Text(self, height=5, width=70)
        txt.config(state="normal")
        txt.insert(tk.INSERT,qlist[1][0])
        txt.config(state="disabled")
        txt.place(x=35,y=125)
        ans=Entry(self)
        ans.place(x=650, y=350,height=25)
        nxt=Button(self, text="Next", height=3, width=15, fg="white", bg="#004d99", command=lambda:[checkAns(ans.get(), 1),controller.show_frame(q3)])
        nxt.place(x=650, y=400)


class q3(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.configure(bg="white")        
        lbl=Label(self, text="Question 3", font=("Microsoft Jhenghei UI Light", 35), bg="white", fg="#004d99")
        lbl.place(x=30, y=20)
        txt=Text(self, height=5, width=70)
        txt.config(state="normal")
        txt.insert(tk.INSERT,qlist[2][0])
        txt.config(state="disabled")
        txt.place(x=35,y=125)
        ans=Entry(self)
        ans.place(x=650, y=350,height=25)
        nxt=Button(self, text="Next", height=3, width=15, fg="white", bg="#004d99", command=lambda:[checkAns(ans.get(), 2),controller.show_frame(q4)])
        nxt.place(x=650, y=400)


class q4(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.configure(bg="white")        
        lbl=Label(self, text="Question 4", font=("Microsoft Jhenghei UI Light", 35), bg="white", fg="#004d99")
        lbl.place(x=30, y=20)
        txt=Text(self, height=5, width=70)
        txt.config(state="normal")
        txt.insert(tk.INSERT,qlist[3][0])
        txt.config(state="disabled")
        txt.place(x=35,y=125)
        ans=Entry(self)
        ans.place(x=650, y=350,height=25)
        nxt=Button(self, text="Next", height=3, width=15, fg="white", bg="#004d99", command=lambda:[checkAns(ans.get(), 3),controller.show_frame(q5)])
        nxt.place(x=650, y=400)


class q5(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.configure(bg="white")        
        lbl=Label(self, text="Question 5", font=("Microsoft Jhenghei UI Light", 35), bg="white", fg="#004d99")
        lbl.place(x=30, y=20)
        txt=Text(self, height=5, width=70)
        txt.config(state="normal")
        txt.insert(tk.INSERT,qlist[4][0])
        txt.config(state="disabled")
        txt.place(x=35,y=125)
        ans=Entry(self)
        ans.place(x=650, y=350,height=25)
        nxt=Button(self, text="End Test", height=3, width=15, fg="white", bg="#004d99", command=lambda:[checkAns(ans.get(), 4),resultReview(),controller.show_frame(resultPage)])
        nxt.place(x=650, y=400)


class resultPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.configure(bg="white")        
        lbl=Label(self, text="Results", font=("Microsoft Jhenghei UI Light", 35), bg="white", fg="#004d99")
        lbl.place(x=30, y=20)
        nxt=Button(self, text="Restart", height=3, width=15, fg="white", bg="#004d99", command=lambda:[refresh(),controller.show_frame(StartPage)])
        nxt.place(x=650, y=400)



qlist=0
def getQuestions():
    global qlist
    qlist=[0,0,0,0,0]
    noschosen=[]
    with open("questiontest.txt","r") as f:
        lines=f.read().strip().split("\n")
    i=0
    while i<len(qlist):
        chosen=False
        n=random.randint(1,20)
        while n in noschosen:
            n=random.randint(1,20)
        qline=2*n-1
        noschosen.append(n)
        qlist[i]=(lines[qline],lines[qline+1])
        i=i+1
getQuestions()

results=[]
def checkAns(ans, questionAns):
    global results
    if ans == qlist[questionAns][1]:
        results.append("right")
    else:
        results.append("wrong")
correct=0
def resultReview():
    global correct
    for index in range (0,len(results)):
        if results[index]=="right":
            correct=correct+1
    print (results)
    print ("You got", correct,"out of 5 right")

def refresh():
    global qlist,results, correct
    qlist=0
    results=[]
    correct=0
    getQuestions()



print (qlist)
app = MathsApp()
app.mainloop()

The txt file contains:

.
Question1
Answer1
Question2
Answer2
Question3
Answer3
Question4
Answer4
Question5
Answer5
Question6
Answer6
Question7
Answer7
Question8
Answer8
Question9
Answer9
Question10
Answer10
Question11
Answer11
Question12
Answer12
Question13
Answer13
Question14
Answer14
Question15
Answer15
Question16
Answer16
Question17
Answer17
Question18
Answer18
Question19
Answer19
Question20
Answer20

The answer to the questions are "AnswerX", X is the question number in the text box. Is there a way to change the text that shows up in the text boxes? Or is there no other choice but to close and immediately reopen the program? If so how would I do this?

Tolu
  • 3
  • 2
  • Maybe you can create another function for your q1, q2,.. classes "show_question", which will not only raise the frame but also update the text of question field and clear and answer field. You can assign the widgets of q# classes as class variables(`self.txt`) and update them(`q1.txt.config`) from "show_question" function. – Kamal Feb 08 '19 at 06:17
  • *"Is it possible for a widget (ie text) to change"*: Yes, but this is not your mistake. How often do you expect a `def __init__(...` to be called? You change the `qlist` but didn't update the `txt=Text(...`. Read [Is this bad programming practice in tkinter?](https://stackoverflow.com/questions/25454065/is-this-bad-programming-practice-in-tkinter) and [Switch between two frames in tkinter](https://stackoverflow.com/a/49325719/7414759) – stovfl Feb 08 '19 at 14:39

0 Answers0