PyInstaller打包后调用Python3.7.2脚本遇Tcl版本冲突求助
问题描述
- 本地安装Python 3.9.0,编写
script.py后用PyInstaller打包为script.exe script.py通过以下代码调用batch_file.bat执行A.py:
process = subprocess.Popen(batch_file.bat, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
- 项目要求
batch_file.bat使用Python 3.7.2运行A.py,bat内容:
%DIR_PYTHON_3_7_2%\python.exe %ITS_DIR%/A.py
- 打包后运行
script.exe出现Tcl版本冲突错误,直接运行脚本无问题;因依赖库限制无法降级本地Python 3.9.0,修改init.tcl版本号或调整subprocess方法均无效。
报错信息
File "D:\Tool\Common\python\v3.7.2\lib\site-packages\matplotlib\pyplot.py", line 809, in figure FigureClass=FigureClass, **kwargs) File "D:\Tool\Common\python\v3.7.2\lib\site-packages\matplotlib\pyplot.py", line 325, in new_figure_manager return _get_backend_mod().new_figure_manager(*args, **kwargs) File "D:\Tool\Common\python\v3.7.2\lib\site-packages\matplotlib\backend_bases.py", line 3494, in new_figure_manager return cls.new_figure_manager_given_figure(num, fig) File "D:\Tool\Common\python\v3.7.2\lib\site-packages\matplotlib\backends\_backend_tk.py", line 949, in new_figure_manager_given_figure window = tk.Tk(className="matplotlib") File "D:\Tool\Common\python\v3.7.2\lib\tkinter\__init__.py", line 2023, in __init__ self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) _tkinter.TclError: Can't find a usable init.tcl in the following directories: {C:\Users\xxxx\AppData\Local\Temp\_MEI208802\tcl} C:/Users/xxx/AppData/Local/Temp/_MEI208802/tcl8.6 D:/Tool/Common/python/v3.7.2/lib/tcl8.6 D:/Tool/Common/python/lib/tcl8.6 D:/Tool/Common/lib/tcl8.6 D:/Tool/Common/python/library D:/Tool/Common/library D:/Tool/Common/tcl8.6.8/library D:/Tool/tcl8.6.8/library C:/Users/xxx/AppData/Local/Temp/_MEI208802/tcl/init.tcl: version conflict for package "Tcl": have 8.6.8, need 8.6.9 version conflict for package "Tcl": have 8.6.8, need 8.6.9 while executing "package require Tcl 8.6.9" (file "C:/Users/xxx/AppData/Local/Temp/_MEI208802/tcl/init.tcl" line 19) invoked from within "source C:/Users/xxx/AppData/Local/Temp/_MEI208802/tcl/init.tcl" ("uplevel" body line 1) invoked from within "uplevel #0 [list source $tclfile]" This probably means that Tcl wasn't installed properly.
解决方案
方法1:清理subprocess调用的环境变量
PyInstaller打包后会将Python 3.9.0的Tcl/Tk路径注入环境变量,导致子进程调用的Python 3.7.2加载错误版本的Tcl。修改script.py中的调用代码,移除相关环境变量:
import os import subprocess # 复制当前环境并清理Tcl/Tk相关变量 new_env = os.environ.copy() for key in list(new_env.keys()): if key in ('TCL_LIBRARY', 'TK_LIBRARY', 'PYTHONHOME'): del new_env[key] # 使用清理后的环境调用bat文件 process = subprocess.Popen(batch_file.bat, env=new_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
此方法让子进程优先使用Python 3.7.2自带的Tcl/Tk库,避免版本冲突。
方法2:在bat文件中强制指定Tcl路径
在batch_file.bat开头添加环境变量设置,明确指向Python 3.7.2的Tcl/Tk目录:
@echo off set TCL_LIBRARY=D:\Tool\Common\python\v3.7.2\tcl\tcl8.6 set TK_LIBRARY=D:\Tool\Common\python\v3.7.2\tcl\tk8.6 %DIR_PYTHON_3_7_2%\python.exe %ITS_DIR%/A.py
注意路径需与Python 3.7.2安装目录下的实际路径保持一致。
方法3:打包时排除Tcl/Tk模块
如果主脚本script.py不需要使用Tkinter,打包时直接排除相关模块,避免PyInstaller将Python 3.9.0的Tcl文件打包进去:
pyinstaller --exclude-module tkinter --exclude-module tcl script.py
内容的提问来源于stack exchange,提问作者nazirul othman
相关产品推荐
相关产品推荐

