From b25f9f97b5e34cd1415e73d5f87b226b5c219d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=B2=81=E5=AD=A6=E5=9D=A4?= Date: Sat, 19 Apr 2025 23:26:19 +0800 Subject: [PATCH] first commit --- .gitignore | 4 + .idea/.gitignore | 3 + .idea/calculator.iml | 10 + .idea/inspectionProfiles/Project_Default.xml | 12 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + README.md | 88 ++++++ calculator.py | 288 ++++++++++++++++++ screenshot.png | Bin 0 -> 28297 bytes 11 files changed, 431 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/calculator.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 README.md create mode 100644 calculator.py create mode 100644 screenshot.png diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ecb2c23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.venv/ +__pycache__/ +.pytest_cache/ +.idea/ diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/calculator.iml b/.idea/calculator.iml new file mode 100644 index 0000000..52ee91d --- /dev/null +++ b/.idea/calculator.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..4f33806 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..ff2a428 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..6aa3d5c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..503c67f --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +# 简易计算器GUI程序 + +![Calculator Screenshot](screenshot.png) + +[![Python Version](https://img.shields.io/badge/python-3.7%2B-blue)](https://www.python.org/) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +## 功能特性 + +- **四则运算**:支持加(+)、减(-)、乘(×)、除(÷)基本运算 +- **连续计算**:自动保留计算结果用于后续运算 +- **智能显示**: + - 自动去除小数点后多余的零 + - 大数字自动适应显示区域 +- **错误处理**: + - 除零错误检测与提示 + - 无效操作拦截 + - 异常崩溃防护 +- **交互设计**: + - 退格键(←)支持 + - 一键清零(C)功能 + - 实时输入反馈 +- **界面特性**: + - 半透明窗口效果 + - 响应式布局 + - 中文宋体显示 + +## 快速开始 + +### 环境要求 +- Python 3.7+ +- Tkinter(通常随Python默认安装) + +### 安装与运行 +```bash +1. 克隆仓库 +git clone https://github.com/yourusername/calculator-gui.git +2. 进入项目目录 +cd calculator-gui +3. 运行程序 +python calculator.py +``` + + +## 技术细节 + +### 技术栈 +- **核心框架**: Python标准库 Tkinter +- **状态管理**: 全局变量跟踪模式 +- **错误处理**: Try/Except异常捕获机制 +- **界面布局**: Grid网格布局系统 + +### 项目结构 +```python +calculator.py +├── 全局状态变量 # current_input, first_operand, operator +├── 样式配置常量 # COLORS, FONT, LAYOUT +├── 事件处理函数 # on_number_click, on_operator_click, calculate等 +├── UI构建模块 # 结果显示区、操作按钮矩阵、等号按钮 +└── 主程序循环 # root.mainloop() +``` + +## 版本历史 + +| 版本号 | 作者 | 发布日期 | 主要变更 | +|--------|----|------------|----------------------| +| v1.0.0 | 鲁豫 | 2025-04-15 | 完善代码注释和结构 | + + +## 贡献指南 + +欢迎通过以下方式参与项目改进: +1. 提交Issue报告问题 +2. Fork仓库并提交Pull Request +3. 优化代码注释或文档 + +**开发团队**: +- 程序员:鲁豫 \<2085520973@qq.com> +- 代码审核:Xuekun Lu \ + +## 学习资源 + +- [Tkinter官方文档](https://docs.python.org/3/library/tkinter.html) +- [Python异常处理指南](https://docs.python.org/3/tutorial/errors.html) +- [GUI设计最佳实践](https://learn.microsoft.com/zh-cn/windows/win32/uxguide/guidelines) + +## 许可证 +本项目基于 [MIT License](LICENSE) 开源 diff --git a/calculator.py b/calculator.py new file mode 100644 index 0000000..4d31952 --- /dev/null +++ b/calculator.py @@ -0,0 +1,288 @@ +""" +简易计算器GUI程序 +[版本信息] +版本号 | 日期 | 作者 | 修改摘要 +----------|------------|------------|------------------ +v1.0.0 | 2025-04-19 | 鲁豫 | 初始版本,实现基本加减法功能 + +[作者信息] +开发团队:Python学习 +程序员:鲁豫<2085520973@qq.com> +代码审核:Xuekun Lu +GitHub仓库:https://github.com/learn-python/calculator-gui +版权声明:本代码遵循MIT开源协议 + +[功能说明] +实现带图形界面的四则运算计算器,支持以下特性: +1. 基础运算:加减乘除 +2. 连续运算功能 +3. 错误处理机制 +4. 历史记录显示(开发中) + +代码结构说明: + 1.全局状态:使用三个变量跟踪计算器状态 + 2.样式配置:集中管理颜色、字体等视觉元素 + 3.事件处理:5个函数处理不同按钮的点击逻辑 + 4.界面构建:分模块创建各个界面组件 + 5.布局管理:使用grid布局实现计算器按键矩阵 + +学习重点: + 1.StringVar的使用:实现显示内容的动态更新 + 2.lambda表达式:用于传递参数的按钮命令绑定 + 3.全局状态管理:如何处理连续运算的中间状态 + 4.异常处理:保证程序在错误输入时不会崩溃 + 5.布局技巧:grid布局的跨列(rowspan)和跨行(columnspan)使用 + +测试建议: + 1.测试乘法:5 × 3 = 15 + 2.测试除法:9 ÷ 3 = 3 + 3.测试除零:5 ÷ 0 → 显示"除零错误" + 4.连续运算测试:2 + 3 = 5 → × 4 = 20 +""" + +# 导入Tkinter图形界面库(Python标准库) +import tkinter as tk + +# ==================== 全局状态变量 ==================== +# 这些变量用于跟踪计算器的当前状态 +current_input = "" # 存储用户当前输入的数字(字符串形式,如"12.34") +first_operand = None # 存储第一个运算数字(当用户点击运算符时保存) +operator = None # 存储当前选择的运算符(+/-等) + +# ==================== 界面样式常量配置 ==================== +# 使用字典统一管理样式,方便后期修改和维护 +COLORS = { + 'operator': '#b1b2b2', # 运算符按钮背景色(浅灰色) + 'number': '#eacda1', # 数字按钮背景色(米黄色) + 'equal': '#eacda1' # 等号按钮背景色(与数字键相同) +} + +FONT = { + 'main': ('宋体', 20), # 显示屏字体(字体,字号) + 'button': ('宋体', 16) # 按钮字体 +} + +LAYOUT = { + 'pad': 4, # 按钮之间的水平间距(单位:像素) + 'margin': 2 # 按钮之间的垂直间距 +} + + +# ==================== 事件处理函数 ==================== +# 以下函数用于响应按钮点击事件 + +def on_number_click(char): + """处理数字和小数点按钮点击事件 + 参数:char - 按钮对应的字符(0-9 或 .) + """ + global current_input # 声明使用全局变量 + + # 处理小数点输入限制 + if char == '.' and '.' in current_input: + return # 如果已包含小数点,不做任何操作 + + current_input += char # 将新字符追加到当前输入 + result_var.set(current_input) # 更新显示屏内容 + + +def on_operator_click(op): + """处理运算符按钮点击事件(+/-/*//) + 参数:op - 运算符符号(字符串) + """ + global first_operand, operator, current_input + + if current_input: # 确保有输入值时才执行 + first_operand = float(current_input) # 将当前输入转为浮点数存储 + operator = op # 记录运算符 + current_input = "" # 清空当前输入,准备接收第二个数字 + result_var.set(op) # 在显示屏显示当前运算符 + + +def calculate(): + """执行计算并显示结果""" + global current_input, first_operand, operator + + # 有效性检查:确保三个要素都存在 + if first_operand is None or operator is None or not current_input: + return + + try: + second_operand = float(current_input) # 将当前输入转为浮点数 + + # 根据运算符执行计算(新增乘除运算) + if operator == '+': + result = first_operand + second_operand + elif operator == '-': + result = first_operand - second_operand + elif operator == '*': + result = first_operand * second_operand + elif operator == '/': + if second_operand == 0: + raise ZeroDivisionError + result = first_operand / second_operand + else: + return # 无效运算符 + + # 格式化显示结果:整数去零,小数保留10位 + if result.is_integer(): + current_input = str(int(result)) # 5.0 → 5 + else: + # 去除末尾多余的零和小数点 + formatted = "{:.10f}".format(result).rstrip('0').rstrip('.') + current_input = formatted if formatted else "0" + + result_var.set(current_input) # 更新显示 + + # 保留计算结果作为下一次运算的第一个操作数 + first_operand = float(current_input) + operator = None # 重置运算符需手动选择 + + except ZeroDivisionError: + result_var.set("除零错误") + # reset_calculator() + except Exception as e: + result_var.set("错误"+e.__cause__) # 显示错误提示 + # reset_calculator() # 重置计算器 + + +def reset_calculator(): + """重置所有状态到初始值""" + global current_input, first_operand, operator + current_input = "" + first_operand = None + operator = None + result_var.set('0') # 显示屏归零 + + +def backspace(): + """删除最后一个输入的字符""" + global current_input + if current_input: + current_input = current_input[:-1] # 移除最后一个字符 + result_var.set(current_input if current_input else '0') # 显示剩余内容或0 + + +# ==================== 主窗口初始化 ==================== +# 创建主窗口并设置基本属性 +root = tk.Tk() # 创建Tkinter主窗口对象 +root.title('简易计算器') # 窗口标题 +root.geometry('295x280+100+100') # 窗口尺寸(宽x高)和初始位置(x+y) +root.attributes("-alpha", 0.9) # 设置窗口透明度(0.0完全透明-1.0不透明) + +# ==================== 结果显示区域 ==================== +# 使用StringVar实现动态更新显示内容 +result_var = tk.StringVar(value='0') # 创建绑定到显示区域的变量 + +# 创建显示标签(显示屏) +display = tk.Label( + root, + textvariable=result_var, # 绑定动态变量 + font=FONT['main'], # 使用主字体 + height=2, # 高度(行数) + width=20, # 宽度(字符数) + justify=tk.LEFT, # 文本左对齐 + anchor=tk.SE # 文本定位到右下角(东南角) +) +# 使用grid布局管理器定位,跨4列显示 +display.grid(row=1, column=1, columnspan=4) + +# ==================== 操作符按钮行 ==================== +# 定义第一行操作符按钮的配置(清除、退格、除、乘) +operator_buttons = [ + # 格式:(显示文本, 行号, 列号, 点击命令) + ('c', 2, 1, reset_calculator), # 清除按钮 + ('←', 2, 2, backspace), # 退格按钮 + ('/', 2, 3, lambda: on_operator_click('/')), # 除法按钮 + ('×', 2, 4, lambda: on_operator_click('*')) # 乘法按钮 +] + +# 批量创建操作符按钮 +for text, row, col, command in operator_buttons: + tk.Button( + root, + text=text, + width=5, # 按钮宽度(字符数) + font=FONT['button'], # 使用按钮字体 + relief=tk.FLAT, # 扁平化按钮样式 + bg=COLORS['operator'], # 设置背景色 + command=command # 绑定点击事件处理函数 + ).grid( + row=row, + column=col, + padx=LAYOUT['pad'], + pady=LAYOUT['margin'] + ) + +# ==================== 数字按钮布局 ==================== +# 定义数字按钮的布局配置(使用嵌套元组) +button_configs = [ + # 每行按钮配置(格式:(按钮1配置, 按钮2配置, ...)) + # 第三行:7、8、9、减号 + (('7', 3, 1), ('8', 3, 2), ('9', 3, 3), ('-', 3, 4, lambda: on_operator_click('-'))), + # 第四行:4、5、6、加号 + (('4', 4, 1), ('5', 4, 2), ('6', 4, 3), ('+', 4, 4, lambda: on_operator_click('+'))), + # 第五行:1、2、3 + (('1', 5, 1), ('2', 5, 2), ('3', 5, 3)), + # 第六行:0、小数点 + (('0', 6, 1), ('.', 6, 3)) +] + +# 遍历配置创建数字按钮 +for row_group in button_configs: + for config in row_group: + # 解析按钮配置 + parts = list(config) + text, row, col = parts[0:3] # 前三个元素固定 + + # 确定点击命令:数字/小数点调用on_number_click,运算符调用on_operator_click + command = parts[3] if len(parts) > 3 else (lambda t=text: on_number_click(t)) + + # 创建按钮对象 + btn = tk.Button( + root, + text=text, + width=5 if text != '0' else 12, # 0按钮特殊宽度 + font=FONT['button'], + relief=tk.FLAT, + bg=COLORS['number'] if text in '1234567890.' else COLORS['operator'], + command=command # 绑定点击事件 + ) + + # 布局按钮(0按钮需要跨列) + if text == '0': + btn.grid( + row=row, + column=col, + columnspan=2, # 跨2列 + padx=LAYOUT['pad'], + pady=LAYOUT['margin'] + ) + else: + btn.grid( + row=row, + column=col, + padx=LAYOUT['pad'], + pady=LAYOUT['margin'] + ) + +# ==================== 等号按钮 ==================== +# 创建特殊尺寸的等号按钮 +tk.Button( + root, + text='=', + width=5, # 宽度(字符数) + height=3, # 高度(行数) + font=FONT['button'], + relief=tk.FLAT, + bg=COLORS['equal'], # 使用等号专用颜色 + command=calculate # 绑定计算函数 +).grid( + row=5, + column=4, + rowspan=2, # 跨5-6两行 + padx=LAYOUT['pad'], + pady=LAYOUT['margin'] +) + +# ==================== 启动程序 ==================== +root.mainloop() # 进入Tkinter事件循环,等待用户操作 diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..53ba13024bbb4df386c80eed1b455bdfeb962537 GIT binary patch literal 28297 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