PyInstaller生成的程序在macOS上无法运行的问题求助
问题排查与解决方案
一、先修复代码本身的致命错误
你的代码存在几个直接导致运行崩溃的问题:
- 未定义
getCoins()函数:代码中调用了coins = getCoins()但没有实现这个函数,运行时会直接抛出NameError。以下是基于CoinGecko API的示例实现(需根据你的币种需求调整):def getCoins(): import requests # 示例API请求,可添加你需要的币种id url = "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=bitcoin,ethereum,ripple" response = requests.get(url) # 转换为按币种名称索引的字典,匹配你的nameList coin_dict = {coin['name']: [coin] for coin in response.json()} return coin_dict - Button组件父对象错误:
main()函数里tk.Button(prices, ...)中的prices变量还未定义,应使用root作为父组件:prices = tk.Button(root, text="Prices", command=getPrices) - 文件路径与未定义变量问题:
- 打包后
Monitoring.xlsx的相对路径会失效,需通过PyInstaller提供的sys._MEIPASS获取资源路径; getPrices()函数中sheet变量未定义,需先指定工作表。
- 打包后
修改后的文件路径处理与工作表代码:
import sys import os # 获取资源路径(兼容开发/打包后环境) def get_resource_path(relative_path): try: base_path = sys._MEIPASS # 打包后的临时资源路径 except Exception: base_path = os.path.abspath(".") # 开发时的本地路径 return os.path.join(base_path, relative_path) # 替换原Excel读取代码 excel_path = get_resource_path('Monitoring.xlsx') df = pd.read_excel(excel_path) nameList = df['Unnamed: 2'].tolist()[1:23] def getPrices(): prices = OrderedDict() coinPrice = [] coins = getCoins() for name in nameList: prices[name] = "" for coin in prices.keys(): prices[coin] = coins[coin][0]["quote"]["USD"]["price"] for item in prices.items(): coinPrice.append(item[1]) workbook = op.load_workbook(excel_path) sheet = workbook.active # 或指定具体工作表名,如workbook['Sheet1'] for x in range(0, len(coinPrice)): sheet["O" + str(x+3)] = coinPrice[x] workbook.save(excel_path)
二、修正PyInstaller配置(.spec文件)
打包时需确保依赖和资源文件被正确包含:
- 添加资源文件:在
Analysis的datas中加入Excel文件,格式为(源文件路径, 目标路径); - 添加隐藏依赖:pandas、openpyxl等库可能需要显式指定
hiddenimports,避免打包后找不到模块; - 开启控制台调试:暂时将
console=False改为console=True,方便查看运行时错误信息。
修改后的完整.spec文件:
# -*- mode: python ; coding: utf-8 -*- import sys from os.path import abspath a = Analysis( ['monitoring.py'], pathex=[abspath('.')], binaries=[], datas=[('Monitoring.xlsx', '.')], hiddenimports=['pandas', 'openpyxl', 'requests', 'pytrends', 'tkinter'], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], noarchive=False, ) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.datas, [], name='Monitoring', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=True, # 调试阶段开启,正常运行后改回False disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, ) app = BUNDLE( exe, name='Monitoring.app', icon=None, bundle_identifier=None, )
三、打包与测试步骤
- 先在开发环境运行修复后的Python脚本,确保无报错;
- 使用修改后的.spec文件重新打包:
pyinstaller Monitoring.spec - 运行
dist/Monitoring.app,通过控制台输出排查剩余问题(如缺少依赖则添加到hiddenimports); - 确认.app正常运行后,将
console=True改回console=False重新打包; - 生成.dmg文件:可通过系统磁盘工具手动创建,或用
create-dmg工具自动化生成:create-dmg --volname "Monitoring" --window-pos 200 120 --window-size 600 300 --icon-size 100 --icon "Monitoring.app" 175 120 --hide-extension "Monitoring.app" --app-drop-link 425 120 "Monitoring.dmg" "dist/"
四、其他注意事项
- 更新所有依赖库到最新版本,避免兼容性问题:
pip install --upgrade pandas openpyxl requests pytrends pyinstaller - 若尝试py2app,核心问题仍是代码错误与资源路径处理,需在
setup.py中配置资源文件与隐藏依赖,建议先解决代码问题后再尝试。
内容的提问来源于stack exchange,提问作者Martín Rodas
相关产品推荐
相关产品推荐

