diff --git a/计算器.py b/计算器.py index 997b207..8347154 100644 --- a/计算器.py +++ b/计算器.py @@ -1,165 +1,205 @@ -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', '*', - 'x³','4', '5', '6', '-', - 'x²','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 == '√': - # 从 . 处分割存入 n,n 是一个列表 - 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 == 'x²': - # 计算平方 - try: - content = str(float(content) ** 2) - except Exception as e: - tk.messagebox.showerror('Error', f'Invalid expression: {e}') - return - elif key == 'x³': - # 计算立方 - 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) +import tkinter as tk +from tkinter import messagebox +import re +from math import * + +# 创建主窗口 +window = tk.Tk() +# 设置窗口大小和位置 +window.geometry('520x300+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) + +record_text = tk.Text(window, wrap=tk.WORD, height=10) +record_text.place(x=320, y=50, width=180, height=240) + +# 按钮显示内容 +value = ['e^x','√', 'π', '%', '//','ln', + '**','⌫', '(', ')', '/','lg', + 'x!','7', '8', '9', '*','tan', + 'x³','4', '5', '6', '-','cos', + 'x²','1', '2', '3', '+','sin',] + +value0 = ['+/-','C', '0', '.', '=',] + +index = 0 +index0 = 0 +# 将按钮进行 5x6 放置 +for row in range(5): + for col in range(6): + 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 * 50, y=50 + row * 40, width=50, height=40) + 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 * 50, y=50 + row * 40, width=50, height=40) + 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 * 50, y=50 + row * 40, width=50, height=40) + 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 * 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") + btn_digit.place(x=20 + col * 50, y=50 + row * 40, width=50, height=40) + +for l in range(5): + c = value0[index0] + index0 += 1 + if (l == 2): + btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="LightPink", fg="red") + btn_digit.place(x=20 + l * 50, y=250, width=50, height=40) + elif (l == 0): + 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) + elif (l == 1): + btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="yellow", fg="red") + btn_digit.place(x=20 + l * 50, y=250, width=50, height=40) + elif (l == 3): + btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="SkyBlue", fg="red") + btn_digit.place(x=20 + l * 50, y=250, width=50, height=40) + else: + btn_digit = tk.Button(window, text=c, command=lambda x=c: onclick(x), bg="LightCoral", fg="black") + btn_digit.place(x=220, y=250, width=100, height=40) + +lab_text_record = tk.Label(window, text='历史记录', font=("Helvetica", 14, "bold"), bg="white", fg="black") +lab_text_record.place(x=320, y=10, width=180, height=40) + +# 添加清除历史记录按钮 +btn_clear_record = tk.Button(window, text='清除记录', command=lambda: record_text.delete(1.0, tk.END), bg="white", fg="black") +btn_clear_record.place(x=320, y=250, width=180, height=40) + +# 点击事件 +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('错误', '数字只有一个小数点,所以不能再次点击!') + return + else: + content += key + elif key == 'C': + # 清除文本框 + content = '' + elif key == '=': + try: + # 对输入的表达式求值 + result = str(eval(content.replace("π", str(pi)).replace("rad", "radians"))) + record_text.insert(tk.END, f"{content} = {result}\n") + content = result + except ZeroDivisionError: + tk.messagebox.showerror('错误', '这个值太大了,以至于无法算出其值,0不能作为除数!') + return + except Exception as e: + tk.messagebox.showerror('错误', f'无效表达式: {e}') + return + elif key in operation: + if content.endswith(operation): + tk.messagebox.showerror('错误', '运算符号之间不能直接连接,需要加入数值!') + return + content += key + + elif key == '+/-': + # 将正负号切换 + if content.startswith('-'): + content = content[1:] + else: + content = '-' + content + elif key in '()': + # 直接在内容后面追加括号 + content += key + elif key == '√': + # 从 . 处分割存入 n,n 是一个列表 + n = content.split('.') + # 如果列表中所有的都是数字,就是为了检查表达式是不是正确的 + if all(map(lambda x: x.isdigit(), n)): + content = sqrt(eval(content)) + else: + tk.messagebox.showerror('错误', '在实数范围内,负数不能算数平方根!') + return + elif key == 'e^x': + # 添加常数e的x次方 + content = exp(eval(content)) + elif key == '⌫': + # 删除最后一个字符 + content = content[:-1] + elif key == 'x²': + # 计算平方 + try: + content = str(float(content) ** 2) + except Exception as e: + tk.messagebox.showerror('错误', f'无效表达式: {e}') + return + elif key == 'x³': + # 计算立方 + try: + content = str(float(content) ** 3) + 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 = +