1

Im having troubles with tkinter frames The folowing code must display labels at left side and there should be more space the button and the label , there is something wrong with my column/row setup. What am i doing wrong?

What is the correct way for a program to display information? 1 global frame with several smaller frames in it? With tkinter when using a menu with page 1 page 2 and page 3 , page 1 has 3 input fields , child of FramePage1 , page 2 has 2 buttons child of FramePage2, page 3 has one big text field child of FramePage3. Is it the correct way to use for changing the pages

#menu tab1 -> command #calls function page1
def page1():
   self.Framepage2.grid_forget()
   self.Framepage1.grid()
   #content of the page

or are there other ways to use different layout style pages?

import tkinter
import tkinter as tk
class sjabloon():
    def __init__(self):
        #make window
        self.win = tk.Tk()
        self.win.geometry("600x600+10+10")
        #make top frame
        self.frame_header = tk.Frame(self.win, background='black', width=600, height=50)
        self.frame_header.grid(column=0, row=0 , columnspan= 10)
        #make body frame
        self.frame_body = tk.Frame(self.win, width=600, height=400)
        self.frame_body.grid(column=0, row=1 , columnspan= 10)
        #button1 select
        tk.Label(self.frame_body, text="Select:").grid(column=0, row=2, stick='W')
        self.button1 = tk.Button(self.frame_body, text="Select")
        self.button1.grid(row=2, column=5, stick='W')
        #button1 select
        tk.Label(self.frame_body, text="Select:").grid(column=0, row=3, stick='W')
        self.button2 = tk.Button(self.frame_body, text="Select")
        self.button2.grid(row=4, column=5, stick='W')
        #button submit
        self.submit = tk.Button(self.frame_body, text="Start")
        self.submit.grid(row=10, column=9, stick='W')
        #make body footer
        self.frame_footer = tk.Frame(self.win, background='yellow', width=600, height=50)
        self.frame_footer.grid(column=0, row=3 , columnspan= 10)


if __name__ == "__main__":
    sjabloon = sjabloon()

1 Answer 1

1

I suggest you to follow this tkinter GUI tutorial, he makes a pretty big app and even if it's not what you exactly looking for, it will help you.

In the part 4, he make a multiple frame architecture in the tkinter GUI.

For switching "pages", i know 2 choices (there's more i think but i don't know them, i'm still a beginner). You can create all the frames inside a window/Frame and raise to the front the one you want (that's in the tutorial part 4) or you can destroy the widgets "Page 1" inside the body frame and create the widgets "Page 2" inside it (obviously in methods/functions to let you switch between the pages).

For your first problem, i'm not sure if i understand your problem, you want more space around your button widget ? if that's what you want, you can use the option padx=(leftPadx,RightPadx) like that :

self.button1.grid(row=2, column=5, stick='W', padx=(50,0))

EDIT : i made a little architecture for you (from what i learn in that tutorial) Basically, you create all the "Page", you add them in the bodyFrame and you raise to the front the one you want. To achieve that, for each "Page", you create a class that inherits tk.Frame and you add an instance of that class in the mainWindow

import tkinter as tk
from tkinter import ttk

LARGE_FONT = ("Verdana 12")
NORM_FONT = "Verdana 10"
SMALL_FONT = ("Verdana 8")
ERROR_404 = "Error 404 : Page not found !"

class sjabloon(tk.Tk):
    def __init__(self, *args, **kwargs):
        #make window        
        tk.Tk.__init__(self, *args, **kwargs)
        self.geometry("600x600+10+10")

        #make top frame
        self.frame_header = tk.Frame(self, background='black', width=600, height=50)
        self.frame_header.grid(column=0, row=0 , columnspan= 10)

        #make body frame
        container = tk.Frame(self, width=600, height=400)
        container.grid(column=0, row=1 , columnspan= 10)

        #list of Pages
        self.frames = {}

        #everytime you create a "Page", you add it there
        for F in (StartPage, HomePage):
            frame = F(container, self)
            self.frames[F] = frame     
            frame.grid(row=1, column = 0, sticky="nsew", columnspan= 10)

        self.show_page("StartPage")


        #make body footer
        self.frame_footer = tk.Frame(self, background='yellow', width=600, height=50)
        self.frame_footer.grid(column=0, row=3 , columnspan= 10)



    def show_page(self, page_name):
        """
            let us use the NAME of the class to display(the function show_frame
            use directly the class).
            when we use the classe name, we can put our classes in defferent
            files
        """
        for F in self.frames:
            if F.__name__ == page_name:
                self.show_frame(F)
                return
        print(ERROR_404)


    def show_frame(self, cont):
        """raise to the front the frame we want

            :param cont: the frame
        """
        frame = self.frames[cont]
        frame.tkraise()



class HomePage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        #button1 select
        tk.Label(self, text="Select:").grid(column=0, row=2, stick='W')
        self.button1 = tk.Button(self, text="Select")
        self.button1.grid(row=2, column=5, stick='W', padx=(50,0))
        #button1 select
        tk.Label(self, text="Select:").grid(column=0, row=3, stick='W')
        self.button2 = tk.Button(self, text="Select")
        self.button2.grid(row=4, column=5, stick='W', padx=(50,0))
        #button submit
        self.submit = tk.Button(self, text="Start")
        self.submit.grid(row=10, column=9, stick='W')


class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        label = tk.Label(self, text="""ALPHA application.
        use at your own risk. There is no promise
        of warranty""", font=LARGE_FONT)
        label.pack(pady=10, padx=10)

        button1 = ttk.Button(self, text="Agree",
                            command=lambda: controller.show_page("HomePage"))
        button1.pack()

        button2 = ttk.Button(self, text="Disagree",
                            command=controller.destroy)
        button2.pack()



if __name__ == "__main__":
    sjabloon = sjabloon()
    sjabloon.mainloop()
Sign up to request clarification or add additional context in comments.

5 Comments

After that, you can basically build anything that's not too complicated by adding some page when you need it. You can put the buttons to navigate through the pages in your header, (each buttons execute the callback show_Page)
Nice work from you , i'll try to take take some pieces of it and play around with it . In the first class you set class sjabloon(tk.Tk): why did you use that tk.Tk in there? you do the same for the HomePage class
@ Sébastien S. Forgot the put in my last post , lots of thanks to you and sorry for the late response. Can you explain the 'controller' var u use? You call that in button1 in class startpage bug i dont understand what it is referring to. , u use it in init but i dont understand why.
glad it helped ! 1. you create a class which is a tkinter window, so you should inherit your class from the class tkinter window (class Tk). you should not create an instance of a tkinter window in your class like you did in your constructor of sjabloon (and btw, i did not see it back then, but it's a standards to upper case the first letter of a class name, you really should do it)
2. the controller var means the main window(Sjlabloon). When i instanciate a page, i put 2 parameters, the frame that my page will be in AND the main window. It's really usefull, for example, for switching page, all my page can use the Sjabloon public method "show_page". I called it controller because it was called like that in the tutorial (personnaly i would called it "main view" or something like that)

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.