Search code examples
pythontkintergrid-layout

Tkinter: maintaining button distance when resizing window


I am switching the layout manager for my tkinter GUI. I was using place instead of grid because it was easier for me in the first place, altough I knew it would not be very compatible. Now I noticed that while using the GUI on another screen resolution.

My example program can you find under the text together with my desired layout. I have configured my grid with rowconfigure() and columnconfigure(). One of my problems now is, that if I resize my window, all of my buttons do not have the same size. I think it is because of the number of rows which have to be distributed on the whole window. Is this just how you grid works or can I set something like a "maxpadding"? My second problem is, when my buttons are much higher than my labels on the right side, all of my labels get a very big padding to each other. How can I avoid that? The only thing I could imagine would be adding padding rows.

import tkinter as tk
from tkinter import ttk


root = tk.Tk()
root.title("GUI-TEST")
root.geometry("1200x600")
#root.resizable(height=False, width=False)

 
#frame = tk.Frame(root)


root.rowconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
root.rowconfigure(2, weight=1)
root.rowconfigure(3, weight=1)
root.rowconfigure(4, weight=1)
root.rowconfigure(5, weight=1)
root.rowconfigure(6, weight=1)
root.rowconfigure(7, weight=1)
root.rowconfigure(8, weight=1)
root.rowconfigure(9, weight=1)
root.rowconfigure(10, weight=1)
root.rowconfigure(11, weight=1)
root.rowconfigure(12, weight=1)
root.rowconfigure(13, weight=1)
root.rowconfigure(14, weight=1)

#configure column size
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.columnconfigure(2, weight=1)
root.columnconfigure(3, weight=1)
root.columnconfigure(4, weight=1)
root.columnconfigure(5, weight=1)

#Creating Labels
label1 = tk.Label(root, text="Label1")
label2 = tk.Label(root, text="Label2")
label3 = tk.Label(root, text="Label3")
label4 = tk.Label(root, text="Label4")
label5 = tk.Label(root, text="Label5")
label6 = tk.Label(root, text="Label6")
label7 = tk.Label(root, text="Label7")
label8 = tk.Label(root, text="Label8")
label9 = tk.Label(root, text="Label9")
label10 = tk.Label(root, text="Label10")
label11 = tk.Label(root, text="Label11")
label12 = tk.Label(root, text="Label12")
label13 = tk.Label(root, text="Label13")
label14 = tk.Label(root, text="Label14")
label15 = tk.Label(root, text="Label15")


#Creating Buttons
button1 = tk.Button(root, text="Button1")
button2 = tk.Button(root, text="Button2")
button3 = tk.Button(root, text="Button3")
button4 = tk.Button(root, text="Button4")


#Layouting
#Layouting Labels
label2.grid(column=1, row=2, sticky=tk.W, padx = 50)
label3.grid(column=1, row=4, sticky=tk.W, padx = 50)
label4.grid(column=1, row=5, sticky=tk.W, padx = 50)
label5.grid(column=1, row=6, sticky=tk.W, padx = 50)
label6.grid(column=1, row=7, sticky=tk.W, padx = 50)
label7.grid(column=1, row=8, sticky=tk.W, padx = 50)
label8.grid(column=1, row=9, sticky=tk.W, padx = 50)
label9.grid(column=1, row=10, sticky=tk.W, padx = 50)
label10.grid(column=1, row=3, sticky=tk.W, padx = 50, pady= 5)
label11.grid(column=1, row=11, sticky=tk.W, padx = 50)
label12.grid(column=1, row=12, sticky=tk.W, padx = 50)
label13.grid(column=1, row=13, sticky=tk.W, padx = 50)
label14.grid(column=0, row=0, sticky=tk.SW, padx=50, pady=0)
label15.grid(column=0, row=1, sticky=tk.W, padx=50, pady=0, rowspan=1)

#Layouting Buttins
button1.grid(column=0, row=2, sticky=tk.W, padx=50, pady= 10)
button2.grid(column=0, row= 3, sticky=tk.W, padx=50, pady= 10)
button3.grid(column=0, row= 4, sticky=tk.W, padx=50, pady= 10)
button4.grid(column=0, row= 5, sticky=tk.W, padx=50, pady= 10)

root.mainloop()

example_code

layout


Solution

  • Based on your image, I would suggest that you divide the window into two logical sections: a column of buttons on the left and a grid of labels and buttons on the right.

    In the following example I use a loop to create the grid, so that the example doesn't get too long. A loop isn't required. Also, I didn't set the weights of rows and columns because it's not clear what you want the behavior to be.

    The important think to understand is that you can use frames to isolate groups of widgets, so that one group doesn't affect the layout of another.

    import tkinter as tk
    
    root = tk.Tk()
    button_frame = tk.Frame(root)
    grid_frame = tk.Frame(root)
    
    button_frame.pack(side="left", fill="y")
    grid_frame.pack(side="right", fill="both", expand=True)
    
    button1 = tk.Button(button_frame, text="Button1")
    button2 = tk.Button(button_frame, text="Button2")
    button3 = tk.Button(button_frame, text="Button3")
    button4 = tk.Button(button_frame, text="Button4")
    button5 = tk.Button(button_frame, text="Button4")
    
    button1.pack(side="top", fill="x")
    button2.pack(side="top", fill="x")
    button3.pack(side="top", fill="x")
    button4.pack(side="top", fill="x")
    button5.pack(side="top", fill="x")
    
    
    widgets = {}
    for row in range(1, 16):
        label = tk.Label(grid_frame, text=f"Label{row}")
        button = tk.Button(grid_frame, text="Button")
        label.grid(row=row, column=0)
        button.grid(row=row, column=1, sticky="ew")
    
        widgets[row,0] = label
        widgets[row,1] = button
    
        if row == 1 or row == 14:
            button = tk.Button(grid_frame, text="Button")
            button.grid(row=row, column=2, sticky="ew")
            widgets[row,2] = button
    
    tk.mainloop()
    

    screenshot