You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
6.3 KiB

import tkinter as tk
from tkinter import messagebox
import re
#import math
from math import *
# 创建主窗口
window = tk.Tk()
# 设置窗口大小和位置
window.geometry('340x240+600+300')
# 不允许改变窗口大小
window.resizable(False, False)
# 设置窗口标题
window.title('计算器')
# 背景颜色
window.config(background="blue")
# 自动刷新字符串变量,可用 set 和 get 方法进行传值和取值
content_var = tk.StringVar(window, '')
# 创建单行文本框
content_entry = tk.Entry(window, textvariable=content_var)
# 设置文本框为只读
content_entry['state'] = 'readonly'
# 设置文本框坐标及宽高
content_entry.place(x=20, y=10, width=300, height=30)
# 按钮显示内容
value = ['e^x','', 'π', '%', '//',
'**','', '(', ')', '/',
'x!','7', '8', '9', '*',
'','4', '5', '6', '-',
'','1', '2', '3', '+',
'C','+/-', '0', '.', '=']
index = 0
# 将按钮进行 6x5 放置
for row in range(6):
for col in range(5):
d = value[index]
index += 1
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="gray", fg="black")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20)
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.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20)
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.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20)
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="LightPink", fg="red")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20)
elif (row==5 and col==2):
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)
elif (row==5 and col!=2):
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="SpringGreen", fg="red")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20)
else:
btn_digit = tk.Button(window, text=d, command=lambda x=d: onclick(x), bg="DeepSkyBlue", fg="purple")
btn_digit.place(x=20 + col * 62, y=50 + row * 30, width=50, height=20)
# 点击事件
def onclick(key):
# 运算符
operation = ('+', '-', '*', '/', '**', '//', '%')
# 获取文本框中的内容
content = content_var.get()
# 如果已有内容是以小数点开头的,在前面加 0
if content.startswith('.'):
content = '0' + content # 字符串可以直接用+来增加字符
# 根据不同的按钮作出不同的反应
if key in '0123456789':
# 按下 0-9 在 content 中追加
content += key
elif key == '.':
# 将 content 从 +-*/ 这些字符的地方分割开来
last_part = re.split(r'[+\-*/]', content)[-1]
if '.' in last_part:
# 信息提示对话框
tk.messagebox.showerror('Error', 'Repeated decimal point')
return
else:
content += key
elif key == 'C':
# 清除文本框
content = ''
elif key == '=':
try:
# 对输入的表达式求值
content = str(eval(content.replace("π", str(pi))))
content = str(eval(content))
except ZeroDivisionError:
tk.messagebox.showerror('Error', 'Division by zero is not allowed')
return
except Exception as e:
tk.messagebox.showerror('Error', f'Invalid expression: {e}')
return
elif key in operation:
if content.endswith(operation):
tk.messagebox.showerror('Error', 'Consecutive operators not allowed')
return
content += key
elif key == '+/-':
# 将正负号切换
if content.startswith('-'):
content = content[1:]
else:
content = '-' + content
elif key in '()':
# 直接在内容后面追加括号
content += key
elif key == '':
# 从 . 处分割存入 nn 是一个列表
n = content.split('.')
# 如果列表中所有的都是数字,就是为了检查表达式是不是正确的
if all(map(lambda x: x.isdigit(), n)):
content = sqrt(eval(content))
else:
tk.messagebox.showerror('Error', 'Invalid expression')
return
elif key == 'e^x':
# 添加常数e的x次方
content = exp(eval(content))
elif key == '':
# 删除最后一个字符
content = content[:-1]
elif key == '':
# 计算平方
try:
content = str(float(content) ** 2)
except Exception as e:
tk.messagebox.showerror('Error', f'Invalid expression: {e}')
return
elif key == '':
# 计算立方
try:
content = str(float(content) ** 3)
except Exception as e:
tk.messagebox.showerror('Error', f'Invalid expression: {e}')
return
elif key == 'x!':
# 计算阶乘
try:
num = int(content)
if num < 0:
tk.messagebox.showerror('Error', 'Please enter a non-negative integer')
return
content = str(factorial(num))
except ValueError:
tk.messagebox.showerror('Error', 'Please enter a non-negative integer')
return
except Exception as e:
tk.messagebox.showerror('Error', f'Invalid expression: {e}')
return
elif key == 'π':
# 添加常数π
content += 'π'
# 将结果显示到文本框中
content_var.set(content)
# 运行主循环
window.mainloop()
#x = 2 + 9 * ((3*12) - 8) // 10
#print(x)