Reputation: 53
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
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):
Upvotes: 0
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
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()
Upvotes: 1