Search code examples
pythontkinter

Problem displaying multiple grids in Tkinter


I am trying to create a Tkinter GUI with multiple pages, each displaying different components made of different widgets. I'm having trouble working with grids from different objects.

from tkinter import *
import tkinter as tk


class MainWindow(tk.Tk):

    def __init__(self):
        super().__init__()

        MainFrame(self)
#EndClass

class MainFrame(tk.Frame):
    """ My pages manager, which will contain pages and manage how to change them """
    def __init__(self, root):
        super().__init__(root)

        Page()

        MainFrame.mainloop(self)
#EndClass

class Lab(tk.Frame):
    """ Some element like a button with label, for exemple """
    def __init__(self):
        super().__init__()

        #Would be in fact more than just one element
        tk.Label(self, text="AAA", font="Arial 30 bold", bg="red").grid()
#EndClass

class Page(tk.Frame):
    """ One page of the application """
    def __init__(self):
        super().__init__()

        Component().grid(row=0, column=0)
#EndClass

class Component(tk.Frame):
    """ Functional component that could be called in various pages """
    def __init__(self):
        super().__init__()

        #tk.Label(self, text="Label 1", font="Arial 30 bold", bg="red").grid(row=0, column=0, sticky="nswe")
        Lab().grid(row=0, column=0, sticky="nswe")
        tk.Label(self, text="Label 2", font="Arial 30 bold", bg="blue").grid(row=0, column=1, sticky="nswe")
        tk.Label(self, text="Label 3", font="Arial 30 bold", bg="blue").grid(row=1, column=0, sticky="nswe")
        tk.Label(self, text="Label 4", font="Arial 30 bold", bg="red").grid(row=1, column=1, sticky="nswe")
#EndClass

MainWindow()

I would like each pages to have their own grid, in which I could place my components in. Similarly, I'd like to place elements in components grid.

I tried many changes in my previous code, but can't display at the same time both the Lab object and the labels.


Solution

  • It is better to specify the master of widgets, otherwise they will be created as children of the root window.

    Also you forget to call layout function on instances of MainFrame(), Page() and Component().

    Below is the modified code:

    import tkinter as tk
    
    class MainWindow(tk.Tk):
    
        def __init__(self):
            super().__init__()
    
            # specify master
            MainFrame(self).grid()  # called .grid()
    #EndClass
    
    class MainFrame(tk.Frame):
        """ My pages manager, which will contain pages and manage how to change them """
        def __init__(self, master):
            super().__init__(master)
    
            # specify master
            Page(self).grid()  # called .grid()
    
            #MainFrame.mainloop(self)
    #EndClass
    
    class Page(tk.Frame):
        """ One page of the application """
        def __init__(self, master):
            super().__init__(master)
    
            Component(self).grid()  # called .grid()
    #EndClass
    
    class Component(tk.Frame):
        """ Functional component that could be called in various pages """
        def __init__(self, master):
            super().__init__(master)
    
            #tk.Label(self, text="Label 1", font="Arial 30 bold", bg="red").grid(row=0, column=0, sticky="nswe")
            Lab(self).grid(row=0, column=0, sticky="nswe")
            tk.Label(self, text="Label 2", font="Arial 30 bold", bg="blue").grid(row=0, column=1, sticky="nswe")
            tk.Label(self, text="Label 3", font="Arial 30 bold", bg="blue").grid(row=1, column=0, sticky="nswe")
            tk.Label(self, text="Label 4", font="Arial 30 bold", bg="red").grid(row=1, column=1, sticky="nswe")
    #EndClass
    
    class Lab(tk.Frame):
        """ Some element like a button with label, for example """
        def __init__(self, master):
            super().__init__(master)
    
            #Would be in fact more than just one element
            tk.Label(self, text="AAA", font="Arial 30 bold", bg="red").grid()
    #EndClass
    
    MainWindow().mainloop()
    

    Result:

    enter image description here