使用qtquick调用python程序,pytorch

一. 内容简介

使用qtquick调用python程序

二. 软件环境

2.1vsCode

2.2Anaconda

version: conda 22.9.0

2.3pytorch

安装pytorch(http://t.csdnimg.cn/GVP23)

2.4QT 5.14.1

新版QT6.4,,6.5在线安装经常失败,而5.9版本又无法编译64位程序,所以就采用5.14.1这个用的比较多也比较稳定的一个版本。

QT编译器采用的是MSVC2017 64bit。

链接:https://pan.baidu.com/s/1ER98DPAkTUPlIyCC6osNNQ?pwd=1234

三.主要流程

3.1 qml中调用c++程序

qml里面不能直接调用python,有那个调命令行然后执行py文件的,我感觉很奇怪,就没用那种方式,就采用c++调用python程序。
首先创建一个c++类,基于QObject对象,名字随便起,我用的是mopsopy,
在这里插入图片描述
完成以后,可以直接在我的模板上面改,就是需要在类的成员上加一些声明,让qml认识,但是变量的那个可以用alt加enter加出来,我的没有那个选项,你们可以直接用用我的模板

头文件

#ifndef MOPSOPY_H
#define MOPSOPY_H#include <QObject>
#include <QDate>
#include <QtQml>
#include <QDebug>class MopsoPy : public QObject
{Q_OBJECT// 用于qml内部识别Q_PROPERTY(QString name READ getName WRITE setName NOTIFY nameChanged)
public:explicit MopsoPy(QObject *parent = nullptr);~MopsoPy();QString getName() const;void setName(const QString &name);Q_INVOKABLE void func();
signals:void nameChanged(QString name);
public slots:private:QString name;
};#endif // MOPSOPY_H

cpp文件

#include "mopsopy.h"MopsoPy::MopsoPy(QObject *parent) : QObject(parent)
{
}MopsoPy::~MopsoPy()
{}QString MopsoPy::getName() const
{return name;
}void MopsoPy::setName(const QString &name)
{if (this->name == name)return;this->name = name;emit nameChanged(this->name);
}void MopsoPy::func()
{
}

完事后,要在main.cpp中注册一下,头文件别忘记了加

#include "mopsopy.h"qmlRegisterType<MopsoPy>("MopsoPy", 1, 0, "MopsoPy");

qml文件中使用,测试代码自己写吧

import MopsoPy 1.0MopsoPy{id: mopsoPy;name: "jjjj"Component.onCompleted: {mopsoPy.func()}}

3.2 c++调用python

首先,添加库的地址,换成自己的

INCLUDEPATH+=D:\Anaconda3\include  #pythonenviroment
LIBS+=-LD:\Anaconda3\libs
-l_tkinter
-lpython3
-lpython39

qt里面创建python文件,

import numpy as np
def add(a,b):# 创建日志文件fileLog = open("log.txt", "w")arr1 = np.array([1, 2, 3, 4, 5])# 写入日志fileLog.write(np.array2string(arr1))# 写入日志fileLog.write("写入完成")# 关闭文件fileLog.close()return a+b

c++方法实现
头文件

// 不加会关键字重复,报错
#undef slots
#include <Python.h>
#define slots Q_SLOTS

cpp文件这么写

void MopsoPy::func()
{// 新建一个元组,用来存放函数参数的值if( !Py_IsInitialized()){     Py_Initialize();}// 导入 Python 模块PyObject* pModule = PyImport_ImportModule("ccc");// 获取模块中的函数对象PyObject* pFunc = PyObject_GetAttrString(pModule, "add");// 创建参数元组PyObject* pArgs = PyTuple_New(2);int num1 = 42;int num2 = 13;// 这个i对应不同的数据格式PyObject* arg1 = Py_BuildValue("i", num1);PyObject* arg2 = Py_BuildValue("i", num2);PyTuple_SetItem(pArgs, 0, arg1);PyTuple_SetItem(pArgs, 1, arg2);// 调用函数并获取返回值PyObject* pResult = PyObject_CallObject(pFunc, pArgs);// 解析返回值double result;PyArg_Parse(pResult, "d", &result);// 打印结果printf("Result: %f\n", result);// 释放资源Py_DECREF(pModule);Py_DECREF(pFunc);Py_DECREF(pArgs);Py_DECREF(pResult);Py_Finalize();
}

最后把文件放到要执行的文件里面,不然会报找不到文件的,放到release里面就行(我用多个release编译的),我外面也扔了一个,
在这里插入图片描述结果,另外两个不用管,是我的其他模块出的。
在这里插入图片描述

3.3 调用复杂的python程序,读取神经网络

神经网络的模型保存以及读取

# 保存神经网络,这个只是保存训练的参数的
torch.save(model,'angelminLoss.pkl')# 神经网络的结构,因为读取只是读取参数,
class Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()# 这个是有wx+bself.linear1 = torch.nn.Linear(2, 56)self.linear2 = torch.nn.Linear(56, 56)self.linear3 = torch.nn.Linear(56, 56)self.linear4 = torch.nn.Linear(56, 28)self.linear5 = torch.nn.Linear(28, 14)self.linear6 = torch.nn.Linear(14, 4)self.linear7 = torch.nn.Linear(4, 1)self.ReLU = torch.nn.ReLU() # 将其看作是网络的一层,而不是简单的函数使用self.Sigmoid = torch.nn.Sigmoid()def forward(self, x):x =  self.ReLU(self.linear1(x))x =  self.ReLU(self.linear2(x)) x =  self.ReLU(self.linear3(x))x =  self.ReLU(self.linear4(x))x =  self.ReLU(self.linear5(x))x =  self.ReLU(self.linear6(x))x =  self.linear7(x)return x
# 读取神经网络参数,没有结构
model = torch.load('angelminLoss.pkl')

下面是测试的py文件test.py,

import numpy as np
import torch
import matplotlib.pyplot as plt
from IPython import display
from d2l import torch as d2l
import osclass Model(torch.nn.Module):def __init__(self):super(Model, self).__init__()# 这个是有wx+bself.linear1 = torch.nn.Linear(5, 56)self.linear2 = torch.nn.Linear(56, 56)self.linear3 = torch.nn.Linear(56, 56)self.linear4 = torch.nn.Linear(56, 28)self.linear5 = torch.nn.Linear(28, 14)self.linear6 = torch.nn.Linear(14, 5)self.linear7 = torch.nn.Linear(5, 1)self.ReLU = torch.nn.ReLU()  # 将其看作是网络的一层,而不是简单的函数使用self.Sigmoid = torch.nn.Sigmoid()def forward(self, x):x = self.ReLU(self.linear1(x))x = self.ReLU(self.linear2(x))x = self.ReLU(self.linear3(x))x = self.ReLU(self.linear4(x))x = self.ReLU(self.linear5(x))x = self.ReLU(self.linear6(x))x = self.linear7(x)return xdef init():model = Model()modelFF = torch.load("hminLoss.pkl")print("success_1")if __name__ == "__main__":model = Model()modelFF = torch.load("hminLoss.pkl")print("success_2")

可以看到运行没有问题的,单独运行test.py
在这里插入图片描述
但是现在存在一个问题,当调用当前文件时候,qt里面会报这个错,如果没有报错的,直接闪退的话,可以让他打印错误信息

   // 新建一个元组,用来存放函数参数的值if( !Py_IsInitialized()){     Py_Initialize();}// 导入包含你的 Python 类的模块PyObject* pModule = PyImport_ImportModule("ccc");PyErr_Print(); // 打印 Python 异常信息// 获取模块中的函数对象PyObject* pFunc = PyObject_GetAttrString(pModule, "init");PyErr_Print(); // 打印 Python 异常信息// 创建参数元组PyObject* pArgs = PyTuple_New(0);//   int num1 = 42;//   int num2 = 13;//   PyObject* arg1 = Py_BuildValue("i", num1);//   PyObject* arg2 = Py_BuildValue("i", num2);//   PyTuple_SetItem(pArgs, 0, arg1);//   PyTuple_SetItem(pArgs, 1, arg2);// 调用函数并获取返回值PyObject* pResult = PyObject_CallObject(pFunc, pArgs);// 释放资源PyErr_Print(); // 打印 Python 异常信息// 解析返回值double result;PyArg_Parse(pResult, "d", &result);// 打印结果printf("Result: %f\n", result);// 释放资源PyErr_Print(); // 打印 Python 异常信息Py_Finalize();

在这里插入图片描述
AttributeError: Can’t get attribute ‘Model’ on <module ‘main’ (built-in)>在我们自己单独运行时候是没有报错的。
当我们把文件改成这样,就会报相同的错误,就是torch.load(“hminLoss.pkl”)在导入参数时候,他是没有得到神经网络的结构了,所以报错。我一开始以为是我们c++调用python时候,只会运行导入的函数,没有执行那个Model类,所以会报错,其实不是的,因为在用numpy时候,import导入以后下下面可以直接用,而且上面Model类也可以实例出对象,这就说明其实网络结构应该是有的,但是他拿不到,在调用时候会把import和类这些先运行一下的。

import numpy as np
import torch
import matplotlib.pyplot as plt
from IPython import display
from d2l import torch as d2l
import osdef init():model = Model()modelFF = torch.load("hminLoss.pkl")print("success_1")if __name__ == "__main__":model = Model()modelFF = torch.load("hminLoss.pkl")print("success_2")

后来我就把网格结构单独放在一个py文件,作为一个模块导入进去,也还是这个问题,单独文件运行都没报错,作为模块导入就会报错,就发现其实PyObject_GetAttrString(pModule, “init”),他其实和import init from pModule是一样的,知道这点以后,我们将其当成一个模块,在其他py文件导入,报错如下
在这里插入图片描述


# 如果当前执行的是这文件的话,就有__name__= "__main__,
# 我们看报错信息 Can't get attribute 'Model' on <module '__main__' from,里面有一个__mian__
# 就是在当前文件中声明类Model时候,会往__main__中挂载一些信息,然后torch.load会去__main__里面拿,在当前文件中运行的话,都是可以获取到的
# 所以不会报错,但是作为模块导入时候,__main__其实已经变了,当前文件中__main__是没有网络结构信息的,他又不能去导入模块的__main__
# 去拿,所以就会报错,没有网络结构,PyObject_GetAttrString(pModule, "init"),他其实和import init from pModule一样,所以他就会报
# Can't get attribute 'Model' on <module '__main__' 
if __name__ == "__main__":init()model = Model()modelFF = torch.load("hminLoss.pkl")print("success_2")

解决办法就是,把整个网络参数以及结构全部保存

import numpy as np
import matplotlib.pyplot as plt
from IPython import display
from d2l import torch as d2l
import random
import numpy as np
import torch
import matplotlib.pyplot as plt
from IPython import display
from d2l import torch as d2# 在保存模型时,将模型转化为脚本并保存,整个网络参数以及结构全部保存
model = torch.load('angelminLoss.pkl')
scripted_model = torch.jit.script(model)
torch.jit.save(scripted_model, 'angelminLoss_scripted.pkl')

读取模型,

model = torch.jit.load('angelminLoss_scripted.pkl')

这样就可以正常读取了,有时候可能会说找不到什么的,这种是工作目录不在当前文件夹,
在这里插入图片描述
可以这样读取,这样就不会报错了,就可以找到了

import os
def redModel():script_dir = os.path.dirname(os.path.abspath(__file__))# file_path = os.path.join(script_dir, "FFminLoss_scripted.pkl")# # 读取训练好的模型# modelFF = torch.jit.load("FFminLoss_scr.pkl")# modelTemp = torch.jit.load("TT1minLoss_scr.pkl")# modelh = torch.jit.load("hminLoss_scr.pkl")# modelangel = torch.jit.load("angelminLoss_scr.pkl")modelFF = torch.jit.load(os.path.join(script_dir, "FFminLoss_scr.pkl"))modelTemp = torch.jit.load(os.path.join(script_dir, "TT1minLoss_scr.pkl"))modelh = torch.jit.load(os.path.join(script_dir, "hminLoss_scr.pkl"))modelangel = torch.jit.load(os.path.join(script_dir, "angelminLoss_scr.pkl"))print("模型读取成功")logger.info("Model read successfully")return modelFF, modelTemp, modelh, modelangel

成功运行》》》》》》》》》》》》》》》》》》
在这里插入图片描述

四.参考

https://blog.51cto.com/wangjichuan/5691185(Qt调用Python详细过程)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/605111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

程序员为什么不能一次把功能写好,是因为他不想吗

引言 交流一下为什么他做的功能这么多Bug 大家好&#xff0c;最近看到一个有趣的问题&#xff1a; 程序员为什么要不能一次性写好&#xff0c;需要一直改Bug&#xff1f; 在我看来&#xff0c;程序员也是人&#xff0c;并非机器。 拿这个问题去质问程序员&#xff0c;答案无…

Java学习,一文掌握Java之SpringBoot框架学习文集(3)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

【网络】网络层协议ARP和IP协议转发流程

目录 一、IP概述 1.1 IP简介 1.2 IP协议 二、IP地址与硬件地址 三、地址解析协议ARP 3.1 ARP协议简介 3.2 ARP工作流程 3.3 ARP的四种典型情况 四、IP协议的转发流 一、IP概述 1.1 IP简介 IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址…

[VUE]1-创建vue工程

目录 基于脚手架创建前端工程 1、环境要求 2、操作过程 3、工程结构 4、启动前端服务 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c…

如何写html邮件 —— 参考主流outook、gmail、qq邮箱渲染邮件过程

文章目录 ⭐前言⭐outlook渲染邮件⭐gmail邮箱渲染邮件⭐qq邮箱渲染邮件 ⭐编写html邮件&#x1f496;table表格的属性&#x1f496;文本&#x1f496;图片&#x1f496;按钮&#x1f496;背景图片 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 …

云卷云舒:【实战篇】对象存储迁移

云卷云舒&#xff1a;【实战篇】MySQL迁移-CSDN博客 1. 简介 对象存储与块存储、文件存储并列为云计算三大存储模型。提供海量存储空间服务&#xff0c;具备快速的数据存取性能、高可靠和数据安全性&#xff0c;通过标准的RESTful API接口和丰富的SDK包来提供服务&#xff0c…

一篇文章带你了解Jenkins + K8s 部署的好处

在当今的软件开发和运维领域&#xff0c;Kubernetes&#xff08;K8s&#xff09;和 Jenkins 的组合已经成为了一种常见且强大的部署模式。本文将探讨 Jenkins K8s 部署的好处&#xff0c;以及它们如何协同工作以提高效率和可靠性。 一、自动化部署和持续集成/持续交付&#x…

3D模型UV展开原理

今年早些时候&#xff0c;我为 MAKE 杂志写了一篇教程&#xff0c;介绍如何制作视频游戏角色的毛绒动物。 该技术采用给定的角色 3D 模型及其纹理&#xff0c;并以编程方式生成缝纫图案。 虽然我已经编写了一般摘要并将源代码上传到 GitHub&#xff0c;但我在这里编写了对使这一…

Presto CLI学习

1. 序言 作为Presto的客户端之一&#xff0c;Presto CLI是一个基于终端的交互式shell&#xff0c;对应presto源码中的presto-cli模块 Presto CLI的本质是一个self-executing jar —— presto-cli-version-executable.jar&#xff0c;就像一个普通的UNIX可执行文件 因此&#…

olap/spark-tungsten:codegen

15721这一章没什么好说的&#xff0c;不再贴课程内容了。codegen和simd在工业界一般只会选一种实现。比如phothon之前用codegen&#xff0c;然后改成了向量化引擎。一般gen的都是weld IR/LLVM IR/当前语言&#xff0c;gen成C的也要检查是不是有本地预编译版本&#xff0c;要不没…

城市建设模拟游戏:鼠托邦 RATOPIA 中文免安装版

《鼠托邦》是一款由独立游戏开发团队Cassel Games开发的基地建设模拟游戏。在游戏中&#xff0c;玩家需要管理一个庞大的地下鼠国&#xff0c;打造理想中的“鼠托邦”。玩家可以化身为糖果派对游戏中的老鼠女王&#xff0c;带领老鼠民众建设城市、勘探地下领域以扩展生存空间。…

MySQL第一讲:MySQL知识体系详解(P6精通)

MySQL知识体系详解(P6精通) MySQL不论在实践还是面试中,都是频率最高的。本系列主要对MySQL知识体系梳理,将给大家构建JVM核心知识点全局知识体系,本文是MySQL第一讲,MySQL知识体系详解。 文章目录 MySQL知识体系详解(P6精通)1、MySQL学习建议1.1、为什么学习 MySQL?1.2、…

C 练习实例21

题目&#xff1a;猴子吃桃问题&#xff1a;猴子第一天摘下若干个桃子&#xff0c;当即吃了一半&#xff0c;还不瘾&#xff0c;又多吃了一个
第二天早上又将剩下的桃子吃掉一半&#xff0c;又多吃了一个。以后每天早上都吃了前一天剩下
的一半零一个。到第10天早上想再吃时&a…

Web前端-JavaScript(ES6)

文章目录 1.ES5数组新方法1.1 数组方法forEach遍历数组1.2 数组方法filter过滤数组1.3 数组方法some1.4 some和forEach和filter的区别1.5 find()1.6 findIndex()1.7 trim去除字符串两端的空格1.8 获取对象的属性名1.9 Object.defineProperty 2.ES6语法2.1 ES6概述2.2 为什么使用…

Git 提交类型前缀

Git 提交类型前缀是指在 Git 提交消息中用来描述代码更改类型的前缀。除了 feat 和 fix 之外&#xff0c;还有许多其他常见的 Git 提交类型前缀。以下是一些常见的前缀&#xff1a; docs&#xff1a;文档相关的更改&#xff0c;例如更新文档、添加注释等。 style&#xff1a;代…

C# List去除重复数据

List<int> listnew List<int>(){1,1,1,1}; listlist.Distinct.toList();//该语句执行完毕后&#xff0c;list仅有一个元素。

CTF数据分析题详解

目录 题目一(1.pcap) 题目二(2.pcap) 题目三(3.pcap) 题目四(4.pcap) CTF流量分析经典例题详解-CSDN博客 本文章涉及的所有题目附件下载地址&#xff1a; 链接&#xff1a; https://pan.baidu.com/s/18mWo5vn1zp_XbmcQrMOKRA 提取码&#xff1a;hrc4 声明&#xff1a;这里…

WorkPlus AI助理为企业提供智能客服的机器人解决方案

在数字化时代&#xff0c;企业面临着客户服务的重要挑战。AI客服机器人成为了提升客户体验和提高工作效率的关键工具。作为一款优秀的AI助理&#xff0c;WorkPlus AI助理以其智能化的特点和卓越的功能&#xff0c;为企业提供了全新的客服机器人解决方案。 为什么选择WorkPlus A…

特发性震颤的症状有哪些?

特发性震颤是一种神经系统疾病&#xff0c;主要症状为身体部位不自主地震颤&#xff0c;通常影响手部&#xff0c;但也可能涉及头部、颈部和声音。这种震颤在特定情况下如注意力集中、精神紧张、疲劳和温度低时更容易出现。特发性震颤的症状表现多样&#xff0c;对患者的生活和…

Python机器学习入门必学必会:机器学习与Python基础

1.机器学习常见的基础概念 根据输入数据是否具有“响应变量”信息&#xff0c;机器学习被分为“监督式学习”和“非监督式学习”。“监督式学习”即输入数据中即有X变量&#xff0c;也有y变量&#xff0c;特色在于使用“特征&#xff08;X变量&#xff09;”来预测“响应变量&…