Home > Blockchain >  tkinter how to align widgets to the right independently of the length of widgets to the left?
tkinter how to align widgets to the right independently of the length of widgets to the left?

Time:02-18

I would like to align the entry widgets to the right, independently of the width of the labels to the left. I.d. the width of the titles should not matter. The entry widgets should align no matter what the width of the titles are.

enter image description here

Here is my code:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title('test')
root.geometry("500x800")
        
# main frame
main_frame = tk.Frame(root)
main_frame.pack(expand=1, fill='both')

# the message
title = tk.Label(main_frame, text="title 1", bg='white')
title.pack(padx=8, pady=8, fill='x')

foo1_frame = tk.Frame(main_frame)
foo1_frame.pack(padx=8, pady=8, fill='x')

foo1_label = tk.Label(foo1_frame, text="short title foo1")
foo1_label.grid(row=0, column=0)

foo1_entry_box = tk.Entry(foo1_frame, width=10)
foo1_entry_box.grid(row=0, column=2, sticky='e') #sticky does nothing in this case

foo2_frame = tk.Frame(main_frame)
foo2_frame.pack(padx=8, pady=8, fill='x')

foo2_label = tk.Label(foo2_frame, text="loooooooooooonger title foo2")
foo2_label.grid(row=1, column=0)

foo2_entry_box = tk.Entry(foo2_frame, width=10)
foo2_entry_box.grid(row=1, column=2)

root.mainloop()

I have tried using sticky="e" but nothing changes. I don't want to use pack(side='right') because it will look messy/ugly if the window width increases.

CodePudding user response:

The reason sticky = 'e' does not work in this case is because you have not used weight. If you add a weight to the column on the left or right (or both), your problem should be solved.

What is weight?

The default weight for any row or column is 0. If you don't give a row or column any weight, it will just take the required space to accommodate the widgets inside. But if you give the column a weight, you are asking the column to take up as much space as possible.

Intuition: Think of the available space in a frame like a rectangular elastic sheet. By adding the desired weights to different rows and columns, you can proportionately make the sheet expand in the right areas.

Adding weights to rows and columns:

<containter-widget>.grid_columnconfigure(<column number>, weight = <whole number>)

<containter-widget>.grid_rowconfigure(<row number>, weight = <whole number>)

Run this code to understand weights better:

from tkinter import *

root = Tk()

#Gridding root column-wise
root.grid_columnconfigure(0, weight = 2)
root.grid_columnconfigure(1, weight = 1)

#Gridding root row-wise
root.grid_rowconfigure(0, weight = 1)

frame_left = Frame(root, bg = "blue")
frame_right = Frame(root, bg = "green")

frame_left.grid(row = 0, column = 0, sticky = NSEW)
frame_right.grid(row = 0, column = 1, sticky = NSEW)

root.mainloop()

Try tweaking the values of the weights and see what changes happen.

CodePudding user response:

You must permit to column 0 of frames to fill the frame size: with a foo1_frame.columnconfigure(0, weight=1)

root = tk.Tk()
root.title('test')
root.geometry("500x800")

# main frame
main_frame = tk.Frame(root)
main_frame.pack(expand=1, fill='both')

# the message
title = tk.Label(main_frame, text="title 1", bg='white')
title.pack(padx=8, pady=8, fill='x')

foo1_frame = tk.Frame(main_frame)
foo1_frame.pack(padx=8, pady=8, fill='x')
foo1_frame.columnconfigure(0, weight=1) # expand column 0

foo1_label = tk.Label(foo1_frame, text="short title foo1")
foo1_label.grid(row=0, column=0, sticky='w')  # sticky='w'

foo1_entry_box = tk.Entry(foo1_frame, width=10)
foo1_entry_box.grid(row=0, column=2, sticky='e')  # sticky='e'

foo2_frame = tk.Frame(main_frame)
foo2_frame.pack(padx=8, pady=8, fill='x')
foo2_frame.columnconfigure(0, weight=1) # expand column 0

foo2_label = tk.Label(foo2_frame, text="loooooooooooonger title foo2")
foo2_label.grid(row=1, column=0, sticky='w')  # sticky='w'

foo2_entry_box = tk.Entry(foo2_frame, width=10)
foo2_entry_box.grid(row=1, column=2, sticky='e')  # sticky='e'

root.mainloop()

CodePudding user response:

I came with a bit different answer, hope it's works for you, here is the code:

import tkinter as tk
from tkinter import ttk

root = tk.Tk()
root.title('test')
root.geometry("500x800")
        
# main frame
# main_frame = tk.Frame(root)
# main_frame.pack(expand=1, fill='both')

# the message
title = tk.Label(root, text="title 1", bg='white')
title.place(relx = 0.0, rely=0.01, relwidth = 1.0)

# foo1_frame = tk.Frame(root)
# foo1_frame.pack(padx=8, pady=8, fill='x')

foo1_label = tk.Label(root, text="short title foo1")
foo1_label.place(relx = 0.1, rely = 0.05)

foo1_entry_box = tk.Entry(root, width=10)
foo1_entry_box.place(relx = 0.7, rely = 0.05) #sticky does nothing in this case

# foo2_frame = tk.Frame(root)
# foo2_frame.pack(padx=8, pady=8, fill='x')

foo2_label = tk.Label(root, text="loooooooooooonger title foo2")
foo2_label.place(relx = 0.1, rely = 0.1)

foo2_entry_box = tk.Entry(root, width=10)
foo2_entry_box.place(relx = 0.7, rely = 0.1)

root.mainloop()
  • Related