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

QT C++中调用python脚本时,import第三方库失败问题解决

QT C++中调用python脚本时,import第三方库失败问题解决


文章目录

  • QT C++中调用python脚本时,import第三方库失败问题解决
  • 前言
  • 一、问题复现
  • 二、调试过程
  • 三、问题解决
    • 1 numpy问题解决
    • 2 matplotlib问题解决
  • 四、补充说明
  • 五、参考资料


前言

项目需要,计划通过C++的QT调用Python脚本,实现更快的算法实现,并集成在项目软件上。但是,在按照网上教程,配置好C++调用Python脚本的环境后,在调用(import)对应路径下的py文件时,基本没有问题。但是,一旦调用numpy、matplotlib时,则PyImport_ImportModule函数即会返回失败! 因此,这里重点针对import第三方库,却PyImport_ImportModule失败的问题,进行解决。关于配置C++调用Python脚本的环境,参考上述链接即可,并不复杂。


一、问题复现

首先,对具体问题进行更加细致的复现。在C++代码中,具体代码如下。

// 1. 设置Python的运行环境目录Py_SetPythonHome(L"D:/Software/anaconda3/envs/xxxx");// 2. 初始化python解释器Py_Initialize();// 2.1 检查初始化是否成功if (!Py_IsInitialized()) {qDebug() << "Python init fail";Py_Finalize();}// 3.1 执行Python脚本语句PyRun_SimpleString("print('I am Python!')");// 3.2 初始化python系统文件路径,保证可以访问到 .py文件PyRun_SimpleString("import sys");PyRun_SimpleString("sys.path.append('E:/Code/xxxx/')");// 3.3 将文件作为模块,import导入,不需写后缀PyObject* pModule = PyImport_ImportModule("MyTest");if (pModule == NULL) {qDebug() << "module not found";return;}// 3.4 调用函数PyObject* pFunc = PyObject_GetAttrString(pModule, "test");if (!pFunc || !PyCallable_Check(pFunc)) {qDebug() << "not found function test";return;}

在这里,MyTest.py文件内,代码如下。

import numpy as np
from matplotlib import pyplot as plt
import time
import mathdef test():print("hello!")

此时,若将MyTest.py中import的四个模块语句注释,则程序没有任何问题,正常运行。但是,若不注释那四句,则 PyObject* pModule = PyImport_ImportModule(“MyTest”)会返回NULL。这时,便会给我们产生错觉:似乎该环境下,调用通过pip install安装的第三方库,便会失败,即需要进一步配置这些第三方库的环境。

二、调试过程

首先,便是按照上述思路,进行百度谷歌寻找答案,主要是配置python的库文件的环境变量等,这里不赘述,总之,这并不能解决问题!
后来,突然发现,在C++代码中,有这么一句:

PyRun_SimpleString("import sys");

调试发现,该句代码是成功运行的,所以,便推倒前述结论:该环境下,调用通过pip install安装的第三方库,便会失败。那么,也就是说,仅是上述的某些库,import失败了,而非所有第三方库!于是,分别对MyTest.py中的import部分代码轮流注释,如下:

import numpy as np
# from matplotlib import pyplot as plt
# import time
# import mathdef test():print("hello!")

结果发现,当单独import time与math时,PyObject* pModule = PyImport_ImportModule(“MyTest”)返回并不为空,也就是说是导入成功的!因此,可以正确推出结论:PyImport_ImportModule在执行Import numpy与matplotlib时,会失败。 但是,为什么会失败呢?仅从上述代码中的返回结果,仍然无法看出错误原因。于是,修改C++代码,将下述两行代码,加入到PyRun_SimpleString(“import sys”)之后。

PyRun_SimpleString("import numpy");
PyRun_SimpleString("import matplotlib");

于是,背后真正的错误便迎面儿来了。当import numpy时,错误为:

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.Original error was: DLL load failed while importing _multiarray_umath: 找不到指定的模块。

当import matplotlib时,错误为:

ImportError: cannot import name 'Image' from 'PIL' (unknown location)

三、问题解决

其实,当背后错误出现时,再解决问题就很好办了,对应去搜背后错误的解决方法即可。我相应参考numpy问题解决与matplotlib问题解决,两个问题便都迎刃而解了。这里总结一下。

1 numpy问题解决

重新安装numpy即可:

pip uninstall numpy
pip install numpy

2 matplotlib问题解决

pip uninstall pillow
pip install pillow

可以发现,都是通过重新安装库或者关键依赖库后,问题得以解决!至于具体原因是什么,还不是非常清楚,也由于时间问题,就不深入挖掘了,希望后续有大佬搞清楚以后,欢迎交流讨论!

