使用Python创建一个功能完整的Windows风格计算器程序
python实现windows系统计算器程序(含高级功能)
下面我将介绍如何使用python创建一个功能完整的windows风格计算器程序,包含基本运算和高级数学功能。
1. 使用tkinter实现基础计算器
import tkinter as tk
from tkinter import ttk
import math
class calculator:
def __init__(self, root):
self.root = root
self.root.title("高级计算器")
self.root.geometry("400x550")
self.root.resizable(false, false)
# 当前输入和结果
self.current_input = ""
self.previous_input = ""
self.operation = none
self.reset_input = false
# 创建界面
self.create_widgets()
def create_widgets(self):
# 显示框
self.display_frame = ttk.frame(self.root)
self.display_frame.pack(fill=tk.both, padx=10, pady=10)
self.expression_var = tk.stringvar()
self.expression_label = ttk.label(
self.display_frame,
textvariable=self.expression_var,
font=("arial", 18),
anchor=tk.e
)
self.expression_label.pack(fill=tk.both, expand=true)
self.result_var = tk.stringvar()
self.result_label = ttk.label(
self.display_frame,
textvariable=self.result_var,
font=("arial", 28, "bold"),
anchor=tk.e,
foreground="blue"
)
self.result_label.pack(fill=tk.both, expand=true)
# 按钮框架
self.buttons_frame = ttk.frame(self.root)
self.buttons_frame.pack(fill=tk.both, expand=true)
# 按钮布局
buttons = [
("c", 0, 0, "#ff9500", self.clear_all),
("⌫", 0, 1, "#ff9500", self.delete_last),
("÷", 0, 2, "#ff9500", lambda: self.add_operation("/")),
("×", 0, 3, "#ff9500", lambda: self.add_operation("*")),
("7", 1, 0, "#333333", lambda: self.add_number("7")),
("8", 1, 1, "#333333", lambda: self.add_number("8")),
("9", 1, 2, "#333333", lambda: self.add_number("9")),
("-", 1, 3, "#ff9500", lambda: self.add_operation("-")),
("4", 2, 0, "#333333", lambda: self.add_number("4")),
("5", 2, 1, "#333333", lambda: self.add_number("5")),
("6", 2, 2, "#333333", lambda: self.add_number("6")),
("+", 2, 3, "#ff9500", lambda: self.add_operation("+")),
("1", 3, 0, "#333333", lambda: self.add_number("1")),
("2", 3, 1, "#333333", lambda: self.add_number("2")),
("3", 3, 2, "#333333", lambda: self.add_number("3")),
("=", 3, 3, "#4cd964", self.calculate),
("0", 4, 0, "#333333", lambda: self.add_number("0")),
(".", 4, 1, "#333333", lambda: self.add_number(".")),
("(", 4, 2, "#333333", lambda: self.add_number("(")),
(")", 4, 3, "#333333", lambda: self.add_number(")")),
# 高级功能按钮
("sin", 5, 0, "#5856d6", lambda: self.add_function("math.sin(")),
("cos", 5, 1, "#5856d6", lambda: self.add_function("math.cos(")),
("tan", 5, 2, "#5856d6", lambda: self.add_function("math.tan(")),
("log", 5, 3, "#5856d6", lambda: self.add_function("math.log10(")),
("√", 6, 0, "#5856d6", lambda: self.add_function("math.sqrt(")),
("x²", 6, 1, "#5856d6", lambda: self.add_operation("**2")),
("x³", 6, 2, "#5856d6", lambda: self.add_operation("**3")),
("π", 6, 3, "#5856d6", lambda: self.add_number(str(math.pi))),
("e", 7, 0, "#5856d6", lambda: self.add_number(str(math.e))),
("x^y", 7, 1, "#5856d6", lambda: self.add_operation("**")),
("(", 7, 2, "#333333", lambda: self.add_number("(")),
(")", 7, 3, "#333333", lambda: self.add_number(")")),
("ans", 8, 0, "#5856d6", lambda: self.add_number(str(self.previous_result))),
("1/x", 8, 1, "#5856d6", lambda: self.add_function("1/(" + self.current_input + ")")),
("n!", 8, 2, "#5856d6", lambda: self.add_function("math.factorial(int(" + self.current_input + "))" if self.current_input.isdigit() else "")),
("(", 8, 3, "#333333", lambda: self.add_number("(")),
]
# 创建按钮
for (text, row, col, color, command) in buttons:
button = ttk.button(
self.buttons_frame,
text=text,
command=command
)
if text.isdigit() or text in [".", "+", "-", "*", "/", "(", ")", "^"]:
button.configure(style="number.tbutton")
elif text in ["sin", "cos", "tan", "log", "√", "x²", "x³", "ans", "1/x", "n!"]:
button.configure(style="function.tbutton")
else:
button.configure(style="operator.tbutton")
button.grid(row=row, column=col, sticky="nsew", padx=5, pady=5)
# 配置网格权重
self.buttons_frame.grid_rowconfigure(row, weight=1)
self.buttons_frame.grid_columnconfigure(col, weight=1)
# 设置按钮样式
style = ttk.style()
style.configure("tbutton", font=("arial", 14))
style.map("tbutton",
foreground=[('pressed', 'white'), ('active', '#007aff')],
background=[('pressed', '#007aff'), ('active', '#007aff')],
relief=[('pressed', 'flat'), ('active', 'flat')])
style.configure("number.tbutton", background="#f2f2f7")
style.configure("operator.tbutton", background="#ff9500", foreground="white")
style.configure("function.tbutton", background="#5856d6", foreground="white")
# 计算结果变量
self.previous_result = 0
def add_number(self, number):
if self.reset_input:
self.current_input = ""
self.reset_input = false
if number == "." and "." in self.current_input:
return
self.current_input += number
self.expression_var.set(self.current_input)
def add_operation(self, operation):
if self.current_input == "" and self.previous_input == "":
return
if self.previous_input:
self.calculate()
self.operation = operation
else:
self.operation = operation
self.previous_input = self.current_input
self.current_input = ""
self.expression_var.set(self.previous_input + " " + operation)
def add_function(self, function):
if self.reset_input:
self.current_input = ""
self.reset_input = false
# 检查是否需要添加括号
if not (self.current_input.endswith(")") or self.current_input == ""):
self.current_input += ")"
self.current_input += function
if not self.current_input.endswith(")"):
self.current_input += "("
self.expression_var.set(self.current_input)
def clear_all(self):
self.current_input = ""
self.previous_input = ""
self.operation = none
self.reset_input = false
self.expression_var.set("")
self.result_var.set("")
def delete_last(self):
if self.current_input:
self.current_input = self.current_input[:-1]
self.expression_var.set(self.current_input if self.current_input else "")
elif self.previous_input:
self.previous_input = self.previous_input[:-1]
self.expression_var.set(self.previous_input if self.previous_input else "")
def calculate(self):
try:
# 替换x为*用于计算
expression = self.current_input.replace("^", "**")
# 处理特殊函数
if "sin(" in expression:
expression = expression.replace("sin(", "math.sin(")
if "cos(" in expression:
expression = expression.replace("cos(", "math.cos(")
if "tan(" in expression:
expression = expression.replace("tan(", "math.tan(")
if "log(" in expression:
expression = expression.replace("log(", "math.log10(")
if "√(" in expression:
expression = expression.replace("√(", "math.sqrt(")
result = eval(expression, {"math": math})
self.previous_input = str(result)
self.current_input = str(result)
self.expression_var.set(str(result))
self.result_var.set("=" + str(result))
self.previous_result = result
self.reset_input = true
except exception as e:
self.expression_var.set("错误")
self.result_var.set("")
self.current_input = ""
self.previous_input = ""
self.reset_input = false
@property
def current_input(self):
return self._current_input
@current_input.setter
def current_input(self, value):
self._current_input = value
# 创建主窗口并运行计算器
if __name__ == "__main__":
import math
root = tk.tk()
calculator = calculator(root)
# 添加自定义样式
style = ttk.style()
style.theme_use('clam')
root.mainloop()
2. 高级功能实现
2.1 科学计算功能
上述代码已经实现了以下高级功能:
- 三角函数:sin, cos, tan
- 对数函数:log10
- 平方根:√
- 幂运算:x², x³, x^y
- 常数:π, e
- 阶乘:n!
- 反函数:1/x
2.2 历史记录功能(扩展)
要添加历史记录功能,可以修改代码如下:
class calculator:
def __init__(self, root):
# ... 其他初始化代码 ...
self.history = [] # 存储计算历史
def calculate(self):
try:
# ... 计算代码 ...
# 添加到历史记录
if self.previous_input and self.operation and self.current_input:
expression = f"{self.previous_input} {self.operation} {self.current_input}"
self.history.append((expression, str(result)))
if len(self.history) > 10: # 限制历史记录数量
self.history.pop(0)
# ... 其他代码 ...
except exception as e:
# ... 错误处理代码 ...
def show_history(self):
# 创建新窗口显示历史记录
history_window = tk.toplevel(self.root)
history_window.title("计算历史")
history_window.geometry("350x400")
history_text = tk.text(history_window, font=("arial", 12))
history_text.pack(fill=tk.both, expand=true, padx=10, pady=10)
for expr, res in self.history:
history_text.insert(tk.end, f"{expr} = {res}\n")
history_text.config(state=tk.disabled)
2.3 图形绘制功能(扩展)
要添加函数图形绘制功能,可以使用matplotlib:
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import figurecanvastkagg
class calculator:
# ... 其他代码 ...
def plot_function(self):
function_window = tk.toplevel(self.root)
function_window.title("函数绘图")
function_window.geometry("600x500")
# 创建输入框
input_frame = ttk.frame(function_window)
input_frame.pack(fill=tk.x, padx=10, pady=10)
ttk.label(input_frame, text="输入函数 (使用x作为变量):").pack(side=tk.left)
function_entry = ttk.entry(input_frame, width=30)
function_entry.pack(side=tk.left, padx=5)
function_entry.insert(0, "math.sin(x)") # 默认函数
# 创建绘图区域
fig_frame = ttk.frame(function_window)
fig_frame.pack(fill=tk.both, expand=true, padx=10, pady=10)
fig, ax = plt.subplots(figsize=(6, 5))
canvas = figurecanvastkagg(fig, master=fig_frame)
canvas.get_tk_widget().pack(fill=tk.both, expand=true)
# 绘制按钮
def draw_plot():
try:
func_str = function_entry.get()
x = np.linspace(-10, 10, 400)
y = eval(func_str, {"math": math, "x": x, "np": np})
ax.clear()
ax.plot(x, y)
ax.set_title(f"y = {func_str}")
ax.grid(true)
canvas.draw()
except exception as e:
messagebox.showerror("错误", f"无法绘制函数: {str(e)}")
ttk.button(function_window, text="绘制", command=draw_plot).pack(pady=5)
3. 完整功能整合
将上述功能整合到一个完整的计算器程序中:
import tkinter as tk
from tkinter import ttk, messagebox
import math
import numpy as np
class advancedcalculator:
def __init__(self, root):
self.root = root
self.root.title("高级科学计算器")
self.root.geometry("500x650")
self.root.resizable(false, false)
self.current_input = ""
self.previous_input = ""
self.operation = none
self.reset_input = false
self.history = []
self.create_widgets()
def create_widgets(self):
# 显示框
self.display_frame = ttk.frame(self.root)
self.display_frame.pack(fill=tk.both, padx=10, pady=10)
self.expression_var = tk.stringvar()
self.expression_label = ttk.label(
self.display_frame,
textvariable=self.expression_var,
font=("arial", 14),
anchor=tk.e
)
self.expression_label.pack(fill=tk.both, expand=true)
self.result_var = tk.stringvar()
self.result_label = ttk.label(
self.display_frame,
textvariable=self.result_var,
font=("arial", 24, "bold"),
anchor=tk.e,
foreground="blue"
)
self.result_label.pack(fill=tk.both, expand=true)
# 按钮框架
self.buttons_frame = ttk.frame(self.root)
self.buttons_frame.pack(fill=tk.both, expand=true)
# 按钮布局
buttons = [
# 第一行
("c", 0, 0, "#ff9500", self.clear_all),
("⌫", 0, 1, "#ff9500", self.delete_last),
("÷", 0, 2, "#ff9500", lambda: self.add_operation("/")),
("×", 0, 3, "#ff9500", lambda: self.add_operation("*")),
# 第二行
("7", 1, 0, "#333333", lambda: self.add_number("7")),
("8", 1, 1, "#333333", lambda: self.add_number("8")),
("9", 1, 2, "#333333", lambda: self.add_number("9")),
("-", 1, 3, "#ff9500", lambda: self.add_operation("-")),
# 第三行
("4", 2, 0, "#333333", lambda: self.add_number("4")),
("5", 2, 1, "#333333", lambda: self.add_number("5")),
("6", 2, 2, "#333333", lambda: self.add_number("6")),
("+", 2, 3, "#ff9500", lambda: self.add_operation("+")),
# 第四行
("1", 3, 0, "#333333", lambda: self.add_number("1")),
("2", 3, 1, "#333333", lambda: self.add_number("2")),
("3", 3, 2, "#333333", lambda: self.add_number("3")),
("=", 3, 3, "#4cd964", self.calculate),
# 第五行
("0", 4, 0, "#333333", lambda: self.add_number("0")),
(".", 4, 1, "#333333", lambda: self.add_number(".")),
("(", 4, 2, "#333333", lambda: self.add_number("(")),
(")", 4, 3, "#333333", lambda: self.add_number(")")),
# 第六行 - 高级功能
("sin", 5, 0, "#5856d6", lambda: self.add_function("math.sin(")),
("cos", 5, 1, "#5856d6", lambda: self.add_function("math.cos(")),
("tan", 5, 2, "#5856d6", lambda: self.add_function("math.tan(")),
("log", 5, 3, "#5856d6", lambda: self.add_function("math.log10(")),
# 第七行
("√", 6, 0, "#5856d6", lambda: self.add_function("math.sqrt(")),
("x²", 6, 1, "#5856d6", lambda: self.add_operation("**2")),
("x³", 6, 2, "#5856d6", lambda: self.add_operation("**3")),
("π", 6, 3, "#5856d6", lambda: self.add_number(str(math.pi))),
# 第八行
("e", 7, 0, "#5856d6", lambda: self.add_number(str(math.e))),
("x^y", 7, 1, "#5856d6", lambda: self.add_operation("**")),
("(", 7, 2, "#333333", lambda: self.add_number("(")),
(")", 7, 3, "#333333", lambda: self.add_number(")")),
# 第九行
("ans", 8, 0, "#5856d6", lambda: self.add_number(str(self.previous_result))),
("1/x", 8, 1, "#5856d6", lambda: self.add_function("1/(" + self.current_input + ")")),
("n!", 8, 2, "#5856d6", lambda: self.add_function("math.factorial(int(" + self.current_input + "))" if self.current_input.isdigit() else "")),
("hist", 8, 3, "#5856d6", self.show_history),
]
# 创建按钮
for (text, row, col, color, command) in buttons:
button = ttk.button(
self.buttons_frame,
text=text,
command=command
)
if text.isdigit() or text in [".", "+", "-", "*", "/", "(", ")", "^"]:
button.configure(style="number.tbutton")
elif text in ["sin", "cos", "tan", "log", "√", "x²", "x³", "ans", "1/x", "n!"]:
button.configure(style="function.tbutton")
elif text in ["hist"]:
button.configure(style="history.tbutton")
else:
button.configure(style="operator.tbutton")
button.grid(row=row, column=col, sticky="nsew", padx=5, pady=5)
# 配置网格权重
self.buttons_frame.grid_rowconfigure(row, weight=1)
self.buttons_frame.grid_columnconfigure(col, weight=1)
# 设置按钮样式
style = ttk.style()
style.configure("tbutton", font=("arial", 14))
style.map("tbutton",
foreground=[('pressed', 'white'), ('active', '#007aff')],
background=[('pressed', '#007aff'), ('active', '#007aff')],
relief=[('pressed', 'flat'), ('active', 'flat')])
style.configure("number.tbutton", background="#f2f2f7")
style.configure("operator.tbutton", background="#ff9500", foreground="white")
style.configure("function.tbutton", background="#5856d6", foreground="white")
style.configure("history.tbutton", background="#8e8e93", foreground="white")
# 计算结果变量
self.previous_result = 0
def add_number(self, number):
if self.reset_input:
self.current_input = ""
self.reset_input = false
if number == "." and "." in self.current_input:
return
self.current_input += number
self.expression_var.set(self.current_input)
def add_operation(self, operation):
if self.current_input == "" and self.previous_input == "":
return
if self.previous_input:
self.calculate()
self.operation = operation
else:
self.operation = operation
self.previous_input = self.current_input
self.current_input = ""
self.expression_var.set(self.previous_input + " " + operation)
def add_function(self, function):
if self.reset_input:
self.current_input = ""
self.reset_input = false
# 检查是否需要添加括号
if not (self.current_input.endswith(")") or self.current_input == ""):
self.current_input += ")"
self.current_input += function
if not self.current_input.endswith(")"):
self.current_input += "("
self.expression_var.set(self.current_input)
def clear_all(self):
self.current_input = ""
self.previous_input = ""
self.operation = none
self.reset_input = false
self.expression_var.set("")
self.result_var.set("")
def delete_last(self):
if self.current_input:
self.current_input = self.current_input[:-1]
self.expression_var.set(self.current_input if self.current_input else "")
elif self.previous_input:
self.previous_input = self.previous_input[:-1]
self.expression_var.set(self.previous_input if self.previous_input else "")
def calculate(self):
try:
# 替换x为*用于计算
expression = self.current_input.replace("^", "**")
# 处理特殊函数
if "sin(" in expression:
expression = expression.replace("sin(", "math.sin(")
if "cos(" in expression:
expression = expression.replace("cos(", "math.cos(")
if "tan(" in expression:
expression = expression.replace("tan(", "math.tan(")
if "log(" in expression:
expression = expression.replace("log(", "math.log10(")
if "√(" in expression:
expression = expression.replace("√(", "math.sqrt(")
result = eval(expression, {"math": math})
self.previous_input = str(result)
self.current_input = str(result)
self.expression_var.set(str(result))
self.result_var.set("=" + str(result))
self.previous_result = result
self.reset_input = true
# 添加到历史记录
if self.previous_input and self.operation and self.current_input:
expr = f"{self.previous_input} {self.operation} {self.current_input}"
self.history.append((expr, str(result)))
if len(self.history) > 10: # 限制历史记录数量
self.history.pop(0)
except exception as e:
self.expression_var.set("错误")
self.result_var.set("")
self.current_input = ""
self.previous_input = ""
self.reset_input = false
@property
def current_input(self):
return self._current_input
@current_input.setter
def current_input(self, value):
self._current_input = value
def show_history(self):
history_window = tk.toplevel(self.root)
history_window.title("计算历史")
history_window.geometry("400x400")
history_text = tk.text(history_window, font=("arial", 12))
history_text.pack(fill=tk.both, expand=true, padx=10, pady=10)
for expr, res in self.history:
history_text.insert(tk.end, f"{expr} = {res}\n")
history_text.config(state=tk.disabled)
# 创建主窗口并运行计算器
if __name__ == "__main__":
import math
root = tk.tk()
# 添加自定义样式
style = ttk.style()
style.theme_use('clam')
calculator = advancedcalculator(root)
root.mainloop()
4. 功能说明
4.1 基本功能
- 支持加、减、乘、除基本运算
- 支持括号和小数点
- 清除(c)和删除(⌫)功能
4.2 高级科学计算功能
- 三角函数:sin, cos, tan
- 对数函数:log10
- 平方根:√
- 幂运算:x², x³, x^y
- 常数:π, e
- 阶乘:n!
- 反函数:1/x
4.3 额外功能
- 历史记录:记录最近10次计算
- ans功能:使用上一次的计算结果
5. 扩展建议
- 图形绘制功能:添加函数绘图功能,可以使用matplotlib集成
- 单位转换:添加长度、重量、温度等单位转换功能
- 方程求解:添加一元二次方程等求解功能
- 统计计算:添加平均值、标准差等统计功能
- 编程模式:添加自定义函数定义功能
这个计算器程序提供了完整的科学计算功能,界面简洁直观,适合学习和日常使用。
以上就是使用python创建一个功能完整的windows风格计算器程序的详细内容,更多关于python创建windows系统计算器程序的资料请关注代码网其它相关文章!
推荐阅读
-
一文教你Python如何快速精准抓取网页数据
本文将使用requests和beautifulsoup这两个流行的库来实现。1.准备工作首先安装必要的库:pipinst...
-
使用Python实现IP地址和端口状态检测与监控
-
基于Python打造一个智能单词管理神器
-
Python实现微信自动锁定工具
-
Python开发文字版随机事件游戏的项目实例
随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型。在这类游戏中,玩家必须应对随机发生的情况,这些情况可能会影响他们的资...
-
使用Pandas实现Excel中的数据透视表的项目实践
引言在数据分析中,数据透视表是一种非常强大的工具,它可以帮助我们快速汇总、分析和可视化大量数据。虽然excel提供了内置的数据透...
-
Pandas利用主表更新子表指定列小技巧
一、前言工作的小技巧,利用pandas读取主表和子表,利用主表的指定列,更新子表的指定列。案例:主表:uidname0...
-
Pandas中统计汇总可视化函数plot()的使用
-
Python中tensorflow的argmax()函数的使用小结
在tensorflow中,argmax()函数是一个非常重要的操作,它用于返回给定张量(tensor)沿指定轴的最大值的索引。这个...
-
Python中模块graphviz使用入门
