afg229
afg229

Reputation: 53

How do you align labels and entry boxes in a GUI program?

I am trying to create a simple GUI program with Python, but I am having trouble aligning the labels of my program so that the first letter of each word lines up with one another. I tried to use anchor="nw" and anchor="w", but these did not seem to do the trick. I am also having a hard time getting the entry boxes to align with each other. My code as well as the expected GUI are attached. If anyone has suggestions, please let me know.

import tkinter

class Loan:
    def __init__(self):
        #Create main Window
        self.main_window = tkinter.Tk()
        self.main_window.title("Loan Calculator")

        #Create the six frames
        self.intRate_frame = tkinter.Frame(self.main_window)
        self.numYears_frame = tkinter.Frame(self.main_window)
        self.loanAmount_frame = tkinter.Frame(self.main_window)
        self.monthlyPayment_frame = tkinter.Frame(self.main_window)
        self.totalPayment_frame = tkinter.Frame(self.main_window)
        self.button_frame = tkinter.Frame(self.main_window)

        # Create and pack the widgets for interest rate
        self.intRate_label = tkinter.Label(self.intRate_frame, \
                text='Annual Interest Rate', anchor="w")
        self.intRate_entry = tkinter.Entry(self.intRate_frame, \
                                 width=20)
        self.intRate_label.pack(side='left')
        self.intRate_entry.pack(side='left')

        #Create and pack the widgets for number of years
        self.numYears_label = tkinter.Label(self.numYears_frame, \
                text='Number of Years', anchor = "w")
        self.numYears_entry = tkinter.Entry(self.numYears_frame, \
                                 width=20)
        self.numYears_label.pack(side='left')
        self.numYears_entry.pack(side='left')


        #Create and pack the widgets for loan Amount
        self.loanAmount_label = tkinter.Label(self.loanAmount_frame, \
                text='Loan Amount', anchor = "nw")
        self.loanAmount_entry = tkinter.Entry(self.loanAmount_frame, \
                                 width=20)
        self.loanAmount_label.pack(side='left')
        self.loanAmount_entry.pack(side='left')

        #Create and pack the widgets for monthly payment
        self.result_label = tkinter.Label(self.monthlyPayment_frame, \
                text='Monthly Payment', anchor="w")
        self.monthlyPayment = tkinter.StringVar() # To update avg_label
        self.monthlyPayment_label = tkinter.Label(self.monthlyPayment_frame, \
                            textvariable=self.monthlyPayment)
        self.result_label.pack(side='left')
        self.monthlyPayment_label.pack(side='left')

        #Create and pack the widgets for total payment
        self.result2_label = tkinter.Label(self.totalPayment_frame, \
                text='Total Payment', anchor="w")
        self.totalPayment = tkinter.StringVar() # To update avg_label
        self.totalPayment_label = tkinter.Label(self.totalPayment_frame, \
                            textvariable=self.totalPayment)
        self.result2_label.pack(side='left')
        self.totalPayment_label.pack(side='left')

        #Create and pack the widgets for the button widgets
        self.compute_button = tkinter.Button(self.button_frame, \
                             text='Compute Payment', command=self.calc)
        self.compute_button.pack(side='left')

        self.intRate_frame.pack()
        self.numYears_frame.pack()
        self.loanAmount_frame.pack()
        self.monthlyPayment_frame.pack()
        self.totalPayment_frame.pack()
        self.button_frame.pack()

        tkinter.mainloop()

    def calc(self):
        #Get 
        self.intRate = float(self.intRate_entry.get())
        self.numYears = float(self.numYears_entry.get())
        self.loanAmount = float(self.loanAmount_entry.get())
        #Calculations
        monthlyIntRate = self.intRate / 1200   
        monthlyPayment = self.loanAmount * monthlyIntRate/(1 - (1 / (1 +     [enter image description here][1]monthlyIntRate) ** (self.numYears * 12))) 
        totalPayment = self.monthlyPayment * self.numYears * 12 #calculates the total payment

        self.monthlyPayment.set(self.monthlyPayment)
        self.totalPayment.set(self.totalPayment)


