栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

QT下调用py脚本(两种方法)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

QT下调用py脚本(两种方法)

如何实现在c++QT中调用py脚本呢?方法如下:

方法一:通过官方python.h进行调用

该方法参考了Ubuntu18.04下 Qt调用conda下的python_猫生鱼的博客-CSDN博客

感谢大佬的分享~~

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

#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"

#include "ui_mainwindow.h"

#include

#include

MainWindow::MainWindow(QWidget *parent) :

    QMainWindow(parent),

    ui(new Ui::MainWindow)

{

    ui->setupUi(this);

     process1 = new QProcess(this);

//方式一:首先调用控制台,再通过控制台启动程序。(控制台:mac/linux下调用bash,windows下是cmd.exe)

     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读取,获取每次输出。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/744586.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号