一.概述
1.Python功能强大,很多Qt或者c/c++开发不方便的功能可以由Python编码开发,尤其是一些算法库的应用上,然后Qt调用Python。
2.在Qt调用Python的过程中,必须要安装python环境,并且Qt Creator中编译器与Python的版本要对应,具体来说编译器是64位安装Python就是64位,编译器32位安装Python就是32位。
3.本文测试使用的QT版本为:QT5.12; python版本为python-3.12
4.Qt调用python主要有两种方式:
一是混合编程模式,直接调用python文件内的函数,比较灵活,也是本文重点讲述的方法;
二是直接调用python脚本文件,比较简单,但是不够灵活。
二.混合编程代码实现
1.环境配置
(1)pro文件中添加python的头文件和依赖库:
INCLUDEPATH += -I D:\python\Lib\site-packages\numpy\core\include
INCLUDEPATH += -I D:\python\include
LIBS += -L D:\python\libs -l_tkinter -lpython3 -lpython312
(2)修改include文件夹中的object.h文件,因为Python中slots是关键字,Qt中slots也是关键字,会冲突。
#undef slots
PyType_Slot *slots; /* terminated by slot==0. */
#define slots Q_SLOTS
2.代码实现
(1)Python代码添加目录及内容
添加test1.py文件到qt生成exe目录,比如:
../build-qt_python-Desktop_Qt_5_12_10_MinGW_64_bit-Debug/debug/testb.py
否则无法调用py文件。
Python代码:
def hello():
print("hello")
def mix(a,b):
print("=======================")
r1 = a + b
r2 = a - b
return (r1, r2)
2.qt代码
#include <QCoreApplication>
#include <Python.h>
#include <QDebug>
#include <numpy/arrayobject.h>
int Test_hello(void)
{
//初始化python模块
Py_Initialize();
if ( !Py_IsInitialized() )
{
return -1;
}
//导入testb.py模块
PyObject* pModule = PyImport_ImportModule("testb");
if (!pModule) {
qDebug("Cant open python file!\n");
return -1;
}
//获取test模块中的hello函数
PyObject* pFunhello= PyObject_GetAttrString(pModule,"hello");
if(!pFunhello){
qDebug()<<"Get function hello failed";
return -1;
}
//调用hello函数
PyObject_CallFunction(pFunhello,NULL);
//结束,释放python
Py_Finalize();
return 0;
}
int Testt_mix(void)
{
//初始化python模块
Py_Initialize();
if ( !Py_IsInitialized() )
{
return -1;
}
PyObject* pModule = PyImport_ImportModule("testb");//注意文件名字大小写
if (!pModule) {
qDebug("Cant open python file!\n");
return -1;
}
PyObject* pyFunc_mix = PyObject_GetAttrString(pModule, "mix");
if (pModule && PyCallable_Check(pyFunc_mix))
{
PyObject* pyParams = PyTuple_New(2); //定义两个变量
PyTuple_SetItem(pyParams, 0, Py_BuildValue("i", 5));// 变量格式转换成python格式
PyTuple_SetItem(pyParams, 1, Py_BuildValue("i", 2));// 变量格式转换成python格式
int r1 = 0, r2 = 0;
PyObject* pyValue = PyObject_CallObject(pyFunc_mix, pyParams); //调用函数返回结果
PyArg_ParseTuple(pyValue, "i|i", &r1, &r2);//分析返回的元组值
if (pyValue)
{
qDebug("result: %d %d\n", r1, r2);
}
}
//结束,释放python
Py_Finalize();
return 0;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Test_hello();
Testt_mix();
return a.exec();
}
3.输出结果
三.直接调用python脚本模式
1.python文件
import sys
def test():
a = 1
print (a)
if __name__=='__main__':
b = test()
print (b)
2.QT代码
//第一步:初始化Python
Py_Initialize();
//检查初始化是否完成
if (!Py_IsInitialized())
{
return -1;
}
//第二步:导入sys模块
PyRun_SimpleString("import sys");
const char* code = "with open('./debug/scriptpy.py', 'r') as file: exec(file.read())";
// 执行代码字符串
if (PyRun_SimpleString(code) != 0)
{
// 处理错误
PyErr_Print();
return -1;
}
Py_Finalize();
3.执行结果