如何给python文件打包成exe可执行文件
简易计算器python源代码
思维导图
classDiagram
direction BT
class node0 {
buttons
previous_value
fig
ax
display_rect
display_text_obj
display_text
operation
reset_display
current_value
__init__(self)
create_buttons(self)
button_clicked(self, text)
handle_number(self, num)
handle_decimal(self)
handle_operation(self, op)
handle_equals(self)
handle_clear(self)
handle_sign_change(self)
handle_percent(self)
update_display(self)
show(self)
}
class object {
__doc__
__dict__
__module__
__annotations__
__class__(self)
__class__(self, __type: type[object])
__init__(self)
__new__(cls)
__setattr__(self, __name: str, __value: Any)
__delattr__(self, __name: str)
__eq__(self, __value: object)
__ne__(self, __value: object)
__str__(self)
__repr__(self)
__hash__(self)
__format__(self, __format_spec: str)
__getattribute__(self, __name: str)
__sizeof__(self)
__reduce__(self)
__reduce_ex__(self, __protocol: int)
__dir__(self)
__init_subclass__(cls)
__subclasshook__(cls, __subclass: type)
}
class node1 {
__hash__(self)
}
object --> node0
node1 ..> object
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.widgets import Button
class Calculator:
"""
使用matplotlib实现的图形化计算器类
"""
def __init__(self):
# 计算器状态变量
self.display_text = "0" # 当前显示屏上的文本
self.current_value = 0 # 当前输入的数值
self.previous_value = 0 # 上一个操作数
self.operation = None # 当前操作符
self.reset_display = True # 是否需要重置显示
# 创建图形界面
self.fig, self.ax = plt.subplots(figsize=(8, 10)) # 创建8x10英寸的图形
self.fig.patch.set_facecolor('#2c3e50') # 设置图形背景色为深蓝灰色
self.ax.set_xlim(0, 4) # 设置x轴范围
self.ax.set_ylim(0, 6) # 设置y轴范围
self.ax.axis('off') # 隐藏坐标轴
# 创建显示屏
# 创建一个矩形作为显示屏背景
self.display_rect = patches.Rectangle((0.1, 4.7), 3.8, 1,
linewidth=2, edgecolor='#34495e',
facecolor='#ecf0f1') # 浅灰色背景
self.ax.add_patch(self.display_rect) # 将显示屏添加到图形中
# 创建显示文本对象
self.display_text_obj = self.ax.text(3.8, 5.2, self.display_text,
fontsize=24, ha='right', va='center',
color='#2c3e50', weight='bold') # 右对齐显示
# 创建按钮
self.create_buttons()
def create_buttons(self):
"""
创建计算器的所有按钮
每个按钮包含:文本、行、列、宽度、颜色
"""
# 按钮布局定义:[文本, 行, 列, 宽度, 颜色]
buttons = [
['C', 0, 0, 1, '#e74c3c'], # 清除按钮,红色
['±', 0, 1, 1, '#f39c12'], # 正负号切换,橙色
['%', 0, 2, 1, '#f39c12'], # 百分比,橙色
['÷', 0, 3, 1, '#f39c12'], # 除法,橙色
['7', 1, 0, 1, '#95a5a6'], # 数字7,灰色
['8', 1, 1, 1, '#95a5a6'], # 数字8,灰色
['9', 1, 2, 1, '#95a5a6'], # 数字9,灰色
['×', 1, 3, 1, '#f39c12'], # 乘法,橙色
['4', 2, 0, 1, '#95a5a6'], # 数字4,灰色
['5', 2, 1, 1, '#95a5a6'], # 数字5,灰色
['6', 2, 2, 1, '#95a5a6'], # 数字6,灰色
['-', 2, 3, 1, '#f39c12'], # 减法,橙色
['1', 3, 0, 1, '#95a5a6'], # 数字1,灰色
['2', 3, 1, 1, '#95a5a6'], # 数字2,灰色
['3', 3, 2, 1, '#95a5a6'], # 数字3,灰色
['+', 3, 3, 1, '#f39c12'], # 加法,橙色
['0', 4, 0, 2, '#95a5a6'], # 数字0(双倍宽度),灰色
['.', 4, 2, 1, '#95a5a6'], # 小数点,灰色
['=', 4, 3, 1, '#e67e22'] # 等于,深橙色
]
# 存储按钮对象的字典
self.buttons = {}
# 遍历所有按钮信息并创建按钮
for button_info in buttons:
text, row, col, width, color = button_info
# 计算按钮位置
x = col * 0.9 + 0.15 # x坐标基于列位置计算
y = 3.5 - row * 0.8 # y坐标基于行位置计算(注意y轴方向)
w = width * 0.9 - 0.05 # 按钮宽度
h = 0.7 # 按钮高度
# 创建按钮的坐标轴
# 注意:plt.axes()使用的是图形坐标系(0-1),所以需要归一化
button_ax = plt.axes([x/4, y/6, w/4, h/6])
# 创建按钮对象
button = Button(button_ax, text, color=color, hovercolor='#bdc3c7')
# 设置按钮文本样式
button.label.set_fontsize(18)
button.label.set_weight('bold')
button.label.set_color('white')
# 存储按钮并绑定点击事件
# 使用lambda创建闭包,确保每个按钮传递正确的文本参数
self.buttons[text] = button
button.on_clicked(lambda event, t=text: self.button_clicked(t))
def button_clicked(self, text):
"""
处理按钮点击事件的主函数
根据按钮文本决定执行的操作
"""
try:
# 根据按钮文本类型分发到不同的处理函数
if text.isdigit(): # 数字按钮
self.handle_number(text)
elif text == '.': # 小数点按钮
self.handle_decimal()
elif text in ['+', '-', '×', '÷']: # 运算符按钮
self.handle_operation(text)
elif text == '=': # 等于按钮
self.handle_equals()
elif text == 'C': # 清除按钮
self.handle_clear()
elif text == '±': # 正负号切换按钮
self.handle_sign_change()
elif text == '%': # 百分比按钮
self.handle_percent()
# 更新显示屏并重绘
self.update_display()
plt.draw()
except Exception as e:
# 发生异常时显示错误信息
self.display_text = "Error"
self.update_display()
plt.draw()
def handle_number(self, num):
"""
处理数字按钮点击事件
"""
# 如果需要重置显示或当前显示为0,则替换显示内容
if self.reset_display or self.display_text == "0":
self.display_text = num
self.reset_display = False
else:
# 否则将数字追加到当前显示内容
self.display_text += num
def handle_decimal(self):
"""
处理小数点按钮点击事件
"""
# 如果需要重置显示,则显示"0."
if self.reset_display:
self.display_text = "0."
self.reset_display = False
# 如果当前显示内容不包含小数点,则添加小数点
elif '.' not in self.display_text:
self.display_text += '.'
def handle_operation(self, op):
"""
处理运算符按钮点击事件
"""
# 如果已有操作符且不需要重置显示,则先执行之前的运算
if self.operation and not self.reset_display:
self.handle_equals()
# 保存当前显示值作为前一个操作数
self.previous_value = float(self.display_text)
# 保存当前操作符
self.operation = op
# 设置需要重置显示标志
self.reset_display = True
def handle_equals(self):
"""
处理等于按钮点击事件,执行运算
"""
# 只有当存在操作符时才执行运算
if self.operation:
# 获取当前操作数
current = float(self.display_text)
# 根据操作符执行相应运算
if self.operation == '+':
result = self.previous_value + current
elif self.operation == '-':
result = self.previous_value - current
elif self.operation == '×':
result = self.previous_value * current
elif self.operation == '÷':
# 处理除零错误
if current == 0:
self.display_text = "Error"
self.operation = None
self.reset_display = True
return
result = self.previous_value / current
# 格式化结果:如果是整数则显示为整数,否则显示为浮点数并去除末尾的0
if result == int(result):
self.display_text = str(int(result))
else:
self.display_text = f"{result:.8f}".rstrip('0').rstrip('.')
# 清除操作符并设置重置标志
self.operation = None
self.reset_display = True
def handle_clear(self):
"""
处理清除按钮点击事件,重置计算器状态
"""
self.display_text = "0"
self.current_value = 0
self.previous_value = 0
self.operation = None
self.reset_display = True
def handle_sign_change(self):
"""
处理正负号切换按钮点击事件
"""
# 如果当前值不为0,则切换正负号
if self.display_text != "0":
if self.display_text.startswith('-'):
# 如果是负数,去掉负号
self.display_text = self.display_text[1:]
else:
# 如果是正数,添加负号
self.display_text = '-' + self.display_text
def handle_percent(self):
"""
处理百分比按钮点击事件
"""
# 将当前值除以100得到百分比
value = float(self.display_text)
result = value / 100
# 格式化结果显示
if result == int(result):
self.display_text = str(int(result))
else:
self.display_text = f"{result:.8f}".rstrip('0').rstrip('.')
self.reset_display = True
def update_display(self):
"""
更新显示屏内容
"""
# 限制显示文本长度不超过12个字符
if len(self.display_text) > 12:
self.display_text = self.display_text[:12]
# 更新显示屏文本对象
self.display_text_obj.set_text(self.display_text)
def show(self):
"""
显示计算器界面
"""
plt.tight_layout() # 自动调整布局
plt.show() # 显示图形界面
# 创建并显示计算器
if __name__ == "__main__":
calculator = Calculator()
calculator.show()
pip install pyinstaller -i https://pypi.tuna.tsinghua.edu.cn/simple
EXE 打包命令已执行完成。打包过程通常需要1-3分钟,完成后会在当前目录生成以下文件:
dist/ 文件夹 - 包含生成的 Calculator.exe 可执行文件
build/ 文件夹 - 包含临时构建文件(可安全删除)
Calculator.spec 文件 - 打包配置文件
使用说明:
打包完成后,您可以在 dist/ 文件夹中找到 Calculator.exe
可以直接双击运行,或复制到其他Windows电脑使用
由于程序使用了matplotlib图形界面,首次运行可能需要几秒加载时间
注意事项:
生成的EXE文件较大(约10-50MB),这是包含Python解释器和所有依赖库的正常现象
如需添加程序图标,可以使用 --icon=youricon.ico 参数
如需减小体积,可以使用UPX压缩(需先安装UPX工具)


pyinstaller --onefile --noconsole --name calculator main.py
posted on 2025-09-28 10:34 Indian_Mysore 阅读(7) 评论(0) 收藏 举报
浙公网安备 33010602011771号