QT调用python文件

基本步骤

1.将python文件要是使用的环境添加到环境变量中
在这里插入图片描述

2.新建一个QT项目

3.在.pro文件中加入需要的python库文件目录

右击项目名,然后单击“添加库”,库类型选择为“外部库”,库文件选择python要使用的环境中的“python38.lib”
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时,在.pro文件中新增了如下语句。

在这里插入图片描述

最后,还需要在.pro文件中添加下面语句。

在这里插入图片描述

此时,.pro文件就配置好了,该项目中可以之间调用"python.h"库文件了。

4.在QT项目中,新建一个python文件

右击项目名,选择”Add new…“,然后选择python文件,新建一个“Python File”

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

此时,在项目目录下,新建了“Other files”文件夹,同时文件夹中保存有刚刚新建的.py文件。

在这里插入图片描述

最后,就可以在.py文件中写入自己想要实现的功能(可以直接在该文件中写,但是没有联想,不方便;也可以直接在其他地方写完后复制到该文件中)

注:在QT中调用python是以函数的形式调用,因此.py文件中的功能写成函数的形式

在这里插入图片描述

5.在main.cpp中进行python的调用

首先在main.cpp中调用“python.h”,即#include "python.h"

然后在主函数中初始化、配置python,并调用.py文件中的某个函数,代码如下。

#include "mainwindow.h"
#include <QApplication>
#include "Python.h"
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Py_SetPythonHome((const wchar_t *)(L"D:/anaconda3/envs/pycharm"));
    Py_Initialize();
    if ( !Py_IsInitialized() )
    {
    return -1;
    }
    PyRun_SimpleString("import sys");//设置py脚本的路径
    PyRun_SimpleString("sys.path.append('./')");//当前路径
    PyObject* pModule = PyImport_ImportModule("temp");  // 这里的temp就是创建的python文件
    if (!pModule) {
            qDebug()<< "Cant open python file!\n" << endl;
            return -1;
        }
   PyObject* pFunhello= PyObject_GetAttrString(pModule,"Hello");  // 这里的hellow就是python文件定义的函数
    if(!pFunhello){
        qDebug()<<"Get function hello failed"<<endl;
        return -1;
    }
    PyObject_CallFunction(pFunhello,NULL);
    Py_Finalize();

    return a.exec();
}

此时就实现了QT调用python的功能。

遇到的问题

1.无法调用“python.h”,则检查.pro配置文件是否添加了正确的库;同时,检查环境变量是否配置正确。

注:在新添加环境变量后,需要重启QT。

2.调用“python.h”后,可能出现如下问题

在这里插入图片描述

问题出现的原因是在“object.h”中

在这里插入图片描述

解决办法:

PyType_Slot *slots; /* terminated by slot==0. */替换为

#undef slots
PyType_Slot *slots; /* terminated by slot==0. */
#define slots Q_SLOTS

如下图所示
在这里插入图片描述

3.若运行时输出“Cant open python file!”,则可能出现两个问题;一,检查.py文件是否和运行的.exe文件在同一目录下;即,将.py文件复制到debug或release文件夹中;二,检查.py文件是否出现语法性错误

python传参的实现

在QT文件中给python传入参数或读取python传出的参数,都是以PyObject的数据类型进行传入和传出的。

1.给python传入参数

首先在python中写入需要传参的函数,例如两个数相加。

然后在main.cpp中给python函数传递参数,代码如下。

#include "mainwindow.h"
#include <QApplication>
#include "Python.h"
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Py_SetPythonHome((const wchar_t *)(L"D:/anaconda3/envs/pycharm"));
    Py_Initialize();
    if ( !Py_IsInitialized() )
    {
    return -1;
    }
    PyRun_SimpleString("import sys");//设置py脚本的路径
    PyRun_SimpleString("sys.path.append('./')");//当前路径
    PyObject* pModule = PyImport_ImportModule("temp");  // 这里的temp就是创建的python文件
    if (!pModule) {
            qDebug()<< "Cant open python file!\n" << endl;
            return -1;
        }
   PyObject* pFunhello= PyObject_GetAttrString(pModule,"Hello");  // 这里的hellow就是python文件定义的函数
    if(!pFunhello){
        qDebug()<<"Get function hello failed"<<endl;
        return -1;
    }

    PyObject* pFunSum = PyObject_GetAttrString(pModule, "Sum");
    if(!pFunSum){
        qDebug()<<"Get function Sum failed"<<endl;
        return -1;
    }

    PyObject_CallFunction(pFunhello,NULL);

//  新建一个变量,长度为传入参数个数,然后一次将数据传入
    PyObject* args = PyTuple_New(2);
    int x = 100;
    int y = 2;
    PyTuple_SetItem(args, 0, Py_BuildValue("i", x));
    PyTuple_SetItem(args, 1, Py_BuildValue("i", y));

    PyEval_CallObject(pFunSum, args);

    Py_Finalize();

    return a.exec();
}

2.读取python传出的参数

例如,在.py文件中某函数实现输入两个数字,输出加、减的结果

#include "mainwindow.h"
#include <QApplication>
#include "Python.h"
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Py_SetPythonHome((const wchar_t *)(L"D:/anaconda3/envs/pycharm"));
    Py_Initialize();
    if ( !Py_IsInitialized() )
    {
    return -1;
    }
    PyRun_SimpleString("import sys");//设置py脚本的路径
    PyRun_SimpleString("sys.path.append('./')");//当前路径
    PyObject* pModule = PyImport_ImportModule("temp");  // 这里的temp就是创建的python文件
    if (!pModule) {
            qDebug()<< "Cant open python file!\n" << endl;
            return -1;
        }
   PyObject* pFunhello= PyObject_GetAttrString(pModule,"Hello");  // 这里的hellow就是python文件定义的函数
    if(!pFunhello){
        qDebug()<<"Get function hello failed"<<endl;
        return -1;
    }

    PyObject* pFunSum = PyObject_GetAttrString(pModule, "Sum");
    if(!pFunSum){
        qDebug()<<"Get function Sum failed"<<endl;
        return -1;
    }

    PyObject* pFunSum_Minus = PyObject_GetAttrString(pModule, "Sum_Minus");
    if(!pFunSum_Minus){
        qDebug()<<"Get function Sum_Minus failed"<<endl;
        return -1;
    }

    PyObject_CallFunction(pFunhello,NULL);

//  新建一个变量,长度为传入参数个数,然后一次将数据传入
    PyObject* args = PyTuple_New(2);
    int x = 100;
    int y = 2;
    PyTuple_SetItem(args, 0, Py_BuildValue("i", x));
    PyTuple_SetItem(args, 1, Py_BuildValue("i", y));

    PyEval_CallObject(pFunSum, args);

    PyObject* res = PyEval_CallObject(pFunSum_Minus, args);
    int sum, minus;
    if(res) {
        sum = PyLong_AsLong(PyTuple_GetItem(res, 0));
        minus = PyLong_AsLong(PyTuple_GetItem(res, 1));
    }
    qDebug() << sum << minus;

    Py_Finalize();

    return a.exec();
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