一. 内容简介
使用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.0
MopsoPy{
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程序,读取神经网络
后面更新
四.参考
https://blog.51cto.com/wangjichuan/5691185(Qt调用Python详细过程)