Quick actions

cmd+k|ctrl+k

Navigation

Languages

2026022501

Snippet info

Language

Python

Visibility

public

Author

shaoronghong15

Created

2026-02-25T12:07:17.666697Z

Updated

2026-02-25T12:07:17.666697Z

import tkinter as tk
from tkinter import ttk
import math
import re

class CalculatorGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("科学计算器")
        self.root.geometry("400x550")
        self.root.resizable(False, False)
        self.root.configure(bg="#f0f0f0")
        
        # 设置中文字体
        self.font = ("SimHei", 12)
        
        # 计算器逻辑
        self.memory = 0
        self.history = []
        self.current_expression = ""
        self.last_result = None
        
        # 创建界面
        self.create_widgets()
    
    def create_widgets(self):
        """创建计算器界面"""
        # 历史记录按钮
        history_frame = tk.Frame(self.root, bg="#f0f0f0")
        history_frame.pack(pady=5, fill=tk.X, padx=10)
        
        history_button = tk.Button(history_frame, text="历史记录", font=self.font, 
                                  command=self.show_history, bg="#2196F3", fg="white")
        history_button.pack(side=tk.RIGHT, padx=5)
        
        # 显示屏
        display_frame = tk.Frame(self.root, bg="#f0f0f0")
        display_frame.pack(pady=10, fill=tk.X, padx=10)
        
        self.expression_var = tk.StringVar()
        self.expression_var.set("")
        
        self.result_var = tk.StringVar()
        self.result_var.set("0")
        
        expression_label = tk.Label(display_frame, textvariable=self.expression_var, 
                                   font=("SimHei", 14), bg="white", anchor=tk.E, padx=10, pady=5)
        expression_label.pack(fill=tk.X)
        
        result_label = tk.Label(display_frame, textvariable=self.result_var, 
                               font=("SimHei", 24, "bold"), bg="white", anchor=tk.E, padx=10, pady=5)
        result_label.pack(fill=tk.X)
        
        # 按钮框架
        buttons_frame = tk.Frame(self.root, bg="#f0f0f0")
        buttons_frame.pack(pady=10, fill=tk.BOTH, expand=True, padx=10)
        
        # 按钮布局
        buttons = [
            ['7', '8', '9', '/', 'C'],
            ['4', '5', '6', '*', 'CE'],
            ['1', '2', '3', '-', '√'],
            ['0', '.', '=', '+', '^'],
            ['(', ')', 'M+', 'M-', 'MR']
        ]
        
        for i, row in enumerate(buttons):
            for j, text in enumerate(row):
                button = tk.Button(buttons_frame, text=text, font=self.font,
                                  width=7, height=2, bg="#e0e0e0",
                                  command=lambda txt=text: self.button_click(txt))
                button.grid(row=i, column=j, padx=2, pady=2, sticky="nsew")
        
        # 配置网格权重,使按钮均匀分布
        for i in range(len(buttons)):
            buttons_frame.grid_rowconfigure(i, weight=1)
        for j in range(len(buttons[0])):
            buttons_frame.grid_columnconfigure(j, weight=1)
    
    def button_click(self, text):
        """处理按钮点击事件"""
        if text == '=':
            self.calculate()
        elif text == 'C':
            self.current_expression = ""
            self.update_display()
        elif text == 'CE':
            # 删除最后一个字符
            self.current_expression = self.current_expression[:-1]
            self.update_display()
        elif text == '√':
            self.current_expression += "sqrt("
            self.update_display()
        elif text == '^':
            self.current_expression += "**"
            self.update_display()
        elif text == 'M+':
            self.current_expression += f"+{self.memory}"
            self.update_display()
        elif text == 'M-':
            self.current_expression += f"-{self.memory}"
            self.update_display()
        elif text == 'MR':
            self.current_expression += str(self.memory)
            self.update_display()
        else:
            self.current_expression += text
            self.update_display()
    
    def update_display(self):
        """更新显示屏"""
        self.expression_var.set(self.current_expression)
        
        # 如果表达式为空,显示0
        if not self.current_expression:
            self.result_var.set("0")
    
    def calculate(self):
        """计算表达式结果"""
        if not self.current_expression:
            return
        
        expression = self.current_expression
        
        # 替换函数调用
        pattern = r'sqrt\(([^)]+)\)'
        while re.search(pattern, expression):
            match = re.search(pattern, expression)
            arg = match.group(1)
            expression = expression.replace(match.group(0), f"math.sqrt({arg})")
        
        # 替换幂运算
        expression = expression.replace('^', '**')
        
        try:
            # 计算表达式
            result = eval(expression)
            
            # 更新历史记录
            self.history.append(f"{self.current_expression} = {result}")
            
            # 更新显示
            self.result_var.set(str(result))
            self.last_result = result
            
            # 如果用户想继续计算,使用结果作为新表达式的开始
            self.current_expression = str(result)
            
        except ZeroDivisionError:
            self.result_var.set("错误: 除数不能为零")
        except Exception as e:
            self.result_var.set(f"错误: {str(e)}")
    
    def show_history(self):
        """显示历史记录"""
        if not self.history:
            tk.messagebox.showinfo("历史记录", "暂无计算历史")
            return
        
        # 创建历史记录窗口
        history_window = tk.Toplevel(self.root)
        history_window.title("计算历史")
        history_window.geometry("400x300")
        history_window.resizable(False, False)
        history_window.configure(bg="#f0f0f0")
        history_window.transient(self.root)  # 使窗口成为主窗口的子窗口
        
        # 创建历史记录列表
        history_text = tk.Text(history_window, font=self.font, bg="white", wrap=tk.WORD)
        history_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # 插入历史记录
        for i, entry in enumerate(self.history, 1):
            history_text.insert(tk.END, f"{i}. {entry}\n\n")
        
        # 使文本框只读
        history_text.config(state=tk.DISABLED)
        
        # 关闭按钮
        close_button = tk.Button(history_window, text="关闭", font=self.font,
                                command=history_window.destroy, bg="#f44336", fg="white")
        close_button.pack(pady=10)

# 启动计算器
if __name__ == "__main__":
    root = tk.Tk()
    app = CalculatorGUI(root)
    root.mainloop()
INFO