前言
本文主要介绍使用Qt和Python进行混合编程的环境搭建。
运行环境
- Qt 5.13.0 64位 MinGW-64编译器
- Python 3.9.6 64bit
注意 Qt编译器的版本号需要和Python的版本号一致,不然编译时候报错。
环境搭建
- 打开Qt创建一个项目,创建完毕后在项目中创建一个目录thirdLibs用来存放python的头文件和链接库。
- 下载python后安装,找到安装目录,将Python目录中的include 和libs 拷贝到Qt工程中的thirdLibs目录中。
- 将python目录下的python3.dll以及python39.dll拷贝到Qt工程生成的exe同目录(比如:XXX-Desktop_Qt_5_13_0_MinGW_64_bit-Debug\debug)
- 打开Qt项目的pro配置文件,将python的头文件和库文件的依赖路径添加到配置文件中。
win32: LIBS += -L$$PWD/thirdLibs/libs/ -lpython3 -lpython39
INCLUDEPATH += $$PWD/thirdLibs/include
- 在exe运行目录中创建目录python,用来存放后续使用的python库及依赖文件。将python安装目录中的Dlls,include,Lib,libs,tcl,Tools目录拷贝到刚刚创建的python中。
编写Pyhton程序
- 创建python程序命名为qt_test.py 内容为:
def hello():
print("hello world!")
- 将创建好的python文件放到exe运行的目录。
编写Qt程序
-引入头文件,由于python头文件中的slots和Qt中的信号曹相冲突,通过一下代码解决。
#undef slots
#include <Python.h>
#define slots Q_SLOTS
- 编辑main函数
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//配置Python环境目录为exe运行目录下的python环境
QString path = QCoreApplication::applicationDirPath() + "/python";
Py_SetPythonHome((wchar_t*)(reinterpret_cast< const wchar_t* >(path.utf16())));
//初始化python模块
Py_Initialize();
if ( !Py_IsInitialized() )
{
PyErr_Print();
return -1;
}
//导入qt_test.py模块
PyObject* pModule = PyImport_ImportModule("qt_test");
if (!pModule)
{
printf("Cant open qt_test file!\n");
return -1;
}
PyObject* pFunhello= PyObject_GetAttrString(pModule,"hello"); // 这里的hello就是python文件定义的函数
if(!pFunhello)
{
PyErr_Print();
qDebug()<<"Get function hello failed";
return -1;
}
PyObject_CallFunction(pFunhello,NULL);
//结束,释放python
Py_Finalize();
return a.exec();
}
运行程序
如果上面步骤都配置正确,Qt的应用程序输出窗口会打印:
helloworld!
后续
- 虽然此时Qt可以运行python程序了,但是pyhon的运行环境实在庞大,再还没有安装numpy等需要用到的科学库的情况下已经达到惊人的100M+,这种情况对于实际应用中是不可接受的。因此需要使用体积更小的python环境。
- 去python官网上下载对应的嵌入式版本比如我下载的:python-3.9.6-embed-amd64.zip 这个版本是绿色版下载后解压就可直接运行。
- 将解压后的程序拷贝到Qt项目中exe的运行目录将将python-3.9.6-embed-amd64目录该名为python39
- 进入python39将python39.zip解压到本地并重新命名为Lib
- 进入Qt工程将main函数中的python运行环境目录修改为:
QString path = QCoreApplication::applicationDirPath() + "/python39";
Py_SetPythonHome((wchar_t*)(reinterpret_cast< const wchar_t* >(path.utf16())));
- 重新编译Qt项目,运行,OK!
- 此时exe程序下的python运行环境也就 10M+。
- 打工完成!