各种查资料,解决了在conda多python版本环境下,Qt里Embedding Python的问题(WIN10)
C++调用Python,需要指定正确的环境变量PYTHONHOME
。
如果你指定错了,程序会无报错地crashed;
如果你压根没指定,程序跑不起来,直接报错:
Fatal Python error: Py_Initialize: unable to load the file system codec
ModuleNotFoundError: No module named 'encodings'
于是我在系统变量指定PYTHONHOME = path_to_win_anaconda/envs/my_env
但是程序crashed且没有任何提示。
重新指定PYTHONHOME = path_to_win_anaconda
,程序可以跑起来了(我的GUI界面可以出来了)。
问题来了,整个程序里面还有部分功能是通过调用终端,执行py文件实现的。比如执行以下的命令:
conda activate tensorflow23 && python ../../test.py
因为pytorch和TensorFlow在这次的项目系统中都有用到,且两个会起冲突(又是一段艰辛debug),所以使用虚拟环境分开执行
执行就会报错,这条命令拿到程序外的powershell执行也是一样的错误:
Fatal Python error: init_import_size: Failed to import the site module
Python runtime state: initialized
Traceback (most recent call last):
File "D:\win_anaconda\\lib\site.py", line 73, in <module>
import os
File "D:\win_anaconda\\lib\os.py", line 29, in <module>
from _collections_abc import _check_methods
File "D:\win_anaconda\\lib\_collections_abc.py", line 12, in <module>
GenericAlias = type(list[int])
TypeError: 'type' object is not subscriptable
报错可能不完全一样但都是Fatal Python error: init_import_size: Failed to import the site module
,这是因为python路径或者版本不一致的原因,
Python手册的4.6.1备注里提到:
备注: Windows会将用户变量串联在系统变量之后 ,这可能会在修改 PATH 时导致意外结果。
PYTHONPATH 变量被 Python 的所有版本使用,因此除非它列出的路径只包含与所有已安装的 Python 版本兼容的代码,否则不要永久配置此变量。
虚拟环境里的python和已经在系统变量里指定了的PYTHONHOME
有矛盾。
本来到这一筹莫展了,一定要设置PYTHONHOME
又一定要在虚拟环境执行一些命令,PYTHONHOME
还不能设置成虚拟环境的路径不然就报错(还不知道为什么)。
最终找到答案:不在windows的系统变量里设置PYTHONHOME
变量,而是在Qt中用C++调用Python时动态地去设置“PYTHONHOME”,即在Embedding Python里设置临时的PYTHONHOME
变量(=path_to_win_anaconda)!代码形如下:
{
Py_SetPythonHome(L"D:/win_anaconda");
Py_Initialize();
PyRun_SimpleString("print('xiang tuo dan')");
}
要注意的是,Py_SetPythonHome
要在Py_Initialize
之前(好吧可能只有我一个人只顾set没注意顺序)
END…