Qt调用python脚本注意细节以及问题

前言
注意
说明

前言

经过一段时间摸索,发现Qt能够调用python脚本,并且能依据输入参数并获取返回值。但是我却遇到一个困惑,就是python写了一个脚本实现绘画折线图,单独在python idle上运行是没有问题的。
如图:



def getPic(str):
    import matplotlib.pyplot as plt
    import numpy as np

    print ('enter getPic...', str)
    x = np.arange(9)
    y = np.sin(x)
    z = np.cos(x)
    print ('enter getPic...', str)
# marker数据点样式,linewidth线宽,linestyle线型样式,color颜色
    plt.plot(x, y, marker="*", linewidth=3, linestyle="--", color="orange")
    plt.plot(x, z)
    plt.title("matplotlib")
    plt.xlabel("height")
    plt.ylabel("width")
    print ('enter getPic...', str)
# 设置图例
    plt.legend(["Y","Z"], loc="upper right")
    plt.grid(True)
    plt.show()
    print ('enter getPic...', str)

在这里插入图片描述

在Qt上运行结果输出:进入第二个enter pic… ,第三个enter pic…就一直停在那。

在这里插入图片描述
main.cpp

//#include "onetest.h"
#include <QApplication>
#include <QDebug>
#include <QTime>

#pragma push_macro("slots")
#undef slots
#include <Python.h>
#pragma pop_macro("slots")

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    ONETEST w;
//    w.show();
    //进行初始化

    Py_Initialize();
#if 1
    //如果初始化失败,返回
    if(!Py_IsInitialized())
    {
        qDebug()<<"initial failure!";
        return a.exec();
    }

    //加载模块,模块名称为myDemo,就是myDemo.py文件
    PyObject *pModule = PyImport_ImportModule("myDemo");
    //如果加载失败,则返回
    if(!pModule)
    {
        qDebug()<<"load failure";
        return a.exec();
    }
    //加载函数getPic
    PyObject* pDict = PyModule_GetDict(pModule);
    PyObject* pFunc = PyDict_GetItemString(pDict, "getPic"); //从字典属性中获取函数
    if(pFunc && PyCallable_Check(pFunc))
    {
        //调用函数
        PyObject* pArg = Py_BuildValue("(s)", "getPic"); //参数类型转换,传递一个字符串。将c/c++类型的字符串转换为python类型,元组中的python类型查看python文档
        PyEval_CallObject(pFunc, pArg); //调用直接获得的函数,并传递参数
    }
    //如果失败则返回
    else
    {
        qDebug()<<"load function failure";
        return a.exec();
    }

#elif
    PyObject* pDict = PyModule_GetDict(pModule);
    PyObject* pFunc = PyDict_GetItemString(pDict, "add"); //从字典属性中获取函数
    PyObject* pArg = Py_BuildValue("(i, i)", 1, 2); //参数类型转换,传递两个整型参数
    PyObject* result = PyEval_CallObject(pFunc, pArg); //调用函数,并得到python类型的返回值
    int sum;
    PyArg_Parse(result, "i", &sum); //将python类型的返回值转换为c/c++类型
    qDebug()<<"sum = "<<sum;


    PyRun_SimpleString("print('hello world!')");
    PyRun_SimpleString("getPic();");
#endif
    //退出
    Py_Finalize();
    return a.exec();
}

python: 3.7 -32bit
Qt 5.12 -32bit MSVC2017

注意

在进行准备过程中注意如下事项:

  1. qt编译器版本msvc 与 python 位数一样。
  2. 如果python实现可视化的话。可以选择plotly、matplotlib。

plotly可以联网、离线下实现绘图。
官网: https://plot.ly/
plotly是一个可交互,基于浏览器的绘图库,主打功能是绘制在线可交互的图表,所绘制出来的图表真的赏心悦目。
它所支持的语言不只是Python,还支持诸如r,matlab,javescript等语言。plotly绘制的图能直接在jupyter中查看,
也能保存为离线网页,或者保存在plot.ly云端服务器内,以便在线查看。
如果使用Python语言,建议用jupyter notebook或jupyterlab作为IDE。

matplotlib:
事实上Python中很多可视化库都是基于matplotlib开发的。
Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。
是 Python 的绘图库。 它可与 NumPy 一起使用,提供了一种有效的 MatLab 开源替代方案。 它也可以和图形工具包一起使用,

  1. python 安装pyqt5。
  2. 借鉴参考网上调用python中类、函数。

https://blog.csdn.net/spvm1313113/article/details/5819297
https://blog.csdn.net/sihai12345/article/details/82745350
要注意在.pro工程文件中,release版本 python没有debug库
LIBS += -LD:/Python/Python37-32/libs -lpython37
INCLUDEPATH += D:/Python/Python37-32/include
DISTFILES += myDemo.py
https://blog.csdn.net/yinyuchen1/article/details/77775851

  1. 头文件声明python.h。更细节错误参考如下·遇到的坑。

网址:https://www.csdn.net/gather_20/MtzaUgzsODAtYmxvZwO0O0OO0O0O.html

https://blog.csdn.net/alxe_made/article/details/83382159

说明

目前是可以通过qt 调用Python脚本实现参数输入与返回,这个是可以确定的。但是至于为什么在绘图或者其他可视化过程中,没有调用起来,而是一直进入到plot相关准备过程中。我估计应该是绘图机制与底层平台有关,因为在python文件单独在idle上运行时,实现绘图并重新需要开启一个进程实现绘图。所以导致qt调用时,虽然能进入到此函数中,但是在准备绘图时却导致无法进入python绘图底层。

针对于以上猜想,我试了两种方法。
方案一:
qt负责调用python函数,然后该函数负责开启进程启动,然后结果导致启动很多进程去调用时内存崩溃问题。
方案二:
qt开启进程去调用python文件,实现绘图。
QProcess::execute(“安装python.exe路径”, “所执行的Python文件”);

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

道阻且长,行则降至

无聊,打赏求刺激而已

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

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

打赏作者

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

抵扣说明:

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

余额充值