四、补充说明

本部分,为后续补充内容。在完成本篇博客后,后续项目推进上,又碰到了很多类似问题,例如同样在C++调用Python拓展模块时,报错:

ImportError: DLL load failed while importing cv2: 找不到指定的模块。

此时,我按照本文提出方法,卸载opencv后继续安装,也进一步安装了opencv-contrib-python模块等,均未解决问题。后来考虑,是否为opencv版本太高呢,于是将opencv降版本至4.5.1.48,问题解决!至此,大概可以为为本文的问题形成一个结论:当出现找不到指定模块、DLL加载失败等类似问题时,可考虑一种很大可能性,是该库的版本与环境不匹配,可能版本太旧,但同样也可能版本太新!此时,可调整几个版本测试,很多类似问题可能也就此解决了!
另外,在本部分的研究内容中,需要自行编译支持gstreamer编码器的opencv,感觉这类opencv库应该需求量很大,但是却没有人提供编译好的库,故此在这里提供链接。

五、参考资料

最后,感谢各位大佬提供的前人经验:
[1] alxe_made: Qtcreator中C++调用python方法
[2] HJ: 成功解决ImportError: cannot import name ‘image‘ from ‘PIL‘(unknown location)
[3] 衷科知眠: 成功解决ImportError: cannot import name ‘image‘ from ‘PIL‘(unknown location)

相关文章:

QT C++中调用python脚本时,import第三方库失败问题解决

QT C中调用python脚本时&#xff0c;import第三方库失败问题解决 文章目录 QT C中调用python脚本时&#xff0c;import第三方库失败问题解决前言一、问题复现二、调试过程三、问题解决1 numpy问题解决2 matplotlib问题解决 四、补充说明五、参考资料 前言 项目需要&#xff0c…...

【AI视野·今日Robot 机器人论文速览 第七十期】Thu, 4 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Thu, 4 Jan 2024 Totally 17 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Many-Objective-Optimized Semi-Automated Robotic Disassembly Sequences Authors Takuya Kiyokawa, Kensuke Harada, Weiwei …...

Flutter中的布局组件介绍及使用

1. 引言 Flutter 是一款由 Google 开发的开源 UI 软件开发工具&#xff0c;可用于在单个代码库中构建漂亮、本机编译的应用程序。在 Flutter 中&#xff0c;布局是构建用户界面的核心部分之一。本文将介绍 Flutter 中的全部布局组件&#xff0c;以及它们的使用方式。 2. 基础…...

【面试高频算法解析】算法练习2 回溯(Backtracking)

前言 本专栏旨在通过分类学习算法&#xff0c;使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目&#xff0c;帮助您深度理解每种算法&#xff0c;避免出现刷了很多算法题&#xff0c;还是一知半解的状态 专栏导航 二分查找回溯&#xff08;Backtracking&…...

认识Git

&#x1f30e;初识Git 初识Git 什么是Git Git的安装       Centos平台安装Git       Ubuntu平台安装Git Git的基本操作       创建远程仓库       配置Git 认识工作区、暂存区与版本库       添加文件到暂存区       将暂存区文件提交至本…...

@RequestParam,@RequestBody和@PathVariable 区别

RequestParam&#xff0c;RequestBody和PathVariable 这三者是spring常见的接受前端数据的注解&#xff0c;那么他们分别是接受什么的前端数据呢&#xff1f; RequestParam&#xff1a;这个注解主要用于处理请求参数&#xff0c;尤其是GET请求中的查询参数和表单参数。它可以用…...

vue3组件传参

1、props: 2、自定义事件子传父 3、mitt任意组件通讯 4、v-model通讯(v-model绑定在组件上) (1)V2中父子组件的v-model通信&#xff0c;限制了popos接收的属性名必须为value和emit触发的事件名必须为input,所以有时会有冲突; 父组件: 子组件: (2)V3中:限制了popos接收的属性名…...

React16源码: React中创建更新的方式及ReactDOM.render的源码实现

React当中创建更新的主要方式 ReactDOM.render || hydrate 这两个API都是我们要把整个应用第一次进行渲染到我们的页面上面能够展现出来我们整个应用的样子的一个过程这是初次渲染 setState 后续更新应用 forceUpdate 后续更新应用 replaceState 在后续被舍弃 关于 ReactDOM…...

CentOS 7 系列默认的网卡接口名称

CentOS 7 系列默认的网卡接口是随机的&#xff0c;如果要修改网卡名称以 eth 开头&#xff0c;有两种方式。 方法一&#xff1a;安装系统时 在安装界面移动光标到 Install Centos 7.按 TAB 键 在出现的代码的末尾添加&#xff1a;net.ifnames0 biosdevname0.按下回车开始安装即…...

