目录
- 前言
 - 1. Win10 安装 Miniconda
 - 2. 创建虚拟环境
 - 3. 配置C++调用python环境
 - 4. C++调用Python带参函数
 - 5.遇到的问题
 - 6. 总结
 
前言
本文记录了Win10 系统下Qt 应用程序调用Python时配置Miniconda虚拟环境的过程及遇到的问题,通过配置Python虚拟环境,简化了Qt应用程序的部署。
1. Win10 安装 Miniconda
首先下载Windows 版Miniconda,https://docs.conda.io/en/latest/miniconda.html
 
 下载完成后,双击安装,选择安装位置,然后一直点下一步,安装完成后在开始菜单中增加了两个打开Miniconda终端的菜单项,如下图
 
2. 创建虚拟环境
新建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依赖包。
 
3. 配置C++调用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 !";
    }
 
4. C++调用Python带参函数
创建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);
 
5.遇到的问题
在配置好pro文件编译qt工程时遇到如下图所示的错误,原因是object中定义的slots与qt的slots定义冲突,解决方法是添加下面第二张图所示的两行代码,先取消slots宏定义,然后再重新define,可解决这个问题。
 

6. 总结
以上就是本文的所有内容了,完整的demo可以从这里下载C++调用Python Miniconda虚拟环境,如果对C++调用Python环境配置有任何疑问,欢迎留言讨论。



















