1

I'm currently working on a project using the Tkinter module in Python. I am using the menu widget and for each command on the menu there is another command associated with it. Each of these commands opens a new frame. I am using the grid geometry manager.

My problem is that I would like the user to be able to switch from frame to frame but when I try doing this, the frames overlap each other instead of switching. How can I get the active frame to hide and then open up a new frame? I don't want to have to iterate through a list of possible frames and tell them all to hide.

Here is the code I've written so far:

import Tkinter as tkinter
root = tkinter.Tk()
root.minsize(400,300)
welcome = tkinter.Frame(root).grid()
label = tkinter.Label(welcome, text="Welcome to my program").grid(row=0, column=3)
button = tkinter.Button(welcome,text="Exit",command=root.destroy).grid(row=3, column=1)
def newFrame():
        newFrame = tkinter.Frame(root).grid()
        newFrame_name = tkinter.Label(newFrame, text="This is another frame").grid()
menu = tkinter.Menu(root)
root.config(menu=menu)

main_menu = tkinter.Menu(menu)
menu.add_cascade(label="Main Menu", menu= main_menu)
main_menu.add_command(label="New Frame", command=newFrame)

#menu.add_command(label="Exit", command=root.destroy, menu= filemenu)


root.mainloop()

When the user selects the New Frame option from the menu, I want the newFrame to replace the welcome frame.

martineau
  • 119,623
  • 25
  • 170
  • 301
jules
  • 63
  • 3
  • 10

1 Answers1

1

If you use place or grid to stack the frames on top of each other you can simply change the stacking order with the lift method.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I've tried that but I keep getting an error saying that the 'NoneType' object has no attribute named 'lift'. Also, will the lift method clear all the other frames that are visible or will it just raise one particular frame of my choosing? – jules Jul 17 '12 at 09:47
  • @juleszero: `lift` will only raise the one frame. As for the NoneType error, simply ask yourself "why is this object set to None?". My guess is you're doing something like this: `frame=Frame(...).grid(...)`, which causes `frame` to be None. Bottom line is, there's a bug in your code that is causing you to call `lift` on a variable that is set to None. Since you haven't posted any of your code it's impossible to get any more specific. – Bryan Oakley Jul 17 '12 at 10:38
  • That's exactly how I've been setting up all my frames! I wasn't aware that it caused the object to be set to 'None'. I've updated my post with my code so hopefully that helps. – jules Jul 17 '12 at 11:45
  • @juleszero: when you call `.pack()` or `.grid()`, those functions return `None`, which is why all your widget references are `None`. Unfortunately, some online tutorials teach you to do it this way, but it's a bad practice. I recommind that you always separate your layout code from your widget creation code. – Bryan Oakley Jul 17 '12 at 12:44
  • Could you please provide me with an example of what you mean by that and possibly some correct tutorials? – jules Jul 17 '12 at 12:58
  • @juleszero: an example is simple, just put the creation of the widget in a separate statement from the layout: `b=Button(...); b.grid(...)`. I almost always clump all of my widget creation code together (or in logical groups), and my layout code together in a separate section. It makes it easier to tweak the layout if all of the `grid` or `pack ` statements are in one place. – Bryan Oakley Jul 17 '12 at 15:02