Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TKInter widgets having different width even after setting same width

I am trying to build a small window in tkinter, but I observed that different widgets take on different widths even when set with the same width. Here's the output that I can see on running the code:

output

The black widget in first row is an Entry widget declared as below (width=30):

entry=Entry(root,width=30,font=('arial',14,'bold'),bd=0,bg='black',fg='white')
entry.grid(row=0,column=0,padx=0,pady=0,ipadx=0,ipady=0,columnspan=10)

The colorful widgets in second row are Label(s) widgets defined as below (width=3 * 10 widgets = 30):

label=Label(root,width=3,font=('arial',14,'bold'),bg=<different_colors>)
label.grid(row=1,column=<increasing columns>,padx=0,pady=0ipadx=0ipady=0)

The purple widget in the third row is again a Label widget defined as below (width=30):

biglabel=(root,width=30,font=('arial',14,'bold'),bg='purple')
biglabel.grid(row=2,column=0,padx=0,pady=0ipadx=0ipady=0,columnspan=10)

As per the widths mentioned, shouldn't all 3 rows be of same width? But as seen in the output image, all 3 rows are of different width.

Questions:

  1. Can someone please explain the reason for this behavior?
  2. How to make different widgets to follow the grids throughout the app/what to use instead of width to make them of the same size deterministically? As I need to add widgets based on what is typed in the entry and don't want it to have different sizes. Right now the window expands to accommodate the second row when that row is added after typing something in the entry. Interactive output can be seen by executing my code online here: https://replit.com/@KCKotak/TKinter-experiment#main.py

Full code example to test:

from tkinter import *

root=Tk()

def add_text_label(r=0,c=0,bgcolor='white'):
    text_label=Label(root, width=3, font=('arial',14,'bold'), bg=bgcolor)
    text_label.grid(row=r,column=c,padx=0,pady=0,ipadx=0,ipady=0)

root.geometry('-15-35')
root.title('experiment')
root.config(bg='white')

# first row: black entry as seen in output image. **width=30**
text_entry=Entry(root,width=30,font=('arial',14,'bold'),bd=0,bg='black',fg='white')
text_entry.grid(row=0,column=0,padx=0, pady=0,ipadx=0,ipady=0,columnspan=10)

# second row: colorful labels. **width=3 x 10 = 30**
add_text_label(1,0,'red')
add_text_label(1,1,'blue')
add_text_label(1,2,'yellow')
add_text_label(1,3,'orange')
add_text_label(1,4,'green')
add_text_label(1,5,'red')
add_text_label(1,6,'blue')
add_text_label(1,7,'yellow')
add_text_label(1,8,'orange')
add_text_label(1,9,'green')

# third row: purple label. **width=30**
big_label=Label(root, width=30, font=('arial',14,'bold'), bg='purple')
big_label.grid(row=2,column=0,padx=0, pady=0,ipadx=0,ipady=0,columnspan=10)

root.mainloop()
like image 255
KCK Avatar asked May 11 '26 10:05

KCK


1 Answers

Can someone please explain the reason for this behavior?

The short answer is that Entry and Label widgets aren't the same, and may have different values for some of the options. For example, an Entry widget by default has a highlightthickness of 1, but that same option for the Label is likely zero. Also, labels have a padx and pady option that might by default be non-zero. The Entry widget does not have this option.

If you set borderwidth and highlightthickness to 0 (zero) for both the Entry and Label widgets, and also set padx to zero on the Label widgets, then everything may line up. On my machine I still get a 2 pixel difference between the top row and the other two rows. There might be another option I'm forgetting about, or it might just be that an Entry widget is naturally going to be just slightly larger than a Label.

How to make different widgets to follow the grids throughout the app

Use the sticky attribute so that the widgets fill the space allocated to them. You can also use the uniform and weight options on all columns to force them to be exactly the same width. For example:

entry.grid(..., sticky="nsew")
...
label.grid(...,sticky="nsew")
...
biglabel.grid(..., sticky="nsew")
...
root.grid_columnconfigure((0,1,2,3,4,5,6,7,8,9), weight=1, uniform="a")

Note: the specific value for uniform ("a") is irrelevant. The only thing that matters is that all columns use the same value.

like image 108
Bryan Oakley Avatar answered May 13 '26 22:05

Bryan Oakley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!