loan1 = Loan()

Expected GUI:

Upvotes: 1

Views: 4404

Answers (3)

Andath
Andath

Reputation: 22714

The main problem originates from the frames you used: they are never packed. So pack them and set this option: fill='both'.

You also did mistakes when, sometimes, you pack two widgets of the same frame to left instead of setting one of them to the left and the other to the right.

You also need to use the justify='right' for the text to show in the right inside each entry widget.

Here is your code (need to be cleaned) with the demo:

import tkinter

class Loan:
    def __init__(self):
        #Create main Window
        self.main_window = tkinter.Tk()
        self.main_window.title("Loan Calculator")

        #Create the six frames
        self.intRate_frame = tkinter.Frame(self.main_window)
        self.intRate_frame.pack()
        self.numYears_frame = tkinter.Frame(self.main_window)
        self.numYears_frame.pack(fill='both')
        self.loanAmount_frame = tkinter.Frame(self.main_window)
        self.loanAmount_frame.pack(fill='both')
        self.monthlyPayment_frame = tkinter.Frame(self.main_window)
        self.monthlyPayment_frame.pack(fill='both')
        self.totalPayment_frame = tkinter.Frame(self.main_window)
        self.totalPayment_frame.pack(fill='both')
        self.button_frame = tkinter.Frame(self.main_window)
        self.button_frame.pack(fill='both')

        # Create and pack the widgets for interest rate
        self.intRate_label = tkinter.Label(self.intRate_frame, \
                text='Annual Interest Rate',  anchor="w")
        self.intRate_entry = tkinter.Entry(self.intRate_frame, \
                                 width=20, justify='right')

        self.intRate_label.pack(side='left')
        self.intRate_entry.pack(side='left')

        #Create and pack the widgets for number of years
        self.numYears_label = tkinter.Label(self.numYears_frame, text='Number of Years')
        self.numYears_entry = tkinter.Entry(self.numYears_frame, justify='right')
        self.numYears_label.pack(side='left')
        self.numYears_entry.pack(side='right')


        #Create and pack the widgets for loan Amount
        self.loanAmount_label = tkinter.Label(self.loanAmount_frame, \
                text='Loan Amount', anchor = "nw")
        self.loanAmount_entry = tkinter.Entry(self.loanAmount_frame, \
                                 width=20, justify='right')
        self.loanAmount_label.pack(side='left')
        self.loanAmount_entry.pack(side='right')

        #Create and pack the widgets for monthly payment
        self.result_label = tkinter.Label(self.monthlyPayment_frame, \
                text='Monthly Payment', anchor="w")
        self.monthlyPayment = tkinter.StringVar() 
        self.monthlyPayment_label = tkinter.Label(self.monthlyPayment_frame, \
                            textvariable=self.monthlyPayment)
        self.result_label.pack(side='left')
        self.monthlyPayment_label.pack(side='right')

        #Create and pack the widgets for total payment
        self.result2_label = tkinter.Label(self.totalPayment_frame, \
                text='Total Payment', anchor="w")
        self.totalPayment = tkinter.StringVar() 
        self.totalPayment_label = tkinter.Label(self.totalPayment_frame, \
                            textvariable=self.totalPayment)
        self.result2_label.pack(side='left')
        self.totalPayment_label.pack(side='left')

        #Create and pack the widgets for the button widgets
        self.compute_button = tkinter.Button(self.button_frame, \
                             text='Compute Payment', command=self.calc)
        self.compute_button.pack(side='right')

        self.intRate_frame.pack()
        self.numYears_frame.pack()
        self.loanAmount_frame.pack()
        self.monthlyPayment_frame.pack()
        self.totalPayment_frame.pack()
        self.button_frame.pack()

        tkinter.mainloop()

    def calc(self):
        #Get 
        self.intRate = float(self.intRate_entry.get())
        self.numYears = float(self.numYears_entry.get())
        self.loanAmount = float(self.loanAmount_entry.get())
        #Calculations
        monthlyIntRate = self.intRate / 1200   
        monthlyPayment = self.loanAmount * monthlyIntRate/(1 - (1 / (1 +     monthlyIntRate) ** (self.numYears * 12))) 
        totalPayment = self.monthlyPayment * self.numYears * 12 #calculates the total payment

        self.monthlyPayment.set(self.monthlyPayment)
        self.totalPayment.set(self.totalPayment)


