import tkinter as tk
from tkinter import messagebox

class Calculator:
    def __init__(self, master):
        self.master = master
        master.title("Python 计算器")
        master.geometry("300x400") # 设置窗口初始大小
        master.resizable(False, False) # 禁止调整窗口大小

        # 状态变量
        self.current_expression = tk.StringVar(value="0") # 显示屏上的当前表达式
        self.first_operand = None    # 存储第一个操作数
        self.operator = None         # 存储操作符
        self.waiting_for_second_operand = False # 标记是否正在等待第二个操作数

        # 配置字体和样式
        self.font_display = ('Arial', 24)
        self.font_button = ('Arial', 16)
        self.bg_color = "#f0f0f0" # 浅灰色背景
        self.button_color = "#e0e0e0" # 按钮颜色
        self.operator_color = "#ff9900" # 橙色运算符
        self.equal_color = "#4CAF50" # 绿色等号
        self.clear_color = "#f44336" # 红色清除

        master.configure(bg=self.bg_color)

        # 创建显示屏
        self.display = tk.Entry(master,
                                textvariable=self.current_expression,
                                font=self.font_display,
                                bd=10,
                                relief=tk.FLAT, # 扁平边框
                                justify='right', # 右对齐
                                bg="#ffffff", # 白色背景
                                fg="#333333") # 深灰色文字
        self.display.grid(row=0, column=0, columnspan=4, sticky="nsew", padx=5, pady=5)

        # 按钮布局
        # 定义按钮文本、行、列、颜色和对应的命令
        buttons = [
            ('C', 1, 0, self.clear_color, self.clear_all),
            ('Del', 1, 1, self.clear_color, self.backspace),
            ('/', 1, 2, self.operator_color, lambda: self.operator_click('/')),
            ('*', 1, 3, self.operator_color, lambda: self.operator_click('*')),

            ('7', 2, 0, self.button_color, lambda: self.number_click('7')),
            ('8', 2, 1, self.button_color, lambda: self.number_click('8')),
            ('9', 2, 2, self.button_color, lambda: self.number_click('9')),
            ('-', 2, 3, self.operator_color, lambda: self.operator_click('-')),

            ('4', 3, 0, self.button_color, lambda: self.number_click('4')),
            ('5', 3, 1, self.button_color, lambda: self.number_click('5')),
            ('6', 3, 2, self.button_color, lambda: self.number_click('6')),
            ('+', 3, 3, self.operator_color, lambda: self.operator_click('+')),

            ('1', 4, 0, self.button_color, lambda: self.number_click('1')),
            ('2', 4, 1, self.button_color, lambda: self.number_click('2')),
            ('3', 4, 2, self.button_color, lambda: self.number_click('3')),
            ('=', 4, 3, self.equal_color, self.calculate), # 等号按钮

            ('0', 5, 0, self.button_color, lambda: self.number_click('0')),
            ('.', 5, 2, self.button_color, lambda: self.number_click('.')),
        ]

        # 创建并放置按钮
        for (text, row, col, color, command) in buttons:
            if text == '0': # '0' 按钮跨两列
                btn = tk.Button(master, text=text, font=self.font_button, bg=color, fg="#333333",
                                command=command, relief=tk.FLAT, bd=1)
                btn.grid(row=row, column=col, columnspan=2, sticky="nsew", padx=2, pady=2)
            elif text == '=': # '=' 按钮跨两行
                 btn = tk.Button(master, text=text, font=self.font_button, bg=color, fg="#ffffff",
                                command=command, relief=tk.FLAT, bd=1)
                 btn.grid(row=row, column=col, rowspan=2, sticky="nsew", padx=2, pady=2)
            else:
                btn = tk.Button(master, text=text, font=self.font_button, bg=color, fg="#333333",
                                command=command, relief=tk.FLAT, bd=1)
                btn.grid(row=row, column=col, sticky="nsew", padx=2, pady=2)

        # 配置行和列的权重，使其在窗口调整大小时能够伸缩
        for i in range(6): # 6 行 (0-5)
            master.grid_rowconfigure(i, weight=1)
        for i in range(4): # 4 列 (0-3)
            master.grid_columnconfigure(i, weight=1)

    def number_click(self, num):
        """处理数字按钮和小数点按钮的点击事件"""
        current = self.current_expression.get()

        if self.waiting_for_second_operand:
            # 如果正在等待第二个操作数，则清除显示并开始新数字
            self.current_expression.set(num)
            self.waiting_for_second_operand = False
        else:
            # 否则，追加数字
            if num == '.':
                if '.' in current: # 避免多个小数点
                    return
                if current == '0': # 如果当前是0，输入.变成0.
                    self.current_expression.set("0.")
                    return

            if current == '0' and num != '.': # 如果当前是0，且输入的不是小数点，则替换0
                self.current_expression.set(num)
            else:
                self.current_expression.set(current + num)

    def operator_click(self, op):
        """处理运算符按钮的点击事件"""
        try:
            current_value = float(self.current_expression.get())
        except ValueError:
            messagebox.showerror("错误", "无效的数字输入")
            self.clear_all()
            return

        if self.first_operand is None:
            # 如果是第一次输入操作数，则存储当前值
            self.first_operand = current_value
        elif not self.waiting_for_second_operand:
            # 如果不是第一次，且不是在等待第二个操作数（即连续输入运算符），则先计算
            self.calculate()
            self.first_operand = float(self.current_expression.get()) # 使用计算结果作为新的first_operand

        self.operator = op
        self.waiting_for_second_operand = True # 设置为等待第二个操作数

    def calculate(self):
        """处理等号按钮的点击事件，执行计算"""
        if self.first_operand is None or self.operator is None:
            return # 没有足够的信息进行计算

        try:
            second_operand = float(self.current_expression.get())
        except ValueError:
            messagebox.showerror("错误", "无效的数字输入")
            self.clear_all()
            return

        result = 0
        try:
            if self.operator == '+':
                result = self.first_operand + second_operand
            elif self.operator == '-':
                result = self.first_operand - second_operand
            elif self.operator == '*':
                result = self.first_operand * second_operand
            elif self.operator == '/':
                if second_operand == 0:
                    messagebox.showerror("错误", "除数不能为零！")
                    self.clear_all()
                    return
                result = self.first_operand / second_operand

            # 格式化结果，避免浮点数精度问题，并去除不必要的.0
            if result == int(result):
                self.current_expression.set(str(int(result)))
            else:
                self.current_expression.set(str(result))

        except Exception as e:
            messagebox.showerror("错误", f"计算出错: {e}")
            self.clear_all()
            return

        # 重置状态，为下一次计算做准备
        self.first_operand = None
        self.operator = None
        self.waiting_for_second_operand = True # 结果显示后，下一个数字会开始新计算

    def clear_all(self):
        """清除所有输入和状态"""
        self.current_expression.set("0")
        self.first_operand = None
        self.operator = None
        self.waiting_for_second_operand = False

    def backspace(self):
        """删除显示屏上的最后一个字符"""
        current = self.current_expression.get()
        if len(current) > 1:
            self.current_expression.set(current[:-1])
        else:
            self.current_expression.set("0")

