QT下调⽤py脚本(两种⽅法)
如何实现在c++QT中调⽤py脚本呢?⽅法如下:
⽅法⼀:通过官⽅python.h进⾏调⽤
该⽅法参考了
感谢⼤佬的分享~~
1.在.pro⽂件中加⼊
##加⼊python库(根据实际位置调整路径)
LIBS += -L/usr/local/python3.7/lib -lpython3.7m -lcrypt -lpthread -ldl -lutil -lm -lpython3
DEPENDPATH += /usr/local/python3.7/include/python3.7m
INCLUDEPATH += /usr/local/python3.7/include/python3.7m -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall
INCLUDEPATH += /usr/local/python3.7/lib/python3.7/site-packages/numpy/core/include
2.在需要调⽤py脚本的⽂件中加⼊
#undef slots
#include <Python.h>
#define slots Q_SLOTS
tip:为什么添加#undef slots#define slots Q_SLOTS?原因是python中的slots与qt中的slots 定义冲突
3. 在需要调⽤py脚本的.cpp⽂件中加⼊以下代码(可以在函数中加⼊)
//以下为使⽤python.h调⽤py的代码
Py_Initialize();// 解释器初始化
if(!Py_IsInitialized()){
PyErr_Print();
qDebug() << "Can't Initialize python!\n" ;
return ;
}
PyRun_SimpleString("import sys");//令python能到已经安装的库,不加此句会出现⽆法import的问题
PyRun_SimpleString("sys.argv = ['python.py']");
PyRun_SimpleString("sys.path.append('./')");//把⼯作⽬录改为py⽂件所在⽬录,这⾥为当前⽬录
//导⼊.py⽂件模块,这⾥的project为⽂件名
PyObject* pModule = PyImport_ImportModule("project");
if(!pModule){
PyErr_Print();
qDebug() << "Can't open python file!\n" ;
return;
}
//导⼊模块中的⽅法字典
PyObject* pDict = PyModule_GetDict(pModule);
if(!pDict){
PyErr_Print();
qDebug() << "Get Dict failed!\n" ;
return;
}
//导⼊已导⼊模块中的⽅法或类,这⾥的main为⽅法(函数)名
PyObject* pFuc = PyDict_GetItemString(pDict, "main");
if(!pFuc){
PyErr_Print();
qDebug() << "Get function failed!\n" ;
return;
}
//启⽤导⼊的⽅法或类
PyObject_CallFunction(pFuc,NULL);
//内存释放
Py_CLEAR(pModule);
Py_CLEAR(pDict);
Py_CLEAR(pFuc);
//释放Python解释器所占⽤的资源
Py_Finalize();
知识点补充:Python嵌⼊C/C++释放资源
Python使⽤引⽤计数机制对内存进⾏管理,实现⾃动垃圾回收。在C/C++中使⽤Python对象时,应正确地处理引⽤计数,否则容易导致内存泄漏。在Python/C API中提供了Py_CLEAR()、Py_DECREF()等宏来对引⽤计数进⾏操作。
当使⽤Python/C API中的函数创建列表、元组、字典等后,就在内存中⽣成了这些对象的引⽤计数。在对其完成操作后应该使⽤Py_CLEAR()、Py_DECREF()等宏来销毁这些对象。其原型分别如下所⽰。
void Py_CLEAR( PyObject *o)
void Py_DECREF( PyObject *o)
其参数含义如下。
*o:要进⾏操作的对象。
对于Py_CLEAR()其参数可以为NULL指针,此时,Py_CLEAR()不进⾏任何操作。⽽对于Py_DECREF()其参数不能为NULL指针,否则将导致错误。
⽅法⼆:通过多线程调⽤
#include "mainwindow.h"
python怎么读取py文件#include "ui_mainwindow.h"
#include <QProcess>
#include <QtDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
process1 = new QProcess(this);
//⽅式⼀:⾸先调⽤控制台,再通过控制台启动程序。(控制台:mac/linux下调⽤bash,windows下是) process1->start("bash");//调⽤控制台程序
process1->waitForStarted();//等待程序确实启动再往下⾛
process1->write("/usr/bin/python3.7 ./handpose.py \n");
//⽅式⼆:直接启动python,并要求他启动指定脚本。
process1->start("/usr/bin/python3.7 /AR/ar/handpose.py");//直接启动python,并要求他启动指定脚本。//信号槽连接,获取到程序输出就调⽤OnReadData函数
connect(process1,SIGNAL(readyReadStandardOutput()),this,SLOT(OnReadData()));
}
void MainWindow::OnReadData(){
//打印输出
QString strResult = QString::fromLocal8Bit(process1->readAllStandardOutput().data());
qDebug() << strResult;
}
MainWindow::~MainWindow()
{
//杀死调⽤的进程
process1->kill();
process1->close();
delete process1;
delete ui;
}
输出问题:
值得指出的是,这⾥输出的内容,是当前py脚本运⾏结束后才会触发。⽐如脚本中有个循环10次每秒输出print,这⾥就不会触发10次分别打出print,⽽是会等10次运⾏结束后,统⼀打出⽂本。
解决办法,如果要想收到控制台的每次输出,可以再py脚本中将输出保存到内存中,或是剪切板,或者是指定的log⽂件,然后再通过qt读取,获取每次输出。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论