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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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)