Search code examples
pythontkinterframeframes

Orient and Organize Tkinter frames


I would like to know how to create frames that align to grid and fill space I dictate. I am having a hard time grasping frame orientation within a window. I can make all the frames, but if I pack, they are all on left or in a line/on right. I played with that and decided on grid(). I set the window geometry and then use grid for frames. However, my frames all collapse down to the top left or my initial frame fills the whole space and the other two squeeze in around the edges. I tried using window geometry of 1024 and 768, then allotting width and height for my first frame to be 512 and 384. Then setting the next two to have width 512 and height of 192. I also saw in other articles that weight is important and tried iterations of code to alter that, but was unsuccessful. Rowspan and columnspan helped me get the background colors to appear so that I could visualize the space being occupied by each.

Anyway, code is below:

class twinsplay:
    
    def __init__(self):
        #Window
        self.window =  Tk()
        self.window.geometry('1024x768')
        self.window.grid_rowconfigure(1, weight=1)
        self.window.grid_columnconfigure(1, weight=1)
        
        #window title
        self.window.title('Live Feed')
        
        #frames and labels
        self.frame_left = Frame(self.window, background='magenta')
        self.frame_left.grid(row=0, column=0, padx=5, pady=5, rowspan=3, columnspan=3, sticky=NSEW)
        self.label_left = Label(self.frame_left, text = 'Weather Data', justify=LEFT)
        self.label_left.grid(row=0,column=0, sticky=NSEW)
        
        self.frame_tr = Frame(self.window, background='green')
        self.frame_tr.grid(row=0, column=3, padx=5, pady=5, rowspan=3, columnspan=2, sticky=NSEW)
        self.label_tr = Label(self.frame_tr, text = 'Solar Data', justify = RIGHT)
        self.label_tr.grid(row=0, column=512, sticky=NSEW)
        
        self.frame_br = Frame(self.window, background='yellow')
        self.frame_br.grid(padx=5, pady=5, rowspan=2, columnspan=2, sticky=NSEW)
        self.label_br = Label(self.frame_br, text = 'News', justify = RIGHT)
        self.label_br.grid(row=0, column=512, sticky=NSEW)
        
        #main
        self.window.mainloop()
    ```

Solution

  • I don't know if I understand your problem.

    Your frames use full size inside window but elements inside frames are collapsed. You may need to use grid_rowconfigure/grid_columnconfigure also with frame_left, frame_tr, frame_br to resize elements in grid inside frames.

    I move elements to rows an columns 0 because empty rows/columns have no size and there is no sense to put in column 512

    from tkinter import *
    
    class twinsplay:
        
        def __init__(self):
            self.window =  Tk()
            self.window.geometry('1024x768')
            
            self.window.grid_rowconfigure(0, weight=1)
            self.window.grid_columnconfigure(0, weight=1)
    
            #window title
            self.window.title('Live Feed')
    
    
            #frames and labels
            self.frame_left = Frame(self.window, background='magenta')
            self.frame_left.grid(row=0, column=0, padx=5, pady=5, sticky=NSEW)
    
    
            self.label_left = Label(self.frame_left, text = 'Weather Data', justify=LEFT, bg='red')
            self.label_left.grid(row=0,column=0, sticky=NSEW)
    
            self.frame_left.grid_rowconfigure(0, weight=1)
            self.frame_left.grid_columnconfigure(0, weight=1)
    
            # ---
            
            
            self.frame_tr = Frame(self.window, background='green')
            self.frame_tr.grid(row=0, column=1, padx=5, pady=5, sticky=NSEW)
            
            self.label_tr = Label(self.frame_tr, text = 'Solar Data', justify = RIGHT, bg='green')
            self.label_tr.grid(row=0, column=0, sticky=NSEW)
    
            self.frame_tr.grid_rowconfigure(0, weight=1)
            self.frame_tr.grid_columnconfigure(0, weight=1)
    
            # ---
            
            self.frame_br = Frame(self.window, background='yellow')
            self.frame_br.grid(row=1, column=0, padx=5, pady=5, columnspan=2, sticky=NSEW)
            
            self.label_br = Label(self.frame_br, text = 'News', justify = RIGHT, bg='yellow')
            self.label_br.grid(row=0, column=0, sticky=NSEW)
    
            self.frame_br.grid_rowconfigure(0, weight=1)
            self.frame_br.grid_columnconfigure(0, weight=1)
    
            #main
            self.window.mainloop()
            
    twinsplay()        
    

    enter image description here


    But if you try to do something different then maybe you have to use grid_rowconfigure/grid_columnconfigure with other rows/columns - you can use it many times with different rows/columns.


    EDIT:

    enter image description here

    from tkinter import *
    
    class twinsplay:
        
        def __init__(self):
            self.window =  Tk()
            self.window.geometry('1024x768')
            
            # left and right column will use the same size
            self.window.grid_columnconfigure(0, weight=1)
            self.window.grid_columnconfigure(1, weight=1)
            
            # top and bottom rows will use the same size
            self.window.grid_rowconfigure(0, weight=1)
            self.window.grid_rowconfigure(1, weight=1)
                    
            #window title
            self.window.title('Live Feed')
    
            #frames and labels
            
            # frame will use 2 rows 
            self.frame_left = Frame(self.window, background='magenta')
            self.frame_left.grid(row=0, column=0, padx=5, pady=5, sticky=NSEW, rowspan=2)
    
    
            self.label_left = Label(self.frame_left, text = 'Weather Data', justify=LEFT, bg='red')
            self.label_left.grid(row=0,column=0, sticky=NSEW)
    
            self.frame_left.grid_rowconfigure(0, weight=1)
            self.frame_left.grid_columnconfigure(0, weight=1)
    
            # ---
            
            self.frame_tr = Frame(self.window, background='green')
            self.frame_tr.grid(row=0, column=1, padx=5, pady=5, sticky=NSEW)
            
            self.label_tr = Label(self.frame_tr, text = 'Solar Data', justify = RIGHT, bg='green')
            self.label_tr.grid(row=0, column=0, sticky=NSEW)
    
            self.frame_tr.grid_rowconfigure(0, weight=1)
            self.frame_tr.grid_columnconfigure(0, weight=1)
    
            # ---
            
            self.frame_br = Frame(self.window, background='yellow')
            self.frame_br.grid(row=1, column=1, padx=5, pady=5, columnspan=2, sticky=NSEW)
            
            self.label_br = Label(self.frame_br, text = 'News', justify = RIGHT, bg='yellow')
            self.label_br.grid(row=0, column=0, sticky=NSEW)
    
            self.frame_br.grid_rowconfigure(0, weight=1)
            self.frame_br.grid_columnconfigure(0, weight=1)
    
            #main
            self.window.mainloop()
            
    twinsplay()