Qt5调用python,以及后续导致 的“程序异常结束”

开发工具:Qt5.9.9_x64    python3.6.13_x64   vs2015

系统环境:win10,win11都行 

vs2015 、python和qt的安装我就不说了,网上很多教程,我这里开发环境是64位,需要注意的就是安装qt的时候一定要选MSCV2015_x64这个选项,其他的随你的需求。

安装好后,首先确定qt能跑你的项目 ,然后我们在测试python环境,在外部工具中设置中画红线的地方填入python安装目录,

参数 :%{CurrentDocument:FilePath};

工作目录:%{CurrentDocument:Path},左边的工具名都是添加自己建的。

 这些弄好后,在资源文化中加入测试的python文件,然后点开文件,点到如图所示中的python3.6,

如果能运行就说明python环境没什么问题,就可以接下来的步骤 。

 接下来在项目中添加 外部库,按如下的图片做完,一直点下一步 就行。

 然后主要调用代码就是这些,我只用了这些。

PyThreadStateLock.h 
//将全局解释器锁和线程的相关操作用类封装
#ifndef PYTHREADSTATELOCK_H
#define PYTHREADSTATELOCK_H
#include<Python.h>

class PyThreadStateLock
{
public:
    PyThreadStateLock(void)
    {
        _save = nullptr;
        nStatus = 0;
        nStatus = PyGILState_Check();   //检测当前线程是否拥有GIL
        PyGILState_STATE gstate;
        if (!nStatus)
        {
            gstate = PyGILState_Ensure();   //如果没有GIL,则申请获取GIL
            nStatus = 1;
        }
        _save = PyEval_SaveThread();
        PyEval_RestoreThread(_save);
    }
    ~PyThreadStateLock(void)
    {
        _save = PyEval_SaveThread();
        PyEval_RestoreThread(_save);
        if (nStatus)
        {
            PyGILState_Release(gstate);    //释放当前线程的GIL
        }
    }

private:
    PyGILState_STATE gstate;
    PyThreadState *_save;
    int nStatus;

};

#endif // PYTHREADSTATELOCK_H
Qtpython::Qtpython()
{//初始化
    if (!Py_IsInitialized())
    {
        //1.初始化Python解释器,这是调用操作的第一步
        Py_Initialize();
        if (!Py_IsInitialized()) {
            qDebug("Initial Python failed!");
//            emit failed();
        }
        else {
            //执行单句Python语句,用于给出调用模块的路径,否则将无法找到相应的调用模块
            PyRun_SimpleString("import sys");
            PyRun_SimpleString("sys.path.append('./Qtpython/')");//python文件在的相对路径
            // 初始化线程支持
            PyEval_InitThreads();
            // 启动子线程前执行,为了释放PyEval_InitThreads获得的全局锁,否则子线程可能无法获取到全局锁。
            PyEval_ReleaseThread(PyThreadState_Get());
            qDebug("Initial Python Success!");
        }
    }
}

void Qtpython::on_openButton_clicked()
{
    class PyThreadStateLock PyThreadLock;//加上线程锁
    PyObject* pModule = PyImport_ImportModule("scriptSecond");
    if (!pModule)
     {
         qDebug()<<"Cant open python file!\n";
         return ;
     }
    PyObject* pFunhello= PyObject_GetAttrString(pModule,"hhh");
    if(!pFunhello){
        qDebug()<<"Get function hello failed";
        return;
    }
    //调用temperImg函数
    PyObject_CallFunction(pFunhello,nullptr);
    PyErr_Print();//报错信息
    //结束,释放python
//    Py_Finalize();
}

 这里不是很建议用Py_Finalize()清除内存 ,英文文档中提到这个函数是没办法完全清除的,所以用了之后很可能调用两到三次就会报错的,这里我就不用了。到这里基本就能用了,可能还会出现以下问题:

  1.在 “;”前出错 类似问题,解决办法是在object.h,*slots改为 * _slots就行了。

  2.没有python36_d,在pyconfig.h中把 ”python36_d“ 改为 ”python36“就行了。

3.最无语的报错 ”程序异常结束“如果你也出现 了以下的错误,恭喜你和我一样幸运 ,巨坑。

在自己的python安装目录下找到这个鬼,然后 复制 到libs中就可以。这坑在没有任何错误信息。

 以上就是qt5调用python,以及报错的全部内容,如果你有其他问题欢迎评论留言,另外想要 资源包的可以用 下面网址下载:

QT5.9,9+VS2015-C++文档类资源-CSDN下载

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问星的世纪

坚持住,成功就是明天

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值