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();
}