34

I have quite a simple question here. In Tkinter (python), I was wondering who to use a button to go to different pages of my application, e.g a register page, and a login page. I am aware that GUI does not have 'pages' like websites do, I've seen a few different ways, but what is the best way to make links to different pages?

0

3 Answers 3

58

Make each page a frame. Then, all your buttons need to do is hide whatever is visible, then make the desired frame visible.

A simple method to do this is to stack the frames on top of each other (this is one time when place makes sense) and then ,lift() the frame you want to be visible. This technique works best when all pages are the same size; in fact, it requires that you explicitly set the size of containing frame.

The following is a contrived example. This isn't the only way to solve the problem, just proof that it's not a particularly hard problem to solve:

import Tkinter as tk

class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class Page1(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="This is page 1")
       label.pack(side="top", fill="both", expand=True)

class Page2(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="This is page 2")
       label.pack(side="top", fill="both", expand=True)

class Page3(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = tk.Label(self, text="This is page 3")
       label.pack(side="top", fill="both", expand=True)

class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = Page1(self)
        p2 = Page2(self)
        p3 = Page3(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p3.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        b1 = tk.Button(buttonframe, text="Page 1", command=p1.show)
        b2 = tk.Button(buttonframe, text="Page 2", command=p2.show)
        b3 = tk.Button(buttonframe, text="Page 3", command=p3.show)

        b1.pack(side="left")
        b2.pack(side="left")
        b3.pack(side="left")

        p1.show()

if __name__ == "__main__":
    root = tk.Tk()
    main = MainView(root)
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("400x400")
    root.mainloop()
Sign up to request clarification or add additional context in comments.

10 Comments

than you so much, exactly what i was after!
@CasparWylie: All this example means is that this whole example is one block of text. You can divide it into as many files as you want -- that has nothing to do with the solution. Each "page" could easily be its own module.
@BryanOakley, wouldn't it be better to use notebook for things like this? tkdocs.com/tutorial/complex.html#notebook
@user3885927: as with most usability questions, "that depends". This question wasn't about what's best, but simply how to switch between pages. You could use a notebook, yes, or you can use this technique to create your own custom notebook. For example, if you had 100 pages, you could create a notebook that uses a listbox for the list of pages, rather than try to squeeze a bunch of tabs across the top of the widget.
@AleksandarBeat: yes, of course. It might be a bit more cumbersome, but it's all just code.
|
7

Could you do something like this?

import tkinter

def page1():
    page2text.pack_forget()
    page1text.pack()

def page2():
    page1text.pack_forget()
    page2text.pack()

window = tkinter.Tk()

page1btn = tkinter.Button(window, text="Page 1", command=page1)
page2btn = tkinter.Button(window, text="Page 2", command=page2)

page1text = tkinter.Label(window, text="This is page 1")
page2text = tkinter.Label(window, text="This is page 2")

page1btn.pack()
page2btn.pack()
page1text.pack()

It seems a lot simpler to me.

2 Comments

@ResheilAgarwal Then you could make a function that would take the page to be hidden as the parameter.
Simpler if number of pages is 2. Not so simple if number of pages is 27.
-1
import tkinter as tk
root=tk.Tk()
root.geometry("360x360")

frame=tk.Frame(root,bg='lightblue')
frame.place(relx=0.2,rely=0.2,relheight=0.6,relwidth=0.6)

def page1():
    label=tk.Label(frame,text='this is the page1')
    label.place(relx=0.3,rely=0.4)

def page2():
    label=tk.Label(frame,text='this is the page2')
    label.place(relx=0.3,rely=0.4)

def page3():
    label=tk.Label(frame,text='this is the page3')
    label.place(relx=0.3,rely=0.4)

bt=tk.Button(root,text='page1',command=page1)
bt.grid(column=0,row=0)

bt1=tk.Button(root,text='page2',command=page2)
bt1.grid(row=0,column=1)

bt2=tk.Button(root,text='page3',command=page3)
bt2.grid(row=0,column=2)

root.mainloop()`

1 Comment

Please add an explanation to your code: What does it do, how does it work, how does it solve OPs problem, and what makes it different from the existing answers. Code only answers can lead to cargo cult programming, and you risk getting downvotes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.