Search code examples
pythontkinterpositionframepack

How can I choose coordinate of tkinter frame?


I am experimenting with Tkinter, as I was trying to place tree frames. Two frames must be placed side by side: the red one and the blue one. (see frame image). I place this two frames with this istructions:

redFrame = tk.Frame(master=masterFrame, bg='red')
redFrame.pack_propagate(0)
redFrame.pack(fill='both', side='left', expand='True')

blueFrame = tk.Frame(master=masterFrame, bg='blue')
destFrame.pack_propagate(0)
destFrame.pack(fill='both', side='right', expand='True')

Now I want to put another frame (green) inside the red one, placed on the left side of the main interface:

greenFrame = tk.Frame(master=masterFrame, width=100, height=100, bg='green')
greenFrame.pack_propagate(0)
greenFrame.pack(side='bottom', padx=0, pady=0)

The problem is that I can't choose its position. It still remain in the top side of the window and centered.

If I change the padx parameter nothing change.

If i change the pady parameter, the frame change its Y position. Why this not appened with the X posistion?


Solution

  • Widgets will by default be centered in their allocated space within the container.

    Your code at the moment doesn't work, so I've changed it to this (I think it mimics what you're saying you currently have):

    import tkinter as tk
    
    root = tk.Tk()
    root.geometry("600x400")
    
    redFrame = tk.Frame(root, bg='red')
    redFrame.pack_propagate(0)
    redFrame.pack(fill='both', side='left', expand='True')
    
    blueFrame = tk.Frame(root, bg='blue')
    blueFrame.pack_propagate(0)
    blueFrame.pack(fill='both', side='right', expand='True')
    
    greenFrame = tk.Frame(redFrame, width=100, height=100, bg='green')
    greenFrame.pack_propagate(0)
    greenFrame.pack(side='top', padx=0, pady=0)
    
    root.mainloop()
    

    If you run this code, the greenFrame will appear as your image shows, at the top and centered inside redFrame.

    If you want greenFrame to appear at the top left of redFrame, you can change the anchor point of the frame:

    greenFrame = tk.Frame(redFrame, width=100, height=100, bg='green')
    greenFrame.pack_propagate(0)
    greenFrame.pack(side='top', padx=0, pady=0, anchor='w')
    

    That is because when you do side="top" using pack, the widget gets allocated an entire strip of horizontal space. It gets centered within that space by default:

    Image showing side=top

    If you do side="left", then the widget gets allocated an entire strip of vertical space, and it gets centered in that space by default.

    Image showing side=left

    However in both cases you can change the anchor point, so that your component is placed differently within that allocated spaces.

    This is the code which achieves what (I think) you want:

    import tkinter as tk
    
    root = tk.Tk()
    root.geometry("600x400")
    
    redFrame = tk.Frame(root, bg='red')
    redFrame.pack_propagate(0)
    redFrame.pack(fill='both', side='left', expand='True')
    
    blueFrame = tk.Frame(root, bg='blue')
    blueFrame.pack_propagate(0)
    blueFrame.pack(fill='both', side='right', expand='True')
    
    greenFrame = tk.Frame(redFrame, width=100, height=100, bg='green')
    greenFrame.pack_propagate(0)
    greenFrame.pack(side='top', padx=0, pady=0, anchor='w')
    
    root.mainloop()