loan1 = Loan()

Demo (on Ubuntu):

enter image description here

Upvotes: 0

ellie ff1493
ellie ff1493

Reputation: 125

try packing the frames, or not using them. frames are used to group widgets together. you can also use "anchor" with "side"

import tkinter

class Loan:
    def __init__(self):
        #Create main Window
        self.main_window = tkinter.Tk()
        self.main_window.title("Loan Calculator")

        #make a frame for alignment
        self.entry_frame =  tkinter.Frame(self.main_window)
        self.entry_frame.pack(side="right", anchor="n")

        # Create and pack the widgets for interest rate
        self.intRate_label = tkinter.Label(self.main_window, \
                text='Annual Interest Rate', anchor="w")
        self.intRate_entry = tkinter.Entry(self.entry_frame, \
                                 width=20)
        self.intRate_label.pack(side="top", anchor="w")
        self.intRate_entry.pack(side="top", anchor="w", pady=1)

        #Create and pack the widgets for number of years
        self.numYears_label = tkinter.Label(self.main_window, \
                text='Number of Years', anchor = "w")
        self.numYears_entry = tkinter.Entry(self.entry_frame, \
                                 width=20)
        self.numYears_label.pack(side="top", anchor="w")
        self.numYears_entry.pack(side="top", anchor="w",  pady=1)


        #Create and pack the widgets for loan Amount
        self.loanAmount_label = tkinter.Label(self.main_window, \
                text='Loan Amount', anchor = "nw")
        self.loanAmount_entry = tkinter.Entry(self.entry_frame, \
                                 width=20)
        self.loanAmount_label.pack(side="top", anchor="w")
        self.loanAmount_entry.pack(side="top", anchor="w", pady=1)

        #pack the frame
        #self.entry_frame.pack(side="top", anchor="e")

        #Create and pack the widgets for monthly payment
        self.result_label = tkinter.Label(self.main_window, \
                text='Monthly Payment', anchor="w")
        self.monthlyPayment = tkinter.StringVar() # To update avg_label
        self.monthlyPayment_label = tkinter.Label(self.main_window, \
                            textvariable=self.monthlyPayment)
        self.result_label.pack(side="top", anchor="w")
        self.monthlyPayment_label.pack(side="top", anchor="w")

        #Create and pack the widgets for total payment
        self.result2_label = tkinter.Label(self.main_window, \
                text='Total Payment', anchor="w")
        self.totalPayment = tkinter.StringVar() # To update avg_label
        self.totalPayment_label = tkinter.Label(self.main_window, \
                            textvariable=self.totalPayment)
        self.result2_label.pack(side="top", anchor="w")
        self.totalPayment_label.pack(side="top", anchor="w")

        #Create and pack the widgets for the button widgets
        self.compute_button = tkinter.Button(self.main_window, \
                             text='Compute Payment', command=self.calc)
        self.compute_button.pack(side="top")

        tkinter.mainloop()

    def calc(self):
        #Get 
        self.intRate = float(self.intRate_entry.get())
        self.numYears = float(self.numYears_entry.get())
        self.loanAmount = float(self.loanAmount_entry.get())
        #Calculations
        monthlyIntRate = self.intRate / 1200   
        monthlyPayment = self.loanAmount * monthlyIntRate/(1 - (1 / (1) ** (self.numYears * 12))) 
        totalPayment = self.monthlyPayment * self.numYears * 12 #calculates the total payment

        self.monthlyPayment.set(self.monthlyPayment)
        self.totalPayment.set(self.totalPayment)


loan1 = Loan()

I added a frame for all the entrys so they all group together

Upvotes: 2

kavko
kavko

Reputation: 2831

You should try packing your widgets with grid() function...it's a lot more flexible for positioning

import tkinter
from tkinter import *

