pythontkintertkinter-menu

How to get grid to stretch inside containers in tkinter


I am trying to use python to create a program that will control pumps in a device later on and I'm now just trying to understand how to build a GUI using tkinter. I have gotten everything to show up, except that I can't make the buttons stretch with the window and I can't make the text stay in the centre of the window. I think I am very close to getting it to work, but have been stuck on this for a while.

The code is something I found online and has tweaked a bit, which is why I'm stuck since I am actually not a programmer, and I, unfortunately, don't have time to dive deeper into it. Which is why I'm asking for help.

If anyone could give some advice, it's highly appreciated! Thanks in advance.

Here is my code:

    import tkinter as tk
    from tkinter import ttk
    
    fonts =("Verdana", 35)
    
    class application(tk.Tk):
    
        # __init__ function for class tkinterApp
        def __init__(self, *args, **kwargs):
    
            # __init__ function for class Tk
            tk.Tk.__init__(self, *args, **kwargs)
    
            tk.Grid.rowconfigure(self, 0, weight=1)
            tk.Grid.columnconfigure(self, 0, weight=1)
    
            # creating a container
            container = tk.Frame(self)
            container.grid(row = 0,column = 0, sticky = "nsew")
    
            # initializing frames to an empty array
            self.frames = {}
    
            # iterating through a tuple consisting
            # of the different page layouts
            pages = (StartPage, Page1)
            for F in pages:
    
                frame = F(container, self)
    
                # initializing frame of that object from
                # startpage, page1, page2 respectively with
                # for loop
                frame.grid(row = 0, column = 0, sticky ="nsew")
                self.frames[F] = frame
    
            self.show_frame(StartPage)
    
        # to display the current frame passed as
        # parameter
        def show_frame(self, cont):
            frame = self.frames[cont]
            frame.grid(sticky ="nsew")
            frame.tkraise()
    
    # first window frame startpage
    
    class StartPage(tk.Frame):
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)
            self.rowconfigure(1, weight=1)
            self.columnconfigure(0, weight=1)
            self.columnconfigure(1, weight=1)
    
            # label of frame Layout 2
            label = ttk.Label(self, text ="Startpage", font = fonts)
    
            # putting the grid in its place by using
            # grid
            label.grid(row = 0, column = 0, padx = 10, pady = 10,columnspan = 2,sticky = "nsew")
    
            btn1 = ttk.Button(self, text ="Page 1",
            command = lambda : controller.show_frame(Page1))
    
            # putting the button in its place by
            # using grid
            btn1.grid(row = 1, column = 0,sticky = "nsew")
    
            btn2 = ttk.Button(self, text ="Page test",
            command = lambda : controller.show_frame(Page1))
    
            # putting the button in its place by
            # using grid
            btn2.grid(row = 1, column = 1,sticky = "nsew")
    
    # second window frame page1
    class Page1(tk.Frame):
    
        def __init__(self, parent, controller):
    
            tk.Frame.__init__(self, parent)
            self.rowconfigure(1, weight=1)
            self.columnconfigure(0, weight=1)
            self.columnconfigure(1, weight=1)
    
            label = ttk.Label(self, text ="Page 1", font = fonts)
            label.grid(row = 0, column = 0, padx = 10, pady = 10,columnspan = 2,sticky = "nsew")
    
            # button to show frame 2 with text
            # layout2
            btn1 = ttk.Button(self, text ="Back",
            command = lambda : controller.show_frame(StartPage))
    
            # putting the button in its place by
            # using grid
            btn1.grid(row = 1, column = 0,sticky = "nsew")
    
            btn2 = ttk.Button(self, text ="Back 2",
            command = lambda : controller.show_frame(StartPage))
    
            # putting the button in its place by
            # using grid
            btn2.grid(row = 1, column = 1,sticky = "nsew")
    
    # Driver Code
    app = application()
    app.mainloop()
    

Solution

  • You need to call:

    container.rowconfigure(0, weight=1)
    container.columnconfigure(0, weight=1)
    

    Otherwise, the StartPage and Page1 will not take all the space of container.

    To center the labels, you need to add anchor="c" in ttk.Label(...):

    ...
    
    label = ttk.Label(self, text ="Startpage", font=fonts, anchor="c")
    
    ...
    
    label = ttk.Label(self, text ="Page 1", font=fonts, anchor="c")
    
    ...