Bart1986
Bart1986

Reputation: 31

Python frames tkinter

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()

Upvotes: 1

Views: 1380

Answers (1)

Sébastien S.
Sébastien S.

Reputation: 176

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()

Upvotes: 1

Related Questions