zoukankan      html  css  js  c++  java
  • 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"
    
    void MainWindow::test()
    
    {
        //进行初始化
        Py_Initialize();
        //如果初始化失败,返回
        if(!Py_IsInitialized())
        {
            qDebug()<<"11111111111111111111";
            return ;
        }
    
        //加载模块,模块名称为myModule,就是myModule.py文件
        PyObject *pModule = PyImport_ImportModule("myModule");
        //如果加载失败,则返回
        if(!pModule)
        {
            qDebug()<<"2222222222222222";
            return;
        }
    
       //加载函数greatFunc
        PyObject * pFuncHello = PyObject_GetAttrString(pModule, "greatFunc");
    
        //如果失败则返回
        if(!pFuncHello)
        {
            qDebug()<<"3333333333333333333333";
            return ;
        }        
    }

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

      .h文件

    #ifndef CALCSCORETHREAD_H
    #define CALCSCORETHREAD_H
    
    #include <QObject>
    #include <QThread>
    #include <Python.h>
    
    class CalcScoreThread : public QThread
    {
        Q_OBJECT
    public:
        CalcScoreThread(QObject *parent = nullptr);
    
        // html转化为PDF
        QString saveHtmlToPDF(QString str);
    
    protected:
        void run();
    
    private:
        QString m_ScoreType;
        QString m_LabelPath;
    };
    
    #endif // CALCSCORETHREAD_H

      cpp文件

    #include "CalcScoreThread.h"
    #include "LoggerInfo.h"
    #include <QCoreApplication>
    #include <QDateTime>
    #include <QDebug>
    #include <QDir>
    
    CalcScoreThread::CalcScoreThread(QObject *parent) : QThread(parent)
    {
    
    }
    
    void CalcScoreThread::SetScoreType(const QString &type)
    {
        m_ScoreType = type;
    }
    
    void CalcScoreThread::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

      

      

  • 相关阅读:
    Codeforces467C George and Job
    Codeforces205E Little Elephant and Furik and RubikLittle Elephant and Furik and Rubik
    Codeforce205C Little Elephant and Interval
    51nod1829 函数
    51nod1574 排列转换
    nowcoder35B 小AA的数列
    Codeforce893E Counting Arrays
    gym101612 Consonant Fencity
    CodeForces559C Gerald and Giant Chess
    CodeForces456D A Lot of Games
  • 原文地址:https://www.cnblogs.com/jiangson/p/12606000.html
Copyright © 2011-2022 走看看