qt调用python代码_Qt 调用Python脚本方法及遇到的问题

1、背景

简单说一下需求,Qt开发的上位机界面程序,需要调用Python编写的算法跑一个结果返回到界面上显示。

2、度娘出一篇博客,按照步骤进行环境搭建和简单的代码测试

环境搭建请参照如下博客地址:

博客:① https://blog.csdn.net/cholenmine/article/details/82854301

② https://blog.csdn.net/yinyuchen1/article/details/77775851

主要代码如下:

#include "Python.h"

voidMainWindow::test()

{//进行初始化

Py_Initialize();//如果初始化失败,返回

if(!Py_IsInitialized())

{

qDebug()<

}//加载模块,模块名称为myModule,就是myModule.py文件

PyObject *pModule = PyImport_ImportModule("myModule");//如果加载失败,则返回

if(!pModule)

{

qDebug()<

}//加载函数greatFunc

PyObject * pFuncHello = PyObject_GetAttrString(pModule, "greatFunc");//如果失败则返回

if(!pFuncHello)

{

qDebug()<

}

3、根据目前的具体需求,我需要在开启一个线程来调用Python脚本,于是新建了一个线程类,调用方法还是用的上面的示例代码。

.h文件

#ifndef CALCSCORETHREAD_H#define CALCSCORETHREAD_H#include#include#include

class CalcScoreThread : publicQThread

{

Q_OBJECTpublic:

CalcScoreThread(QObject*parent =nullptr);//html转化为PDF

QString saveHtmlToPDF(QString str);protected:voidrun();private:

QString m_ScoreType;

QString m_LabelPath;

};#endif //CALCSCORETHREAD_H

cpp文件

#include "CalcScoreThread.h"#include"LoggerInfo.h"#include#include#include#includeCalcScoreThread::CalcScoreThread(QObject*parent) : QThread(parent)

{

}void CalcScoreThread::SetScoreType(const QString &type)

{

m_ScoreType=type;

}voidCalcScoreThread::run()

{

Py_Initialize();//测试集路径

QString setsPath = QCoreApplication::applicationDirPath()+"/datasets/Divide_Labels";

QString name="main_SCORE";

LoggerInfo::GetInstance()->WriteLog("Start Import Module!");

PyObject* pModule = PyImport_ImportModule("main_SCORE");if (!pModule)

{

qDebug()<< "Cant open python file!";return;

}

LoggerInfo::GetInstance()->WriteLog("Import Module Succ!");//获取模块中的函数

PyObject* pFunc = PyObject_GetAttrString(pModule,"main");if(!pFunc)

{

qDebug()<< "Get function failed!";return;

}

QString strEnv= "5,2,2,3";

PyObject* pArgs = PyTuple_New(4);

PyTuple_SetItem(pArgs,0, Py_BuildValue("s",m_ScoreType.toStdString().c_str()));

PyTuple_SetItem(pArgs,1, Py_BuildValue("s",m_LabelPath.toStdString().c_str()));

PyTuple_SetItem(pArgs,2, Py_BuildValue("s",setsPath.toStdString().c_str()));

PyTuple_SetItem(pArgs,3, Py_BuildValue("s",strEnv.toStdString().c_str()));

PyObject* pReturn =PyObject_CallObject(pFunc, pArgs);if(pReturn)

{

qDebug()<< "succ ------";

}

Py_Finalize();if(!strResult.isEmpty())

{

emit SignalScoreResult(strResult);

}

}

现在问题来了:

① 第一次调用python脚本,能够正常调用并且得到结果。

② 不关闭主界面,接着进行第二次调用,软件直接崩溃,崩溃的行数是PyImport_ImportModule()函数,如下图所示:

最开始分析的原因:① 出现了空指针

② 第二次调用时,第一次的资源没有释放,占用python脚本,导致PyImport_ImportModule()函数不能将模块导入

4、最后差资料发现,因为我这里使用的是线程,C++多线调用python时必须要控制GIL

参照如下博客的方法才得以解决这个问题,对于小白初次线程中调用Python,鬼知道要控制什么GIL,虽然问题解决了,到现在都没去看GIL是个什么鬼

https://blog.csdn.net/qq_42938320/article/details/101770269

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值