Update 计算器.py

pull/1/head
plhj9vtan 6 months ago
parent 9a47a172e2
commit a69f81aa82

@ -1,165 +1,205 @@
import tkinter as tk import tkinter as tk
from tkinter import messagebox from tkinter import messagebox
import re import re
#import math from math import *
from math import *
# 创建主窗口
# 创建主窗口 window = tk.Tk()
window = tk.Tk() # 设置窗口大小和位置
# 设置窗口大小和位置 window.geometry('520x300+600+300')
window.geometry('340x240+600+300') # 不允许改变窗口大小
# 不允许改变窗口大小 window.resizable(False, False)
window.resizable(False, False) # 设置窗口标题
# 设置窗口标题 window.title('计算器')
window.title('计算器') # 背景颜色
# 背景颜色 window.config(background="blue")
window.config(background="blue") # 自动刷新字符串变量,可用 set 和 get 方法进行传值和取值
# 自动刷新字符串变量,可用 set 和 get 方法进行传值和取值 content_var = tk.StringVar(window, '')
content_var = tk.StringVar(window, '') # 创建单行文本框
# 创建单行文本框 content_entry = tk.Entry(window, textvariable=content_var)
content_entry = tk.Entry(window, textvariable=content_var) # 设置文本框为只读
# 设置文本框为只读 content_entry['state'] = 'readonly'
content_entry['state'] = 'readonly' # 设置文本框坐标及宽高
# 设置文本框坐标及宽高 content_entry.place(x=20, y=10, width=300, height=30)
content_entry.place(x=20, y=10, width=300, height=30)
# 按钮显示内容 record_text = tk.Text(window, wrap=tk.WORD, height=10)
value = ['e^x','', 'π', '%', '//', record_text.place(x=320, y=50, width=180, height=240)
'**','', '(', ')', '/',
'x!','7', '8', '9', '*', # 按钮显示内容
'','4', '5', '6', '-', value = ['e^x','', 'π', '%', '//','ln',
'','1', '2', '3', '+', '**','', '(', ')', '/','lg',
'C','+/-', '0', '.', '='] 'x!','7', '8', '9', '*','tan',
index = 0 '','4', '5', '6', '-','cos',
# 将按钮进行 6x5 放置 '','1', '2', '3', '+','sin',]
for row in range(6):
for col in range(5): value0 = ['+/-','C', '0', '.', '=',]
d = value[index]
index += 1 index = 0
if (row==1 and (col==1 or col==2 or col==3)): index0 = 0
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="gray", fg="black") # 将按钮进行 5x6 放置
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) for row in range(5):
elif (row==2 and (col==1 or col==2 or col==3)): for col in range(6):
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red") d = value[index]
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) index += 1
elif (row==3 and (col==1 or col==2 or col==3)): if (row==1 and (col==1 or col==2 or col==3)):
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red") btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="gray", fg="black")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) btn_digit.place(x=20 + col * 50, y=50 + row * 40, width=50, height=40)
elif (row==4 and (col==1 or col==2 or col==3)): elif (row==2 and (col==1 or col==2 or col==3)):
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red") btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) btn_digit.place(x=20 + col * 50, y=50 + row * 40, width=50, height=40)
elif (row==5 and col==2): elif (row==3 and (col==1 or col==2 or col==3)):
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red") btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) btn_digit.place(x=20 + col * 50, y=50 + row * 40, width=50, height=40)
elif (row==5 and col!=2): elif (row==4 and (col==1 or col==2 or col==3)):
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="SpringGreen", fg="red") btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="LightPink", fg="red")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) btn_digit.place(x=20 + col * 50, y=50 + row * 40, width=50, height=40)
else:
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="DeepSkyBlue", fg="purple") else:
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20) btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="DeepSkyBlue", fg="purple")
btn_digit.place(x=20 + col * 50, y=50 + row * 40, width=50, height=40)
# 点击事件
def onclick(key): for l in range(5):
# 运算符 c = value0[index0]
operation = ('+', '-', '*', '/', '**', '//', '%') index0 += 1
# 获取文本框中的内容 if (l == 2):
content = content_var.get() btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="LightPink", fg="red")
# 如果已有内容是以小数点开头的,在前面加 0 btn_digit.place(x=20 + l * 50, y=250, width=50, height=40)
if content.startswith('.'): elif (l == 0):
content = '0' + content # 字符串可以直接用+来增加字符 btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="SpringGreen", fg="red")
# 根据不同的按钮作出不同的反应 btn_digit.place(x=20 + l * 50, y=250, width=50, height=40)
if key in '0123456789': elif (l == 1):
# 按下 0-9 在 content 中追加 btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="yellow", fg="red")
content += key btn_digit.place(x=20 + l * 50, y=250, width=50, height=40)
elif key == '.': elif (l == 3):
# 将 content 从 +-*/ 这些字符的地方分割开来 btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="SkyBlue", fg="red")
last_part = re.split(r'[+\-*/]', content)[-1] btn_digit.place(x=20 + l * 50, y=250, width=50, height=40)
if '.' in last_part: else:
# 信息提示对话框 btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="LightCoral", fg="black")
tk.messagebox.showerror('Error', 'Repeated decimal point') btn_digit.place(x=220, y=250, width=100, height=40)
return
else: lab_text_record = tk.Label(window, text='历史记录', font=("Helvetica", 14, "bold"), bg="white", fg="black")
content += key lab_text_record.place(x=320, y=10, width=180, height=40)
elif key == 'C':
# 清除文本框 # 添加清除历史记录按钮
content = '' btn_clear_record = tk.Button(window, text='清除记录', command=lambda: record_text.delete(1.0, tk.END), bg="white", fg="black")
elif key == '=': btn_clear_record.place(x=320, y=250, width=180, height=40)
try:
# 对输入的表达式求值 # 点击事件
content = str(eval(content.replace("π", str(pi)))) def onclick(key):
content = str(eval(content)) # 运算符
except ZeroDivisionError: operation = ('+', '-', '*', '/', '**', '//', '%')
tk.messagebox.showerror('Error', 'Division by zero is not allowed') # 获取文本框中的内容
return content = content_var.get()
except Exception as e: # 如果已有内容是以小数点开头的,在前面加 0
tk.messagebox.showerror('Error', f'Invalid expression: {e}') if content.startswith('.'):
return content = '0' + content # 字符串可以直接用+来增加字符
elif key in operation: # 根据不同的按钮作出不同的反应
if content.endswith(operation): if key in '0123456789':
tk.messagebox.showerror('Error', 'Consecutive operators not allowed') # 按下 0-9 在 content 中追加
return content += key
content += key elif key == '.':
# 将 content 从 +-*/ 这些字符的地方分割开来
elif key == '+/-': last_part = re.split(r'[+\-*/]', content)[-1]
# 将正负号切换 if '.' in last_part:
if content.startswith('-'): # 信息提示对话框
content = content[1:] tk.messagebox.showerror('错误', '数字只有一个小数点,所以不能再次点击!')
else: return
content = '-' + content else:
elif key in '()': content += key
# 直接在内容后面追加括号 elif key == 'C':
content += key # 清除文本框
elif key == '': content = ''
# 从 . 处分割存入 nn 是一个列表 elif key == '=':
n = content.split('.') try:
# 如果列表中所有的都是数字,就是为了检查表达式是不是正确的 # 对输入的表达式求值
if all(map(lambda x: x.isdigit(), n)): result = str(eval(content.replace("π", str(pi)).replace("rad", "radians")))
content = sqrt(eval(content)) record_text.insert(tk.END, f"{content} = {result}\n")
else: content = result
tk.messagebox.showerror('Error', 'Invalid expression') except ZeroDivisionError:
return tk.messagebox.showerror('错误', '这个值太大了以至于无法算出其值0不能作为除数')
elif key == 'e^x': return
# 添加常数e的x次方 except Exception as e:
content = exp(eval(content)) tk.messagebox.showerror('错误', f'无效表达式: {e}')
elif key == '': return
# 删除最后一个字符 elif key in operation:
content = content[:-1] if content.endswith(operation):
elif key == '': tk.messagebox.showerror('错误', '运算符号之间不能直接连接,需要加入数值!')
# 计算平方 return
try: content += key
content = str(float(content) ** 2)
except Exception as e: elif key == '+/-':
tk.messagebox.showerror('Error', f'Invalid expression: {e}') # 将正负号切换
return if content.startswith('-'):
elif key == '': content = content[1:]
# 计算立方 else:
try: content = '-' + content
content = str(float(content) ** 3) elif key in '()':
except Exception as e: # 直接在内容后面追加括号
tk.messagebox.showerror('Error', f'Invalid expression: {e}') content += key
return elif key == '':
elif key == 'x!': # 从 . 处分割存入 nn 是一个列表
# 计算阶乘 n = content.split('.')
try: # 如果列表中所有的都是数字,就是为了检查表达式是不是正确的
num = int(content) if all(map(lambda x: x.isdigit(), n)):
if num < 0: content = sqrt(eval(content))
tk.messagebox.showerror('Error', 'Please enter a non-negative integer') else:
return tk.messagebox.showerror('错误', '在实数范围内,负数不能算数平方根!')
content = str(factorial(num)) return
except ValueError: elif key == 'e^x':
tk.messagebox.showerror('Error', 'Please enter a non-negative integer') # 添加常数e的x次方
return content = exp(eval(content))
except Exception as e: elif key == '':
tk.messagebox.showerror('Error', f'Invalid expression: {e}') # 删除最后一个字符
return content = content[:-1]
elif key == 'π': elif key == '':
# 添加常数π # 计算平方
content += 'π' try:
content = str(float(content) ** 2)
# 将结果显示到文本框中 except Exception as e:
content_var.set(content) tk.messagebox.showerror('错误', f'无效表达式: {e}')
return
# 运行主循环 elif key == '':
window.mainloop() # 计算立方
try:
#x = 2 + 9 * ((3*12) - 8) // 10 content = str(float(content) ** 3)
#print(x) except Exception as e:
tk.messagebox.showerror('错误', f'无效表达式: {e}')
return
elif key == 'x!':
# 计算阶乘
try:
num = int(content)
if num < 0:
tk.messagebox.showerror('错误', '请输入一个非负整数进行阶乘运算!')
return
content = str(factorial(num))
except ValueError:
tk.messagebox.showerror('错误', '请输入一个非负整数进行阶乘运算!')
return
except Exception as e:
tk.messagebox.showerror('错误', f'无效的表达式: {e}')
return
elif key == 'π':
# 添加常数π
content += 'π'
elif key == 'sin':
content = sin(eval(content))
elif key == 'cos':
content = cos(eval(content))
elif key == 'tan':
content = tan(eval(content))
elif key == 'lg':
content = log10(eval(content))
elif key == 'ln':
content = log(eval(content))
elif key == 'rad':
content = str(eval(content)) + ' rad'
# 将结果显示到文本框中
content_var.set(content)
# 运行主循环
window.mainloop()
# 2 + 9 * ((3*12) - 8) // 10 =

Loading…
Cancel
Save