from tkinter import ttk
from tkinter import messagebox
from playsound import playsound
class Calculator:
def __init__(self, master):
self.result = None # 定义 'result' 属性
self.master = master
master.title("多功能计算器")
master.resizable(width=False, height=False)
master.config(bg='#000')
# 显示屏
self.screen = tk.Entry(master, width=35, font=('Digital-7', 18),
justify='right', bd=5, bg='#000', fg='#fff')
self.screen.grid(row=0, column=0, columnspan=4, padx=5, pady=5)
# 按钮字体
button_font = ("Digital-7", 20)
# 数字按钮
self.create_number_button(7, 1, 1, button_font, '#fff', '#11b8b5')
self.create_number_button(8, 1, 2, button_font, '#fff', '#11b8b5')
self.create_number_button(9, 1, 3, button_font, '#fff', '#11b8b5')
self.create_number_button(4, 2, 1, button_font, '#fff', '#11b8b5')
self.create_number_button(5, 2, 2, button_font, '#fff', '#11b8b5')
self.create_number_button(6, 2, 3, button_font, '#fff', '#11b8b5')
self.create_number_button(1, 3, 1, button_font, '#fff', '#11b8b5')
self.create_number_button(2, 3, 2, button_font, '#fff', '#11b8b5')
self.create_number_button(3, 3, 3, button_font, '#fff', '#11b8b5')
self.create_number_button(0, 4, 2, button_font, '#fff', '#11b8b5')
# 运算符按钮
self.create_operator_button('+', 1, 4, button_font, '#fff', '#fc5c65')
self.create_operator_button('-', 2, 4, button_font, '#fff', '#fc5c65')
self.create_operator_button('*', 3, 4, button_font, '#fff', '#fc5c65')
self.create_operator_button('/', 4, 4, button_font, '#fff', '#fc5c65')
# 特殊计算按钮
self.create_special_button('C', 4, 1, button_font, '#fff', '#eb3b5a')
self.create_special_button('=', 4, 3, button_font, '#fff', '#20bf6b')
self.create_special_button('.', 4, 4, button_font, '#fff', '#ffb142')
self.create_special_button('√', 5, 1, button_font, '#fff', '#ff9f43')
self.create_special_button('^', 5, 2, button_font, '#fff', '#ff9f43')
self.create_special_button('(', 5, 3, button_font, '#fff', '#4b6584')
self.create_special_button(')', 5, 4, button_font, '#fff', '#4b6584')
# 其他控件
self.create_menu()
self.create_status_bar()
# 计算结果
self.result = None
def create_number_button(self, number, row, column, font, fg=None, bg=None):
button = tk.Button(self.master, text=number, width=7, height=2,
font=font, fg=fg, bg=bg, command=lambda: (self.append_to_screen(number),playsound('click.wav')))
button.bind('', lambda event, txt=f'输入 "{number}"': self.show_tooltip(txt))
button.bind('', self.hide_tooltip)
button.grid(row=row, column=column, padx=3, pady=3)
button.config(bd=5, relief='raised')
button.config(activebackground='#000', activeforeground=fg)
def create_operator_button(self, operator, row, column, font, fg=None, bg=None):
button = tk.Button(self.master, text=operator, width=7, height=2,
font=font, fg=fg, bg=bg, command=lambda: (self.append_to_screen(operator),playsound('click.wav')))
button.bind('', lambda event, txt=f'输入 "{operator}"': self.show_tooltip(txt))
button.bind('', self.hide_tooltip)
button.grid(row=row, column=column, padx=3, pady=3)
button.config(bd=5, relief='raised')
button.config(activebackground='#000', activeforeground=fg)
def create_special_button(self, special, row, column, font, fg=None, bg=None):
button = tk.Button(self.master, text=special, width=7, height=2,
font=font, fg=fg, bg=bg, command=lambda: (self.special_calculation(special),playsound('click.wav')))
button.bind('', lambda event, txt=f'输入 "{special}"': self.show_tooltip(txt))
button.bind('', self.hide_tooltip)
button.grid(row=row, column=column, padx=3, pady=3)
button.config(bd=5, relief='raised')
button.config(activebackground='#000', activeforeground=fg)
def append_to_screen(self, value):
# 清空结果
if self.result is not None:
self.screen.delete(0, tk.END)
self.result = None
self.screen.insert(tk.END, value)
def special_calculation(self, operator):
expression = self.screen.get()
try:
if operator == 'C':
self.result = None
self.screen.delete(0, tk.END)
elif operator == '=':
# 计算表达式的值
result = eval(expression)
self.screen.delete(0, tk.END)
self.screen.insert(tk.END, result)
self.result = result
elif operator == '.':
if '.' not in expression:
self.screen.insert(tk.END, '.')
elif operator == '√':
# 计算平方根
result = eval(expression + '**0.5')
self.screen.delete(0, tk.END)
self.screen.insert(tk.END, result)
self.result = result
elif operator == '^':
# 计算平方
result = eval(expression + '**2')
self.screen.delete(0, tk.END)
self.screen.insert(tk.END, result)
self.result = result
elif operator == '(':
self.screen.insert(tk.END, '(')
elif operator == ')':
self.screen.insert(tk.END, ')')
except ZeroDivisionError:
messagebox.showerror('错误', '除数不能为0')
except SyntaxError:
messagebox.showerror('错误', '输入不合法')
def create_menu(self):
menu = tk.Menu(self.master)
self.master.config(menu=menu)
file_menu = tk.Menu(menu)
file_menu.add_command(label='退出', command=self.master.quit)
help_menu = tk.Menu(menu)
help_menu.add_command(label='关于', command=self.show_about)
menu.add_cascade(label='文件', menu=file_menu)
menu.add_cascade(label='帮助', menu=help_menu)
def create_status_bar(self):
self.status_bar = tk.Label(self.master, text='', bd=1, relief=tk.SUNKEN,
anchor=tk.W, bg='#000', fg='#fff')
self.status_bar.grid(row=6, column=0, columnspan=4, sticky='we')
self.update_status_bar()
def update_status_bar(self):
if self.result is None:
self.status_bar.config(text='')
else:
self.status_bar.config(text=f'结果:{self.result}')
self.master.after(100, self.update_status_bar)
def show_about(self):
messagebox.showinfo('关于', '这是一个由Binjie09开发的多功能计算器。')
def show_tooltip(self, text):
x = self.master.winfo_x() + self.master.winfo_width() + 5
y = self.master.winfo_y() + self.master.winfo_height() - 30
self.tooltip = tk.Toplevel()
self.tooltip.overrideredirect(True)
self.tooltip.geometry(f'+{x}+{y}')
label = ttk.Label(self.tooltip, text=text)
label.pack(ipadx=5, ipady=5, padx=5, pady=5)
self.tooltip.attributes('-topmost', True)
def hide_tooltip(self, event):
self.tooltip.destroy()
root = tk.Tk()
calculator = Calculator(root)
root.mainloop()