多文件上传

HTML中实现多文件上传是通过用<input type"file">元素的multiple属性&#xff0c;以下简单描述多文件上传的步骤 HTML表单准备&#xff0c;使用<input type"file">元素&#xff0c;并为其添加multiple属性&#xff0c;以允许用户选择多个文件…...

2024.1.7力扣每日一题——赎金信

2024.1.7 题目来源我的题解方法一 哈希表方法二 数组 题目来源 力扣每日一题&#xff1b;题序&#xff1a;383 我的题解 方法一 哈希表 使用哈希表记录ransomNote中所需字符的数量&#xff0c;然后遍历magazine并将哈希表中存在的对应的数量减一 时间复杂度&#xff1a;O(nm…...

C#中List<T>底层原理剖析

C#中List底层原理剖析 1. 基础用法2. List的Capacity与Count&#xff1a;3.List的底层原理3.1. 构造3.2 Add()接口3.3 Remove()接口3.4 Inster()接口3.5 Clear()接口3.6 Contains()接口3.7 ToArray()接口3.8 Find()接口3.8 Sort()接口 4. 总结5. 参考 1. 基础用法 list.Max() …...

Leetcode 3003. Maximize the Number of Partitions After Operations

Leetcode 3003. Maximize the Number of Partitions After Operations 1. 解题思路2. 代码实现 题目链接&#xff1a;10038. Maximize the Number of Partitions After Operations 1. 解题思路 这一题我看实际比赛当中只有72个人做出来&#xff0c;把我吓得够呛&#xff0c;…...

MySQL第一讲:MySQL知识体系详解(P6精通)

MySQL知识体系详解(P6精通) MySQL不论在实践还是面试中,都是频率最高的。本系列主要对MySQL知识体系梳理,将给大家构建JVM核心知识点全局知识体系,本文是MySQL第一讲,MySQL知识体系详解。 文章目录 MySQL知识体系详解(P6精通)1、MySQL学习建议1.1、为什么学习 MySQL?1.2、…...

逻辑回归简单案例分析--鸢尾花数据集

文章目录 1. IRIS数据集介绍2. 具体步骤2.1 手动将数据转化为numpy矩阵2.1.1 从csv文件数据构建Numpy数据2.1.2 模型的搭建与训练2.1.3 分类器评估2.1.4 分类器的分类报告总结2.1.5 用交叉验证&#xff08;Cross Validation&#xff09;来验证分类器性能2.1.6 完整代码&#xf…...

Python print 高阶玩法

Python print 高阶玩法 当涉及到在Python中使用print函数时&#xff0c;有许多方式可以玩转文本样式、字体和颜色。在此将深入探讨这些主题&#xff0c;并介绍一些print函数的高级用法。 1. 基本的文本样式与颜色设置 使用ANSI转义码 ANSI转义码是一种用于在终端&#xff0…...

Wpf 使用 Prism 实战开发Day09

设置模块设计 1.效果图 一.系统设置模块&#xff0c;主要有个性化(用于更改主题颜色)&#xff0c;系统设置&#xff0c;关于更多&#xff0c;3个功能点。 个性化的颜色内容样式&#xff0c;主要是从 Material Design Themes UI简称md、提供的demo里复制代码过来使用的。 1.设置…...

网络端口(包括TCP端口和UDP端口)的作用、定义、分类,以及在视频监控和流媒体通信中的定义

目 录 一、什么地方会用到网络端口&#xff1f; 二、端口的定义和作用 &#xff08;一&#xff09;TCP协议和UDP协议 &#xff08;二&#xff09;端口的定义 &#xff08;三&#xff09;在TCP/IP体系中&#xff0c;端口(TCP和UDP)的作用 &#xff08;…...

flink如何写入es

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、写入到Elasticsearch5二、写入到Elasticsearch7总结 前言 Flink sink 流数据写入到es5和es7的简单示例。 一、写入到Elasticsearch5 pom maven依赖 <d…...

Java、Python、C++和C#的界面开发框架和工具的重新介绍

好的&#xff0c;以下是Java、Python、C和C#的界面开发框架和工具的重新介绍&#xff1a; Java界面开发&#xff1a; Swing: 是Java提供的一个基于组件的GUI工具包&#xff0c;可以创建跨平台的图形用户界面。它提供了丰富的组件和布局管理器&#xff0c;使得界面开发相对简单。…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...

海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》

近日&#xff0c;嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》&#xff0c;海云安高敏捷信创白盒&#xff08;SCAP&#xff09;成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天&#xff0c;网络安全已成为企业生存与发展的核心基石&#xff0c;为了解…...