本文记录了Win10 系统下Qt 应用程序调用Python时配置Miniconda虚拟环境的过程及遇到的问题,通过配置Python虚拟环境,简化了Qt应用程序的部署。
首先下载Windows 版Miniconda,https://docs.conda.io/en/latest/miniconda.html
下载完成后,双击安装,选择安装位置,然后一直点下一步,安装完成后在开始菜单中增加了两个打开Miniconda终端的菜单项,如下图
新建Qt工程pythondemo,在pro文件中添加程序生成目录 DESTDIR
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += console
TARGET = pythondemo
TEMPLATE = app
DESTDIR = $$PWD/bin
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
编译并运行程序,可以看到在bin目录下生成了可执行程序。在bin目录下新建python目录,然后在开始菜单中找到 **Anaconda Prompt(miniconda3)**打开一个Python终端,默认激活的是base虚拟环境。使用如下命令创建指定路径,指定Python版本的虚拟环境:
conda create --prefix C:\develop\QT\pythondemo\bin\python\env python=3.8
激活虚拟环境:
conda activate C:\develop\QT\pythondemo\bin\python\env
虚拟环境中默认安装了pip,可以使用pip install xxxpackage
命令安装Python依赖包。
首先修改pro文件,添加 Python 头文件的路径和依赖的lib库,并将bin/python/env目录下的python38.dll 和 python3.dll复制到bin目录下。pro文件增加如下配置
INCLUDEPATH += $$PWD/bin/python/env/include
LIBS += -L$$PWD/bin/python/env/libs \
-lpython38 -lpython3
初始化 Python 环境,并在程序中设置 PythonHome 环境变量,如何知道PythonHome环境变量需要设置哪些路径呢?这里需要参考虚拟环境的环境变量值。在激活的 bin\python\env 虚拟环境下运行Python解释器,打印虚拟环境的path值,如下图所示:
在代码中设置PythonHome 并初始化Python环境,代码如下:
QString pythonHome = qApp->applicationDirPath() + "/python/env";
pythonHome.append(";");
pythonHome.append(qApp->applicationDirPath() + "/python/env/python38.zip");
pythonHome.append(";");
pythonHome.append(qApp->applicationDirPath() + "/python/env/DLLs");
pythonHome.append(";");
pythonHome.append(qApp->applicationDirPath() + "/python/env/lib");
pythonHome.append(";");
pythonHome.append(qApp->applicationDirPath() + "/python/env/lib/site-packages");
wchar_t pythonHomeWchar[1500];
memset(pythonHomeWchar, 0, sizeof(pythonHomeWchar));
pythonHome.toWCharArray(pythonHomeWchar);
//设置PythonHome环境变量
Py_SetPythonHome(pythonHomeWchar);
//初始化Python C API
Py_Initialize();
if(Py_IsInitialized())
{
qDebug() << "python env init !";
}
创建testPython.py文件,并添加一个带参数的测试函数,如下
def writeData(data):
print(data)
下面的代码演示了如何设置应用程序python脚本路径,导入Python模块,获取模块中定义的函数,设置函数参数及调用函数。
//应用程序python脚本路径
QString pyfilePath = QString::fromLocal8Bit("sys.path.append('%1')").arg(qApp->applicationDirPath() + "/python");
PyRun_SimpleString(pyfilePath.toLocal8Bit().data());
//导入python模块
PyObject* pWriteWordModule = PyImport_ImportModule("testPython");
if(!pWriteWordModule)
{
qDebug() << "import module faild!";
PyErr_Print();
}
//获取testPython模块中的函数
PyObject *pFunc = PyObject_GetAttrString(pWriteWordModule, "writeData");
if(!pFunc)
{
qDebug() << "get func faild!";
}
//设置函数参数
PyObject *pTuple = PyTuple_New(1);
PyTuple_SetItem(pTuple, 0, Py_BuildValue("s", "hello python !"));
//调用函数
PyObject_CallObject(pFunc, pTuple);
在配置好pro文件编译qt工程时遇到如下图所示的错误,原因是object中定义的slots与qt的slots定义冲突,解决方法是添加下面第二张图所示的两行代码,先取消slots宏定义,然后再重新define,可解决这个问题。
以上就是本文的所有内容了,完整的demo可以从这里下载C++调用Python Miniconda虚拟环境,如果对C++调用Python环境配置有任何疑问,欢迎留言讨论。