2

I am trying to make a simple Magic Eight Ball application just for practice. I am using tkinter and python 3.0. I'm trying to switch frames to the next part of the application but can't get around it. I am just wondering what is wrong with this code as every time I try to correct it, it just comes up with either error "container is not defined" or "PageOne has no attribute 'tk'". I would like to say I am fairly comfortable with tkinter so far and can make basic GUIs that only have one page. However, I just can't seem to work this. Here is the code:

import tkinter as tk

class EightBall(tk.Tk):

        def __init__(self, *args, **kwargs):

                tk.Tk.__init__(self, *args,**kwargs)
                container = tk.Frame(self)

                container.configure(width=500, height=500)
                container.pack()


                self.frames={}

                for F in (StartPage, PageOne):

                        frame = F(container,self)

                        self.frames[F]=frame

                        frame.configure(width=500,height=500)
                        frame.pack()


                self.show_frame(StartPage)


        def show_frame(self,controller):

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



class StartPage(tk.Frame):

        def __init__(self, parent, controller):
            tk.Frame.__init__(self,parent)
            HomeButton=tk.Button(self, text="Press to play",
                                     command=lambda: controller.show_frame(PageOne))
            HomeLabel=tk.Label(self, text="Magic 8 Ball", fg="white",bg="blue")
            HomeLabel.configure(font="Arial 22")
            HomeButton.place(relx=0.5,rely=0.5,anchor="center")
            HomeLabel.place(relx=0.35,y=10)


class PageOne(tk.Frame):

        def __init__(self, parent, controller):
            tk.Frame.__init__(self,parent)
            PageOneLabel=tk.Label(PageOne,text="What is your name?")
            PageOneEntry=Entry(PageOne)
            PageOneButton=tk.Button(PageOne, text="Enter",
                                        command=lambda: controller.show_frame(PageTwo))
            PageOneLabel.place(relx=0.50,rely=0.45)
            PageOneEntry.place(relx=0.50,rely=0.50)
            PageOneButton.place(relx=0.50,rely=0.55)
app=EightBall()
app.mainloop()

What am I doing wrong?

Artemis
  • 2,553
  • 7
  • 21
  • 36
E.SAYB
  • 31
  • 4
  • 1
    Possible duplicate of [Switch between two frames in tkinter](https://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter) – Reblochon Masque Jun 07 '18 at 02:17
  • 1
    I'm fairly confident that the question linked by @ReblochonMasque is where you got most of your code from. The problem however is that you've been making changes that break the working of the code sample. Are you sure you fully understand the code you've started out with? If not, you really should try to because otherwise you will get into many more difficulties. – fhdrsdg Jun 07 '18 at 07:37

1 Answers1

0

Working Code:

import tkinter as tk
class EightBall(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args,**kwargs)
        self.container = tk.Frame(self)
        self.container.pack()
        self.frames={}
        for F in (StartPage, PageOne):
            frame = F(self.container, self)
            self.frames[F]=frame
            frame.configure(width=500, height=500)
            frame.grid(row=0, column=0)
            self.show_frame(StartPage)
    def show_frame(self, controller):
        frame=self.frames[controller]
        frame.tkraise()
class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        HomeButton=tk.Button(self, text="Press to play",
                                 command=lambda: controller.show_frame(PageOne))
        HomeLabel=tk.Label(self, text="Magic 8 Ball", fg="white",bg="blue")
        HomeLabel.configure(font="Arial 22")
        HomeButton.place(relx=0.5,rely=0.5,anchor="center")
        HomeLabel.place(relx=0.35,y=10)
class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        PageOneLabel=tk.Label(self,text="What is your name?")
        PageOneEntry=tk.Entry(self)
        PageOneButton=tk.Button(self, text="Enter",
                                    command=lambda: controller.show_frame(StartPage))
        PageOneLabel.place(relx=0.50,rely=0.45)
        PageOneEntry.place(relx=0.50,rely=0.50)
        PageOneButton.place(relx=0.50,rely=0.55)
app=EightBall() ; app.mainloop()

Fixes:

  • Removed useless configuration in EightBall.__init__

  • Replaced PageTwo with StartPage, since that's its name

  • Replaced container with controller in EightBall.show_frame since that's what's passed

  • Replaced pack() with grid(row=0, column=0) in EightBall.__init__ to place frames ontop of each other

  • Added the tk. before Entry in PageOne.__init__

  • Removed blank lines, coupled the last two, so that the code fitted without scrolling.

Artemis
  • 2,553
  • 7
  • 21
  • 36