这段代码实现了一个综合计算器应用程序,它使用Python的Tkinter库创建了一个图形用户界面(GUI)。该计算器包含两个主要功能:普通计算器和贷款计算器。下面是对代码的详细解释:
1. 导入模块
import tkinter as tk
from tkinter import messagebox
from math import sqrt
tkinter
:用于创建GUI应用程序。messagebox
:用于显示消息框。sqrt
:用于计算平方根。
2. 定义计算器应用程序类
class CalcApp:
def __init__(self, root):
self.root = root
self.root.title("综合计算器")
self.mode = tk.StringVar(value="普通计算器")
self.create_menu()
self.norm_frame = tk.Frame(self.root)
self.mort_frame = tk.Frame(self.root)
self.create_norm_calc(self.norm_frame)
self.create_mort_calc(self.mort_frame)
self.norm_frame.grid(row=1, column=0, padx=10, pady=10)
__init__
方法初始化应用程序,设置窗口标题,创建菜单和两个计算器界面(普通计算器和贷款计算器)。
3. 创建菜单
def create_menu(self):
modes = ["普通计算器", "贷款计算器"]
tk.OptionMenu(self.root, self.mode, *modes, command=self.switch_mode).grid(row=0, column=0, padx=10, pady=10)
- 创建一个下拉菜单,用于选择计算器模式(普通计算器或贷款计算器)。
4. 切换模式
def switch_mode(self, mode):
if mode == "普通计算器":
self.mort_frame.grid_forget()
self.norm_frame.grid(row=1, column=0, padx=10, pady=10)
else:
self.norm_frame.grid_forget()
self.mort_frame.grid(row=1, column=0, padx=10, pady=10)
- 根据选择的模式切换不同的界面。
5. 创建普通计算器界面
def create_norm_calc(self, frame):
self.expr = ""
self.res = tk.StringVar()
self.display = tk.Entry(frame, textvariable=self.res, font=('Arial', 20), bd=10, insertwidth=4, width=14, borderwidth=4)
self.display.grid(row=0, column=0, columnspan=4)
btns = [
('7', 1, 0), ('8', 1, 1), ('9', 1, 2), ('/', 1, 3),
('4', 2, 0), ('5', 2, 1), ('6', 2, 2), ('*', 2, 3),
('1', 3, 0), ('2', 3, 1), ('3', 3, 2), ('-', 3, 3),
('0', 4, 0), ('.', 4, 1), ('+', 4, 2), ('=', 4, 3),
('C', 5, 0), ('←', 5, 1), ('sqrt', 5, 2), ('%', 5, 3),
('(', 6, 0), (')', 6, 1), ('^', 6, 2), ('1/x', 6, 3)
]
for (text, row, col) in btns:
btn = tk.Button(frame, text=text, padx=20, pady=20, font=('Arial', 18), command=lambda t=text: self.on_btn_click(t))
btn.grid(row=row, column=col, sticky="nsew")
for i in range(7):
frame.grid_rowconfigure(i, weight=1)
for i in range(4):
frame.grid_columnconfigure(i, weight=1)
- 创建普通计算器的界面,包括显示框和按钮。
6. 普通计算器按钮点击事件
def on_btn_click(self, char):
if char == '=':
try:
self.expr = str(eval(self.expr))
except Exception:
self.expr = "Error"
elif char == 'C':
self.expr = ""
elif char == '←':
self.expr = self.expr[:-1]
elif char == 'sqrt':
self.expr += 'sqrt('
elif char == '1/x':
self.expr += '1/('
else:
self.expr += str(char)
self.res.set(self.expr)
- 处理按钮点击事件,更新表达式并显示结果。
7. 创建贷款计算器界面
def create_mort_calc(self, frame):
self.pay_type = tk.StringVar(value="等额本息")
self.years = tk.StringVar()
self.amount = tk.StringVar()
self.rate = tk.StringVar()
self.monthly_pay = tk.StringVar()
self.total_int = tk.StringVar()
self.total_pay = tk.StringVar()
tk.Label(frame, text="还款方式:").grid(row=0, column=0, padx=5, pady=5, sticky='w')
tk.Radiobutton(frame, text="等额本息", variable=self.pay_type, value="等额本息").grid(row=0, column=1)
tk.Radiobutton(frame, text="等额本金", variable=self.pay_type, value="等额本金").grid(row=0, column=2)
tk.Label(frame, text="贷款年限(年):").grid(row=1, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.years).grid(row=1, column=1, columnspan=2)
tk.Label(frame, text="贷款金额(万元):").grid(row=2, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.amount).grid(row=2, column=1, columnspan=2)
tk.Label(frame, text="贷款利率(%):").grid(row=3, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.rate).grid(row=3, column=1, columnspan=2)
tk.Button(frame, text="计算", command=self.calc_mort).grid(row=4, column=0, columnspan=2, pady=10)
tk.Button(frame, text="重置", command=self.reset_mort).grid(row=4, column=2, pady=10)
tk.Label(frame, text="月均还款(元):").grid(row=5, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.monthly_pay, state='readonly').grid(row=5, column=1, columnspan=2)
tk.Label(frame, text="利息总额(元):").grid(row=6, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.total_int, state='readonly').grid(row=6, column=1, columnspan=2)
tk.Label(frame, text="还款总额(元):").grid(row=7, column=0, padx=5, pady=5, sticky='w')
tk.Entry(frame, textvariable=self.total_pay, state='readonly').grid(row=7, column=1, columnspan=2)
- 创建贷款计算器的界面,包括输入框和按钮。
8. 贷款计算器计算逻辑
def calc_mort(self):
try:
yrs = int(self.years.get())
princ = float(self.amount.get()) * 10000
rate_yr = float(self.rate.get()) / 100
months = yrs * 12
rate_mth = rate_yr / 12
if self.pay_type.get() == "等额本息":
m_pay = princ * rate_mth * ((1 + rate_mth) ** months) / (((1 + rate_mth) ** months) - 1)
total_pay = m_pay * months
total_int = total_pay - princ
else:
m_pay = princ / months + (princ * rate_mth)
total_pay = (months + 1) * princ * rate_mth / 2 + princ
total_int = total_pay - princ
self.monthly_pay.set(f"{m_pay:.2f}")
self.total_int.set(f"{total_int:.2f}")
self.total_pay.set(f"{total_pay:.2f}")
except ValueError:
messagebox.showerror("输入错误", "请输入有效的数字")
- 根据用户输入计算贷款的月均还款、利息总额和还款总额。
9. 重置贷款计算器输入和输出
def reset_mort(self):
self.years.set("")
self.amount.set("")
self.rate.set("")
self.monthly_pay.set("")
self.total_int.set("")
self.total_pay.set("")
- 重置贷款计算器的输入和输出。
10. 主程序
if __name__ == "__main__":
root = tk.Tk()
app = CalcApp(root)
root.mainloop()
- 创建Tkinter窗口并运行应用程序。
注意事项
- 该代码在计算贷款时,将贷款金额从万元转换为元,因此在输入贷款金额时,需要输入万元。
- 在计算贷款时,使用了等额本息和等额本金两种还款方式,用户可以通过选择不同的还款方式来计算。
- 在计算贷款时,使用了异常处理来处理用户输入无效的情况。