minigregg
minigregg

Reputation: 15

Python tkinter, making a quiz with randomly generated questions that reset after each submit

My problem is that I'm trying to make a math quiz in tkinter which asks for a name, and then picks a question using the randint function. The person inputs an answer, clicks submit and the app responds to whether it was right or wrong.

The problem arises in that I then want the program to after it has been submitted clear the question and answer and come up with new ones 3 times over (each time adding to a score which is then shown at the end), however I can't seem to find a way to easily do this; I've currently been trying a while loop but it isn't working.

So my question is how would I make that part of the code loop 3 times over asking a different question each time?

My code thus far:

    from tkinter import*;from random import randint

class Tk_app(Frame):
    def __init__(self, root):
        super(Tk_app, self).__init__(root);self.grid();self.createElements()
    def nameElements(self):
        self.NmLbl = Label(self, text="Name:").grid(row=0)
        self.Name = Entry(self);self.Name.grid(row=0, column=1);self.score = int(0)
    def createElements(self):
        Frame.grid_forget(self)
        self.QNum = randint(1, 2)
        self.QEnt = Entry(self);self.QEnt.grid(row=1, column=1)
        if(self.QNum == 1):
            self.QLbl = Label(self, text="What is the air speed velocity of a flying swallow?").grid(row=1)
            self.a = "African or European?"
        elif(self.QNum == 2):
            self.QLbl = Label(self, text="What is your quest?").grid(row=1)
            self.a = "To find the holy grail."
        else:
            self.QLbl = Label(self, text="What is your favourite colour?").grid(row=1)
            self.a = "Green"
        def submit(self):
            FinNam = self.Name.get()
            Ans = self.QEnt.get()
            if(Ans == self.a):
                AnsLbl = Label(self, text = "Well done you got it right, "+FinNam).grid(row=2, column=1)
                self.score+=1
            else:
                AnsLbl = Label(self, text = "Sorry not this time, "+FinNam+" The answer was " + self.a).grid(row=2, column=1)
        self.SBut = Button(self, text="submit", command=lambda:submit(self)).grid(row=2)


root = Tk();root.title("Monty Questions")
app = Tk_app.nameElements(root)
fin = int(0)
while(fin<3):
    fin+=1
    app2 = Tk_app.createElements(root)

root.mainloop()

Upvotes: 0

Views: 1857

Answers (1)

DenverCoder9
DenverCoder9

Reputation: 495

You don't want to have a while loop outside of your app class. When the program is running, it should have called root.mainloop() before the user interacts with it at all, and stay that way until it is finished. The general structure of this code is not correct.

In Tkinter I would only have this outside of the class definition:

root = Tk()
root.title("Monty Questions")
app = Tk_app()
root.mainloop()

And then you set up all of your tk widgets and whatnot in init:

class Tk_app(Frame):
    def __init__(self, root):
        Frame.__init__(root);
        self.grid();
        self.createElements()
        self.nameElements()

etc.

Finally, if you just define submit() as a member function of Tk_app instead of as a nested function definition like you have it, you don't need to use a lambda function to pass self. Just do:

class Tk_app():

    ... __init__ and other things...

    def createElements(self):
        ... some code ...
        self.SBut = Button(self, text="submit", command=self.submit ).grid(row=2)

    def submit(self, Event):
        ... submit code ...

The Event is necessary because not only will submit be passed self, as all member functions are, it also gets passed the event that triggered its call.

This might not get you all the way but will hopefully help structure your code in a way that will allow Tkinter to work properly. Check out examples, especially this one, to see how to structure your code. Explore that site and you should get an idea of the vibe of Tkinter.

Upvotes: 1

Related Questions