Qt/C++里调用执行python(conda管理)的一些坑

各种查资料,解决了在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'

参考博客:使用Anaconda遇到问题的总结(持续更新)

于是我在系统变量指定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')");
}

参考博客:解决PYTHONHOME这个环境变量带来的问题

要注意的是,Py_SetPythonHome要在Py_Initialize之前(好吧可能只有我一个人只顾set没注意顺序)


END…

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值