当前位置: 首页 > news >正文

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")就可以;

相关文章:

  • 桥接模式 (Bridge Pattern)
  • Centos6配置yum源
  • 国企笔试之2025年中广核校招SHL测评笔试内容详解
  • 一文了解 threejs 中.bin 文件与 .gltf 文件 和 .glb 文件三者之间的关系
  • 汽车芯片成本控制:挑战、策略与未来趋势
  • 数学建模中的最大最小值模型详解
  • vue3:十一、主页面布局(优化页面跳转方式)
  • 网络层之IP协议
  • MySQL拒绝访问
  • 使用Docker部署MySQL8.0.29
  • SpringDoc和Swagger使用
  • LeetCode 热题 100_划分字母区间(80_763_中等_C++)(贪心算法(求并集))
  • 点亮STM32最小系统板LED灯
  • 烧结银技术赋能新能源汽车超级快充与高效驱动
  • C/C++转换为字符串宏和字符串拼接宏的综合使用
  • [HY000][1366] Incorrect string value: ‘张三‘ for column ‘name‘ at row 1
  • 基于vue框架的在线影院系统a079l(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 鸿蒙生态开发
  • 【Java】深入了解下Java Bitset
  • SOFABoot-09-模块隔离
  • 山东省委组织部办公室主任吴宪利已任德州市委常委、组织部部长
  • 李开复出任福耀科技大学理事会理事,助力学校AI战略
  • 今年一季度全国城镇新增就业308万人,就业形势保持总体稳定
  • 神舟十九号载人飞船因东风着陆场气象原因推迟返回
  • 泽连斯基承认乌情报部门刺杀俄军高官
  • 10台核电新机组获核准,上海核电厂商独揽超500亿元订单