import tkinter as tk
from tkinter import ttk, messagebox
import math
class LoanCalculator:
def __init__(self, root):
self.root = root
self.root.title("贷款利息计算器")
self.root.geometry("580x600")
self.root.resizable(False, False)
# 初始化变量
self.loan_amount = tk.StringVar() # 贷款金额
self.annual_rate = tk.StringVar() # 年利率(%)
self.loan_years = tk.StringVar() # 贷款年限
self.result_var = tk.StringVar() # 计算结果
self.recommend_var = tk.StringVar()# 推荐方案
# 创建界面
self.create_widgets()
def create_widgets(self):
# 标题
title_label = ttk.Label(
self.root,
text="贷款利息计算器",
font=("微软雅黑", 16, "bold")
)
title_label.pack(pady=10)
# 输入框架
input_frame = ttk.LabelFrame(self.root, text="贷款信息")
input_frame.pack(padx=20, pady=10, fill="x")
# 贷款金额
ttk.Label(input_frame, text="贷款金额(元):").grid(row=0, column=0, padx=10, pady=8, sticky="w")
amount_entry = ttk.Entry(input_frame, textvariable=self.loan_amount, width=30)
amount_entry.grid(row=0, column=1, padx=10, pady=8)
# 年利率
ttk.Label(input_frame, text="年利率(%):").grid(row=1, column=0, padx=10, pady=8, sticky="w")
rate_entry = ttk.Entry(input_frame, textvariable=self.annual_rate, width=30)
rate_entry.grid(row=1, column=1, padx=10, pady=8)
# 贷款年限
ttk.Label(input_frame, text="贷款年限(年):").grid(row=2, column=0, padx=10, pady=8, sticky="w")
years_entry = ttk.Entry(input_frame, textvariable=self.loan_years, width=30)
years_entry.grid(row=2, column=1, padx=10, pady=8)
# 计算按钮
calc_btn = ttk.Button(
self.root,
text="计算并推荐最优方案",
command=self.calculate_loan
)
calc_btn.pack(pady=10)
# 结果框架
result_frame = ttk.LabelFrame(self.root, text="计算结果")
result_frame.pack(padx=20, pady=5, fill="both", expand=True)
# 结果文本框
self.result_text = tk.Text(result_frame, font=("微软雅黑", 10), wrap=tk.WORD)
scrollbar = ttk.Scrollbar(result_frame, orient="vertical", command=self.result_text.yview)
self.result_text.configure(yscrollcommand=scrollbar.set)
self.result_text.pack(side="left", fill="both", expand=True, padx=(0, 5), pady=5)
scrollbar.pack(side="right", fill="y", pady=5)
# 推荐方案标签
recommend_label = ttk.Label(
self.root,
textvariable=self.recommend_var,
font=("微软雅黑", 11, "bold"),
foreground="#d63031"
)
recommend_label.pack(pady=8)
def validate_inputs(self):
"""验证输入是否合法"""
try:
amount = float(self.loan_amount.get())
rate = float(self.annual_rate.get())
years = int(self.loan_years.get())
if amount <= 0:
messagebox.showerror("错误", "贷款金额必须大于0!")
return None
if rate <= 0 or rate > 100:
messagebox.showerror("错误", "年利率必须在0-100之间!")
return None
if years <= 0 or years > 50:
messagebox.showerror("错误", "贷款年限必须在1-50之间!")
return None
return amount, rate, years
except ValueError:
messagebox.showerror("错误", "请输入有效的数字!")
return None
def calculate_equal_principal_interest(self, principal, annual_rate, years):
"""
计算等额本息还款方式
公式:
月利率 = 年利率 / 12 / 100
月供 = 本金 × 月利率 × (1 + 月利率)^还款月数 / [(1 + 月利率)^还款月数 - 1]
总利息 = 月供 × 还款月数 - 本金
"""
monthly_rate = annual_rate / 12 / 100
months = years * 12
if monthly_rate == 0:
monthly_payment = principal / months
total_interest = 0
else:
monthly_payment = principal * monthly_rate * math.pow(1 + monthly_rate, months) / (math.pow(1 + monthly_rate, months) - 1)
total_interest = monthly_payment * months - principal
return {
"monthly_payment": monthly_payment,
"total_interest": total_interest,
"total_payment": principal + total_interest
}
def calculate_equal_principal(self, principal, annual_rate, years):
"""
计算等额本金还款方式
公式:
月利率 = 年利率 / 12 / 100
每月应还本金 = 本金 / 还款月数
每月应还利息 = 剩余本金 × 月利率
总利息 = (还款月数 + 1) × 本金 × 月利率 / 2
"""
monthly_rate = annual_rate / 12 / 100
months = years * 12
monthly_principal = principal / months
# 计算总利息
total_interest = (months + 1) * principal * monthly_rate / 2
# 首月还款额
first_month_payment = monthly_principal + principal * monthly_rate
# 每月递减金额
monthly_decrease = monthly_principal * monthly_rate
return {
"first_month_payment": first_month_payment,
"monthly_decrease": monthly_decrease,
"total_interest": total_interest,
"total_payment": principal + total_interest
}
def calculate_interest_first_principal_last(self, principal, annual_rate, years):
"""
计算到期还本、按期还息(先息后本)还款方式
公式:
月利率 = 年利率 / 12 / 100
每月还息 = 本金 × 月利率
到期还本 = 本金
总利息 = 本金 × 年利率 × 年限
"""
monthly_rate = annual_rate / 12 / 100
# 每月还息金额
monthly_interest = principal * monthly_rate
# 总利息
total_interest = principal * annual_rate * years / 100
# 总还款金额
total_payment = principal + total_interest
return {
"monthly_interest": monthly_interest,
"final_principal": principal,
"total_interest": total_interest,
"total_payment": total_payment
}
def calculate_loan(self):
"""主计算函数"""
# 清空结果
self.result_text.delete(1.0, tk.END)
self.recommend_var.set("")
# 验证输入
inputs = self.validate_inputs()
if not inputs:
return
principal, annual_rate, years = inputs
months = years * 12
# 计算三种还款方式
eqi_pi = self.calculate_equal_principal_interest(principal, annual_rate, years) # 等额本息
eqi_p = self.calculate_equal_principal(principal, annual_rate, years) # 等额本金
interest_first = self.calculate_interest_first_principal_last(principal, annual_rate, years) # 先息后本
# 构建结果文本
result_text = f"""
【贷款基本信息】
贷款金额:{principal:,.2f} 元
年利率:{annual_rate:.2f} %
贷款年限:{years} 年({months} 个月)
【等额本息还款方案】
每月还款额:{eqi_pi['monthly_payment']:,.2f} 元
总还款金额:{eqi_pi['total_payment']:,.2f} 元
总支付利息:{eqi_pi['total_interest']:,.2f} 元
【等额本金还款方案】
首月还款额:{eqi_p['first_month_payment']:,.2f} 元
每月递减金额:{eqi_p['monthly_decrease']:,.4f} 元
总还款金额:{eqi_p['total_payment']:,.2f} 元
总支付利息:{eqi_p['total_interest']:,.2f} 元
【到期还本、按期还息(先息后本)方案】
每月还息金额:{interest_first['monthly_interest']:,.2f} 元
到期还本金额:{interest_first['final_principal']:,.2f} 元
总还款金额:{interest_first['total_payment']:,.2f} 元
总支付利息:{interest_first['total_interest']:,.2f} 元
【三种方案利息对比】
等额本息利息:{eqi_pi['total_interest']:,.2f} 元
等额本金利息:{eqi_p['total_interest']:,.2f} 元
先息后本利息:{interest_first['total_interest']:,.2f} 元
"""
# 插入结果
self.result_text.insert(tk.END, result_text)
self.result_text.see(tk.END)
# 找出利息最低的方案
interest_dict = {
"等额本金": eqi_p['total_interest'],
"等额本息": eqi_pi['total_interest'],
"到期还本、按期还息": interest_first['total_interest']
}
# 按利息升序排序
sorted_interest = sorted(interest_dict.items(), key=lambda x: x[1])
best_plan = sorted_interest[0][0]
best_interest = sorted_interest[0][1]
second_interest = sorted_interest[1][1]
interest_diff = second_interest - best_interest
# 推荐最优方案
self.recommend_var.set(f"✅ 推荐方案:{best_plan}(总利息最低,为 {best_interest:,.2f} 元,比第二名少付 {interest_diff:,.2f} 元)")
if __name__ == "__main__":
root = tk.Tk()
app = LoanCalculator(root)
root.mainloop()
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
