Qt调用Miniconda的python方法
1、 Win 64环境下载及安装 Miniconda
首先下载Windows 版Miniconda,https://docs.conda.io/en/latest/miniconda.html或
https://repo.anaconda.com/miniconda/
安装界面及选择如下图所示:
安装完python3.12版报错如下。
说明:python3.11版本以后都不支持Py_SetPythonHome函数为此,下载了python3.10版本。
版本问题是程序员的硬伤!!!
2、创建虚拟环境
新建Qt工程pythondemo,在pro文件中添加程序生成目录 DESTDIR及添加头文件和库文件内容如下:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = PythonDemo
TEMPLATE = app
DESTDIR = $$PWD/bin #Added By LZY
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
CONFIG += c++11
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
INCLUDEPATH += $$PWD/bin/python/env/include #Added By LZY
LIBS += -L$$PWD/bin/python/env/libs \
-lpython310 -lpython3
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
编译并运行程序,可以看到在bin目录下生成了可执行程序。在bin目录下新建python目录,然后在开始菜单中找到 **Anaconda Prompt(miniconda3)**打开一个Python终端,默认激活的是base虚拟环境。使用如下命令创建指定路径,指定Python版本的虚拟环境:
#1)指定Python版本的虚拟环境:并按照提示选择Y
conda create --prefix D:\LZY\SelfSearch\Src\PythonDemo\bin\python\env python=3.10
#2)激活虚拟环境:
conda activate D:\LZY\SelfSearch\Src\PythonDemo\bin\python\env
3、 配置C++调用python环境
初始化 Python 环境,并在程序中设置 PythonHome 环境变量,如何知道PythonHome环境变量需要设置哪些路径呢?这里需要参考虚拟环境的环境变量值。在激活的 bin\python\env 虚拟环境下运行Python解释器,打印虚拟环境的path值,如下所示:
(D:\LZY\SelfSearch\Src\PythonDemo\bin\python\env) D:\LZY\SelfSearch\Src\PythonDemo>python
Python 3.10.16 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 16:19:12) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print(sys.path)
['', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\python310.zip', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\DLLs', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\lib', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env', 'D:\\LZY\\SelfSearch\\Src\\PythonDemo\\bin\\python\\env\\lib\\site-packages']
>>>
在代码中设置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 !";
}
编译问题:
在配置好pro文件编译qt工程时遇到如下图所示的错误,原因是object中定义的slots与qt的slots定义冲突,解决方法是在头文件python.h声明前先取消slots宏定义,包含python.h后再重新define,可解决这个问题。如下图所示:
#include <QDebug>
#include <qtextcodec.h>
#include "mainwindow.h"
#include "ui_mainwindow.h"
//--
#undef slots //Added By Lzy
#include "Python.h"
#define slots Q_SLOTS
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、问题处理
1)调用python模块出错如下:
Traceback (most recent call last):
File "D:\LZY/SelfSearch/Src/PythonDemo/bin/python\testPython.py", line 2, in writeData
print(data)
UnicodeEncodeError: 'gbk' codec can't encode character '\ufffd' in position 0: illegal multibyte sequence
解决方法:在头文件中加入#pragma execution_character_set("utf-8")就可以;