class Loan:
    def __init__(self):
        #Create main Window
        self.main_window = tkinter.Tk()
        self.main_window.title("Loan Calculator")

        #Create the six frames
        self.intRate_frame = tkinter.Frame(self.main_window)
        self.numYears_frame = tkinter.Frame(self.main_window)
        self.loanAmount_frame = tkinter.Frame(self.main_window)
        self.monthlyPayment_frame = tkinter.Frame(self.main_window)
        self.totalPayment_frame = tkinter.Frame(self.main_window)
        self.button_frame = tkinter.Frame(self.main_window)

        # Create and pack the widgets for interest rate
        self.intRate_label = tkinter.Label(self.intRate_frame, \
                text='Annual Interest Rate', anchor="w")
        self.intRate_entry = tkinter.Entry(self.intRate_frame, \
                                 width=20)
        self.intRate_label.grid(row=0, column=0, sticky=W)
        self.intRate_entry.grid(row=0, column=1, sticky=W)

        #Create and pack the widgets for number of years
        self.numYears_label = tkinter.Label(self.numYears_frame, \
                text='Number of Years', anchor = "w")
        self.numYears_entry = tkinter.Entry(self.numYears_frame, \
                                 width=20)
        self.numYears_label.grid(row=1, column=0, sticky=W)
        self.numYears_entry.grid(row=1, column=1, sticky=W)


        #Create and pack the widgets for loan Amount
        self.loanAmount_label = tkinter.Label(self.loanAmount_frame, \
                text='Loan Amount', anchor = "nw")
        self.loanAmount_entry = tkinter.Entry(self.loanAmount_frame, \
                                 width=20)
        self.loanAmount_label.grid(row=2, column=0, sticky=W)
        self.loanAmount_entry.grid(row=2, column=1, sticky=W)

        #Create and pack the widgets for monthly payment
        self.result_label = tkinter.Label(self.monthlyPayment_frame, \
                text='Monthly Payment', anchor="w")
        self.monthlyPayment = tkinter.StringVar() # To update avg_label
        self.monthlyPayment_label = tkinter.Label(self.monthlyPayment_frame, \
                            textvariable=self.monthlyPayment)
        self.result_label.grid(row=3, column=0, sticky=W)
        self.monthlyPayment_label.grid(row=3, column=1, sticky=W)

        #Create and pack the widgets for total payment
        self.result2_label = tkinter.Label(self.totalPayment_frame, \
                text='Total Payment', anchor="w")
        self.totalPayment = tkinter.StringVar() # To update avg_label
        self.totalPayment_label = tkinter.Label(self.totalPayment_frame, \
                            textvariable=self.totalPayment)
        self.result2_label.grid(row=4, column=0, sticky=W)
        self.totalPayment_label.grid(row=1, column=1, sticky=W)

        #Create and pack the widgets for the button widgets
        self.compute_button = tkinter.Button(self.button_frame, \
                             text='Compute Payment', command=self.calc)
        self.compute_button.pack(side='left')

        self.intRate_frame.grid(row=1, column=1, sticky=W)
        self.numYears_frame.grid(row=2, column=1, sticky=W)
        self.loanAmount_frame.grid(row=3, column=1, sticky=W)
        self.monthlyPayment_frame.grid(row=4, column=1, sticky=W)
        self.totalPayment_frame.grid(row=5, column=1, sticky=W)
        self.button_frame.grid(row=6, column=1, sticky=W)

        tkinter.mainloop()

    def calc(self):
        #Get 
        self.intRate = float(self.intRate_entry.get())
        self.numYears = float(self.numYears_entry.get())
        self.loanAmount = float(self.loanAmount_entry.get())
        #Calculations
        monthlyIntRate = self.intRate / 1200
        monthlyPayment = self.loanAmount * monthlyIntRate/(1 - (1 / (1 +     [enter image description here][1]monthlyIntRate) ** (self.numYears * 12))) 
        totalPayment = self.monthlyPayment * self.numYears * 12 #calculates the total payment
        self.monthlyPayment.set(self.monthlyPayment)
        self.totalPayment.set(self.totalPayment)


loan1 = Loan()

enter image description here

Upvotes: 1

Related Questions