scruffyboy13
scruffyboy13

Reputation: 97

tkinter - How to fix label and check button not lining up?

Below is a part of a code which opens a file and creates a label and check button for every person on the register but when I run the code, the label and check buttons aren't aligned and I don't know why. Can someone help?

screenshot of current results

Code:

x=0
for line in open(register, "r"):
    with open(register,"r") as file:
        all_lines=file.readlines()
    Label(registersuccess,text=all_lines[x]).grid(column=0,row=x)
    Checkbutton(registersuccess,text="Present").grid(column=1,row=x)
    x=x+1

Upvotes: 1

Views: 403

Answers (2)

stovfl
stovfl

Reputation: 15513

Question: Label text and Checkbutton text does not lining up?

Your problem are the new lines \n. By reading from a text file, every line ends with \n. Therefore your text = line becomes text='Boy1\n' which is two lines and does not lining up with the Checkbutton text which is one line.
Result after removed, the \n using .strip(): enter image description here


Reference:

  • str.strip([chars])

    Return a copy of the string with the leading and trailing characters removed, the chars argument defaults to removing whitespace.

  • str.rstrip([chars])

    Return a copy of the string with trailing characters removed, the chars argument defaults to removing whitespace

  • enumerate(iterable, start=0)

    Returns a tuple containing a count and the values obtained from iterating over iterable.

  • 7.2. Reading and Writing Files

    It is good practice to use the with keyword when dealing with file objects. The advantage is that the file is properly closed after its suite finishes.


import tkinter as tk
import io

# Simulate the contents of the file 'register'
register = """Boy 1
Girl 1
Boy 2
Girl 2
Boy 3
Girl 3
"""


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        
        # with open(register) as fh:
        with io.StringIO(register) as fh:
            for row, line in enumerate(fh):
                text = line.strip()
                
                tk.Label(self, text=text).grid(row=row, column=0)
                tk.Checkbutton(self, text="Present").grid(row=row, column=1)


if __name__ == "__main__":
    App().mainloop()

Tested with Python: 3.5 - 'TclVersion': 8.6 'TkVersion': 8.6

Upvotes: 1

martineau
martineau

Reputation: 123453

The alignment problem is because the lines in file all end with a newline character, which you can remove by using the string rstrip() method. You're also doing things very inefficiently since you reading the entire file in each time through the inner-most for loop.

Here's how to avoid that as well as fix the problem:

from tkinter import *

register = 'register.txt'
root = Tk()
registersuccess = Frame(root)
registersuccess.pack()

with open(register, "r") as file:
    for row, line in enumerate(file):
        line = line.rstrip()  # Remove trailing newline.
        Label(registersuccess, text=line).grid(column=0, row=row)
        Checkbutton(registersuccess, text='Present').grid(column=1, row=row)

Button(registersuccess, text='Submit').grid(column=2, row=row+1)

root.mainloop()

Result:

screenshot of result

Upvotes: 1

Related Questions