|
| 1 | +""" |
| 2 | +打包PDF工具为EXE文件 |
| 3 | +使用方法: 执行此脚本,将在dist目录下生成EXE文件 |
| 4 | +""" |
| 5 | +import os |
| 6 | +import subprocess |
| 7 | +import sys |
| 8 | +import shutil |
| 9 | + |
| 10 | +def build_exe(): |
| 11 | + """使用PyInstaller打包应用程序为EXE文件""" |
| 12 | + print("开始打包PDF工具为可执行文件...") |
| 13 | + |
| 14 | + # 确保PyInstaller已安装 |
| 15 | + try: |
| 16 | + import PyInstaller |
| 17 | + print(f"检测到PyInstaller版本: {PyInstaller.__version__}") |
| 18 | + except ImportError: |
| 19 | + print("未检测到PyInstaller,正在安装...") |
| 20 | + subprocess.check_call([sys.executable, "-m", "pip", "install", "pyinstaller"]) |
| 21 | + print("PyInstaller安装完成") |
| 22 | + |
| 23 | + # 清理之前的构建文件 |
| 24 | + if os.path.exists("build"): |
| 25 | + shutil.rmtree("build") |
| 26 | + if os.path.exists("dist"): |
| 27 | + shutil.rmtree("dist") |
| 28 | + |
| 29 | + # 检查是否有图标文件,如果没有尝试创建一个 |
| 30 | + if not os.path.exists("icon.ico"): |
| 31 | + print("未找到icon.ico文件,尝试创建默认图标...") |
| 32 | + try: |
| 33 | + # 如果有PIL库,尝试创建一个图标 |
| 34 | + from PIL import Image, ImageDraw, ImageFont |
| 35 | + |
| 36 | + # 创建一个512x512的图标 |
| 37 | + icon_size = 512 |
| 38 | + icon = Image.new('RGBA', (icon_size, icon_size), (255, 255, 255, 0)) |
| 39 | + draw = ImageDraw.Draw(icon) |
| 40 | + |
| 41 | + # 绘制背景 |
| 42 | + draw.rectangle([(0, 0), (icon_size, icon_size)], fill=(52, 152, 219, 255)) |
| 43 | + |
| 44 | + # 绘制PDF字样 |
| 45 | + try: |
| 46 | + # 尝试使用一个常见字体 |
| 47 | + font = ImageFont.truetype("arial.ttf", int(icon_size/2)) |
| 48 | + except IOError: |
| 49 | + # 如果找不到字体,使用默认字体 |
| 50 | + font = ImageFont.load_default() |
| 51 | + |
| 52 | + # 在图标中央绘制文字 |
| 53 | + draw.text((icon_size/2, icon_size/2), "PDF", fill=(255, 255, 255, 255), |
| 54 | + font=font, anchor="mm") |
| 55 | + |
| 56 | + # 保存为ICO文件 |
| 57 | + icon.save("icon.ico") |
| 58 | + print("成功创建默认图标") |
| 59 | + except Exception as e: |
| 60 | + print(f"创建图标失败: {str(e)}") |
| 61 | + print("将使用无图标方式打包") |
| 62 | + use_icon = False |
| 63 | + else: |
| 64 | + use_icon = True |
| 65 | + else: |
| 66 | + use_icon = True |
| 67 | + |
| 68 | + # 创建spec文件内容 |
| 69 | + if use_icon: |
| 70 | + # 使用图标的spec配置 |
| 71 | + spec_content = """ |
| 72 | +# -*- mode: python ; coding: utf-8 -*- |
| 73 | +
|
| 74 | +block_cipher = None |
| 75 | +
|
| 76 | +a = Analysis( |
| 77 | + ['pdf_tool_gui.py'], |
| 78 | + pathex=[], |
| 79 | + binaries=[], |
| 80 | + datas=[], |
| 81 | + hiddenimports=[], |
| 82 | + hookspath=[], |
| 83 | + hooksconfig={}, |
| 84 | + runtime_hooks=[], |
| 85 | + excludes=[], |
| 86 | + win_no_prefer_redirects=False, |
| 87 | + win_private_assemblies=False, |
| 88 | + cipher=block_cipher, |
| 89 | + noarchive=False, |
| 90 | +) |
| 91 | +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) |
| 92 | +
|
| 93 | +exe = EXE( |
| 94 | + pyz, |
| 95 | + a.scripts, |
| 96 | + a.binaries, |
| 97 | + a.zipfiles, |
| 98 | + a.datas, |
| 99 | + [], |
| 100 | + name='PDF工具', |
| 101 | + debug=False, |
| 102 | + bootloader_ignore_signals=False, |
| 103 | + strip=False, |
| 104 | + upx=True, |
| 105 | + upx_exclude=[], |
| 106 | + runtime_tmpdir=None, |
| 107 | + console=False, |
| 108 | + disable_windowed_traceback=False, |
| 109 | + argv_emulation=False, |
| 110 | + target_arch=None, |
| 111 | + codesign_identity=None, |
| 112 | + entitlements_file=None, |
| 113 | + icon='icon.ico', |
| 114 | +) |
| 115 | +""" |
| 116 | + else: |
| 117 | + # 不使用图标的spec配置 |
| 118 | + spec_content = """ |
| 119 | +# -*- mode: python ; coding: utf-8 -*- |
| 120 | +
|
| 121 | +block_cipher = None |
| 122 | +
|
| 123 | +a = Analysis( |
| 124 | + ['pdf_tool_gui.py'], |
| 125 | + pathex=[], |
| 126 | + binaries=[], |
| 127 | + datas=[], |
| 128 | + hiddenimports=[], |
| 129 | + hookspath=[], |
| 130 | + hooksconfig={}, |
| 131 | + runtime_hooks=[], |
| 132 | + excludes=[], |
| 133 | + win_no_prefer_redirects=False, |
| 134 | + win_private_assemblies=False, |
| 135 | + cipher=block_cipher, |
| 136 | + noarchive=False, |
| 137 | +) |
| 138 | +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) |
| 139 | +
|
| 140 | +exe = EXE( |
| 141 | + pyz, |
| 142 | + a.scripts, |
| 143 | + a.binaries, |
| 144 | + a.zipfiles, |
| 145 | + a.datas, |
| 146 | + [], |
| 147 | + name='PDF工具', |
| 148 | + debug=False, |
| 149 | + bootloader_ignore_signals=False, |
| 150 | + strip=False, |
| 151 | + upx=True, |
| 152 | + upx_exclude=[], |
| 153 | + runtime_tmpdir=None, |
| 154 | + console=False, |
| 155 | + disable_windowed_traceback=False, |
| 156 | + argv_emulation=False, |
| 157 | + target_arch=None, |
| 158 | + codesign_identity=None, |
| 159 | + entitlements_file=None, |
| 160 | +) |
| 161 | +""" |
| 162 | + |
| 163 | + # 写入spec文件 |
| 164 | + with open("pdf_tool.spec", "w", encoding="utf-8") as f: |
| 165 | + f.write(spec_content) |
| 166 | + |
| 167 | + print("生成配置文件完成,开始打包...") |
| 168 | + |
| 169 | + # 执行PyInstaller命令 |
| 170 | + subprocess.check_call([ |
| 171 | + sys.executable, |
| 172 | + "-m", |
| 173 | + "PyInstaller", |
| 174 | + "--clean", |
| 175 | + "pdf_tool.spec" |
| 176 | + ]) |
| 177 | + |
| 178 | + print("\n打包完成! 可执行文件已生成在dist目录中。") |
| 179 | + print("您可以在dist文件夹中找到 'PDF工具.exe' 文件") |
| 180 | + print("\n注意事项:") |
| 181 | + print("1. 首次启动可能较慢,这是正常现象") |
| 182 | + print("2. 杀毒软件可能会对生成的EXE进行检查,这是因为打包工具的特性") |
| 183 | + print("3. 确保最终用户电脑上安装了适当的字体,否则可能会影响界面显示") |
| 184 | + |
| 185 | +if __name__ == "__main__": |
| 186 | + build_exe() |
0 commit comments