#设置窗口初始大小
#禁止调整窗口大小

#状态变量
#显示屏上的当前表达式
#存储第一个操作数
#存储操作符
#标记是否正在等待第二个操作数

#配置字体和样式

#浅灰色背景
#按钮颜色
#橙色运算符
#绿色等号
#红色清除

#创建显示屏

#扁平边框
#右对齐
#白色背景
#深灰色文字

#按钮布局
#定义按钮文本、行、列、颜色和对应的命令

#等号按钮

#创建并放置按钮

#'0' 按钮跨两列

#'=' 按钮跨两行

#配置行和列的权重，使其在窗口调整大小时能够伸缩
#6 行 (0-5)

#4 列 (0-3)

#如果正在等待第二个操作数，则清除显示并开始新数字

#否则，追加数字

#避免多个小数点

#如果当前是0，输入.变成0.

#如果当前是0，且输入的不是小数点，则替换0

#如果是第一次输入操作数，则存储当前值

#如果不是第一次，且不是在等待第二个操作数（即连续输入运算符），则先计算

#使用计算结果作为新的first_operand

#设置为等待第二个操作数

#没有足够的信息进行计算

#格式化结果，避免浮点数精度问题，并去除不必要的.0

#重置状态，为下一次计算做准备

#结果显示后，下一个数字会开始新计算

#主程序入口
if (__name__ == '__main__'):
    root = tk.Tk()
    my_calculator = Calculator(root)
    root.mainloop()
