Align text with checkbox in tkinter

Question:

I’m trying to align the text with the checkboxes.

test image

Reading from a list in a text file but only the last checkbox align with the text.

import tkinter as tk

root = tk.Tk()
root.geometry("200x300") 
root.title("Test")

with open("test.txt", "r") as file:
    lines = file.readlines()

checkboxes = []
for line in lines:
    checkboxes.append(tk.IntVar())

for i, line in enumerate(lines):
    c = tk.Checkbutton(root, text=line, variable=checkboxes[i])
    c.pack()

root.mainloop()

test.txt:

Yellow
Blue
Red
White
Black
Orange

Guessing it has something to do with line breaks in the text file. What can I do to fix it?

Asked By: Jonken

||

Answers:

There are trailing newline ("n") characters at the end of the items except the last one.

You can use file.read().splitlines() instead to get rid of those newline characters:

with open("test.txt", "r") as file:
    #lines = file.readlines()
    lines = file.read().splitlines()
Answered By: acw1668

The problem is that you’re calling pack and not giving it any options, so it’s using all of the default options, including the one that centered the widget at the top of the available space. The lines will all be aligned down the middle.

It’s not clear exactly what you expect, but one solution is to add anchor='w' when calling pack (and I personally think it’s also good to always explicitly state the side):

c.pack(side="top", anchor="w")

screenshot using the anchor option

The packer allocates all of one side of the available space, and the anchor attribute tells the packer how to align the widget in the allocated space. The values are points on a compass (‘n’, ‘s’, ‘e’, ‘w’) and ‘c’ for center.

If you want the checkboxes aligned to the left but in the center of the window you’ll have to do some extra work. For example, you can pack empty frames to the left and right to take up all extra space.

Add the following before the loop that creates the checkbuttons:

left_padding = tk.Frame(root)
right_padding = tk.Frame(root)
left_padding.pack(side="left", expand=True)
right_padding.pack(side="right", expand=True)

screenshot showing padding

Answered By: Bryan Oakley