Search code examples
pythontkinterframes

How to set up multiple frames


This is a simple math game which is currently in progress. The loop starts off in mainGame() which then proceeds to mainMenu(). I am trying to create 2 frames; mframe and gframe in order to .destroy() the frames later on, essentially clearing the previous interface for the next one (similar to changing pages).

error:

Label(gframe, textvariable=self.question_var).pack() #gframe stands for game frame NameError: name 'gframe' is not defined

from tkinter import *
from random import randint

root = Tk()
mframe = Frame(root).pack()
gframe = Frame(root).pack()
frame.pack()
start = True

class mainMenu:
    def __init__(self):
        gframe.destroy() #gets rid of previous interface
        title = Label(mframe, text = "main menu").pack() #mfame stands for menu frame

class mainGame:
    def __init__(self):
        if start == False:
            mframe.destroy() #gets rid of previous interface

        #question
        self.question_var = StringVar()
        Label(gframe, textvariable=self.question_var).pack() #gframe stands for game frame

        #answer
        self.user_answer_var = StringVar()
        entry = Entry(gframe, textvariable=self.user_answer_var)
        entry.pack()
        submit = Button(gframe, text = "submit", command = self.check_answer).pack()

        #response output
        self.response_var = StringVar()
        self.count = 0
        self.score = 0
        Label(gframe, textvariable=self.response_var).pack()

        #starts loop
        self.ask_question()
        root.mainloop()

    def ask_question(self):
        if self.count == 1: 
            self.endGame()
        num1 = randint(1, 10)
        num2 = randint(1, 10)
        self.question_var.set("What is "+str(num1)+" + " +str(num2)+"?")
        self.true_answer = num1 + num2
        #print(self.true_answer) #testing purposes

    def check_answer(self):
        self.count += 1
        user_answer = self.user_answer_var.get()
        #print(user_answer) #testing purposes
        if int(user_answer) == self.true_answer:
            text = "Good job"
            self.score += 1
        else:
            text = "Oh no"
        self.response_var.set(text)

        #clear answer for next loop
        self.user_answer_var.set("")
        self.ask_question()

    def endGame(self):
        print("endGame")
        mainMenu()


mainGame()

Solution

  • As said in the comments above, the pack() method returns None. What you need to do is first create the two frames and assign them to variables, then pack them later. This way, the variables still point to the frame instances and not None.

    You should change;

    root = Tk()
    mframe = Frame(root).pack()
    gframe = Frame(root).pack()
    frame.pack()
    start = True
    

    to;

    root = Tk()
    mframe = Frame(root)
    gframe = Frame(root)
    mframe.pack()
    gframe.pack()
    start = True