使用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…

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;带领老鼠民众建设城市、勘探地下领域以扩展生存空间。…

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 为什么使用…

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…

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

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

【Python从入门到进阶】46、58同城Scrapy项目案例介绍

接上篇《45、Scrapy框架核心组件介绍》 上一篇我们学习了Scrapy框架的核心组件的使用。本篇我们进入实战第一篇&#xff0c;以58同城的Scrapy项目案例&#xff0c;结合实际再次巩固一下项目结构以及代码逻辑的用法。 一、案例网站介绍 58同城是一个生活服务类平台&#xff0c…

【分布式】分布式链路跟踪技术

为什么需要分布式链路追踪 提到分布式链路追踪&#xff0c;我们要先提到微服务。相信很多人都接触过微服务。微服务是一种开发软件的架构和组织方法&#xff0c;它侧重将服务解耦&#xff0c;服务之间通过API通信。使应用程序更易于扩展和更快地开发&#xff0c;从而加速新功能…

Go-gin-example 添加注释 第一部分 新建项目及api编写

文章目录 go-gin-example环境准备初始化 Go Modules基础使用 gin 安装测试gin是否引入 gin搭建Blog APIsgo-ini简述配置文件 阶段目标 编写简单API错误码包 完成一个demo初始化项目初始化项目数据库编写项目配置包拉取go-ini配置包在conf目录下新建app.ini文件&#xff0c;写入…

【操作系统篇】什么是分段和分页

什么是分段和分页 ✔️ 典型解析✔️分页✔️页表✔️分段&#xff08;Segmentation&#xff09;✔️ 分段和分页的区别✔️分页和分段哪个更耗资源✔️它们对性能的影响是怎样的✔️分段和分页分别适合什么场景 ✔️ 典型解析 在操作系统中&#xff0c;分段和分页是两种不同的…

在做题中学习(43):长度最小的子数组

LCR 008. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;同向双指针-------滑动窗口算法 解释&#xff1a;本是暴力枚举做法&#xff0c;因为全部是正整数&#xff0c;就可以利用单调性和双指针解决问题来节省时间 思路&#xff1a; 如上面图&am…

ES -极客学习

Elasticsearch 简介及其发展历史 起源 Lucene 于 Java 语言开发的搜索引擎库类创建于 1999 年&#xff0c;2005 年成为 Apache 顶级开源项目Lucene 具有高性能、易扩展的优点Lucene 的局限性 只能基于 Java 语言开发类库的接口学习曲线陡峭原生并不支持水平扩展原生并不支持水…